블로그

🤖 Gato GraphQL과 ChatGPT의 연동이 더욱 강력해졌습니다

Leonardo Losoviz
작성자: Leonardo Losoviz ·

Gato GraphQL의 Power Extensions 번들 최신 릴리스에는 다음과 같은 새로운 Root 필드가 포함되어 있습니다:

  • _arrayEncodeAsJSONString
  • _objectEncodeAsJSONString

이 필드들은 서로 다른 구조(_arrayEncodeAsJSONString으로 항목 배열, _objectEncodeAsJSONString으로 JSON 객체)를 JSON 인코딩하여 문자열 표현으로 생성합니다.

이를 통해 ChatGPT 프롬프트에 구조화된 데이터를 포함하여 전송할 수 있습니다.

이 기능은 ChatGPT를 통한 콘텐츠 번역 시(다른 사용 사례도 포함) 유용합니다. 여러 문자열을 배열이나 객체로 묶으면 단일 요청으로 한꺼번에 번역할 수 있어, 여러 개의 독립적인 요청을 보내는 것보다 번역 품질이 향상됩니다.

몇 가지 예시를 살펴보겠습니다.

배열을 전송하여 ChatGPT로 여러 문자열 번역하기

쿼리 Translate multiple sentences using ChatGPT는 여러 게시물에서 콘텐츠를 가져와 ChatGPT를 사용하여 임의의 언어로 번역합니다.

이 비디오에서 쿼리 실행을 시연합니다:

배열을 전송하여 ChatGPT로 여러 문자열 번역하기

먼저 게시물 콘텐츠 항목을 가져와 배열로 내보냅니다. 그런 다음 새 _arrayEncodeAsJSONString 필드를 사용하여 배열을 문자열로 인코딩하고 ChatGPT 프롬프트에 포함합니다. 마지막으로 ChatGPT API에 HTTP 요청을 실행하여 번역 결과를 가져옵니다.

쿼리를 실행한 후, translatedContent 항목 아래에서 번역 결과를 가져오세요.

query GetPostContent($limit: Int! = 5) {
  posts(pagination: {limit: $limit}, sort: {by: ID, order: ASC}) {
    content
      @export(
        as: "contentItems",
        type: LIST
      )
  }
}
 
query TranslateContentWithChatGPT(
  $fromLang: String!
  $toLang: String!
  $openAIAPIKey: String!
  $systemMessage: String! = "You are a language translator"
  $promptTemplate: String! = """
I'm working on internationalizing my application.
 
I've created a JSON with sentences in {$fromLang}. Please translate the sentences to {$toLang}.
 
If a sentence contains HTML, do not translate inside the HTML tags.
 
This is the JSON:
 
{$encodedContentItems}
"""
  $model: String! = "gpt-4o-mini"
)
  @depends(on: "GetPostContent")
{
  contentItems: _echo(value: $contentItems)
  encodedContentItems: _arrayEncodeAsJSONString(array: $contentItems)
  prompt: _strReplaceMultiple(
    search: ["{$fromLang}", "{$toLang}", "{$encodedContentItems}"],
    replaceWith: [$fromLang, $toLang, $__encodedContentItems],
    in: $promptTemplate
  )
  openAIResponse: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://api.openai.com/v1/chat/completions",
    method: POST,
    options: {
      auth: {
        password: $openAIAPIKey
      },
      json: {
        model: $model,
        messages: [
          {
            role: "system",
            content: $systemMessage
          },
          {
            role: "user",
            content: $__prompt
          },
        ],
        response_format: {
          type: "json_schema",
          json_schema: {
            name: "translation_response",
            strict: true,
            schema: {
              type: "object",
              properties: {
                translations: {
                  type: "array",
                  items: {
                    type: "string"
                  }
                }
              },
              required: ["translations"],
              additionalProperties: false
            }
          }
        }
      }
    }
  })
    @underJSONObjectProperty(by: { key: "choices" })
      @underArrayItem(index: 0)
        @underJSONObjectProperty(by: { path: "message.content" })
          @export(as: "jsonEncodedTranslatedContent")
}
 
query ExtractTranslatedContent
  @depends(on: "TranslateContentWithChatGPT")
{
  jsonEncodedTranslatedContent: _echo(value: $jsonEncodedTranslatedContent)
    @remove
  decodedTranslatedContent: _strDecodeJSONObject(string: $jsonEncodedTranslatedContent)
    @remove
  translatedContent: _objectProperty(
    object: $__decodedTranslatedContent,
    by: { key: "translations" }
  )
}

스페인어로 번역하기 위해 쿼리를 실행한 결과는 다음과 같습니다:

{
  "data": {
    "posts": [
      {
        "content": "\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n"
      },
      {
        "content": "\n<p>This is a paragraph block. Professionally productize highly efficient results with world-class core competencies. Objectively matrix leveraged architectures vis-a-vis error-free applications. Completely maximize customized portals via fully researched metrics. Enthusiastically generate premier action items through web-enabled e-markets. Efficiently parallel task holistic intellectual capital and client-centric markets.<br><br></p>\n\n\n\n<h2 class=\"wp-block-heading\">Image Block (Standard)</h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https://d.pr/i/8pTmgY+\" alt=\"\" class=\"wp-image-1755\"/></figure>\n"
      }
    ],
    "contentItems": [
      "\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n",
      "\n<p>This is a paragraph block. Professionally productize highly efficient results with world-class core competencies. Objectively matrix leveraged architectures vis-a-vis error-free applications. Completely maximize customized portals via fully researched metrics. Enthusiastically generate premier action items through web-enabled e-markets. Efficiently parallel task holistic intellectual capital and client-centric markets.<br><br></p>\n\n\n\n<h2 class=\"wp-block-heading\">Image Block (Standard)</h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https://d.pr/i/8pTmgY+\" alt=\"\" class=\"wp-image-1755\"/></figure>\n"
    ],
    "encodedContentItems": "[\"\\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!<\\/p>\\n\",\"\\n<p>This is a paragraph block. Professionally productize highly efficient results with world-class core competencies. Objectively matrix leveraged architectures vis-a-vis error-free applications. Completely maximize customized portals via fully researched metrics. Enthusiastically generate premier action items through web-enabled e-markets. Efficiently parallel task holistic intellectual capital and client-centric markets.<br><br><\\/p>\\n\\n\\n\\n<h2 class=\\\"wp-block-heading\\\">Image Block (Standard)<\\/h2>\\n\\n\\n\\n<figure class=\\\"wp-block-image\\\"><img decoding=\\\"async\\\" src=\\\"https:\\/\\/d.pr\\/i\\/8pTmgY+\\\" alt=\\\"\\\" class=\\\"wp-image-1755\\\"\\/><\\/figure>\\n\"]",
    "prompt": "\nI'm working on internationalizing my application.\n\nI've created a JSON with sentences in English. Please translate the sentences to Spanish.\n\nThis is the JSON:\n\n[\"\\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!<\\/p>\\n\",\"\\n<p>This is a paragraph block. Professionally productize highly efficient results with world-class core competencies. Objectively matrix leveraged architectures vis-a-vis error-free applications. Completely maximize customized portals via fully researched metrics. Enthusiastically generate premier action items through web-enabled e-markets. Efficiently parallel task holistic intellectual capital and client-centric markets.<br><br><\\/p>\\n\\n\\n\\n<h2 class=\\\"wp-block-heading\\\">Image Block (Standard)<\\/h2>\\n\\n\\n\\n<figure class=\\\"wp-block-image\\\"><img decoding=\\\"async\\\" src=\\\"https:\\/\\/d.pr\\/i\\/8pTmgY+\\\" alt=\\\"\\\" class=\\\"wp-image-1755\\\"\\/><\\/figure>\\n\"]\n",
    "openAIResponse": {
      "id": "chatcmpl-AlcAdtuZ40iauuSVvr1uEdrbYefMa",
      "object": "chat.completion",
      "created": 1735911507,
      "model": "gpt-4o-mini-2024-07-18",
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "{\"translations\":[\"\\n<p>Bienvenido a WordPress. Esta es tu primera publicación. Edítala o elimínala, ¡y luego empieza a escribir!<\\\\/p>\\n\",\"\\n<p>Este es un bloque de párrafo. Profesionalmente productiza resultados altamente eficientes con competencias esenciales de clase mundial. Objetivamente aprovecha arquitecturas aprovechadas en relación con aplicaciones sin errores. Maximiza completamente portales personalizados a través de métricas totalmente investigadas. Genera entusiastamente elementos de acción de primer nivel a través de mercados electrónicos habilitados por la web. Eficazmente paralelamente gestiona el capital intelectual holístico y los mercados centrados en el cliente.<br><br><\\\\/p>\\n\\n\\n\\n<h2 class=\\\"wp-block-heading\\\">Bloque de Imagen (Estándar)<\\\\/h2>\\n\\n\\n\\n<figure class=\\\"wp-block-image\\\"><img decoding=\\\"async\\\" src=\\\"https://d.pr/i/8pTmgY+\\\" alt=\\\"\\\" class=\\\"wp-image-1755\\\"/><\\\\/figure>\\n\"]}",
            "refusal": null
          },
          "logprobs": null,
          "finish_reason": "stop"
        }
      ],
      "usage": {
        "prompt_tokens": 257,
        "completion_tokens": 224,
        "total_tokens": 481,
        "prompt_tokens_details": {
          "cached_tokens": 0,
          "audio_tokens": 0
        },
        "completion_tokens_details": {
          "reasoning_tokens": 0,
          "audio_tokens": 0,
          "accepted_prediction_tokens": 0,
          "rejected_prediction_tokens": 0
        }
      },
      "system_fingerprint": "fp_0aa8d3e20b"
    },
    "translatedContent": [
      "\n<p>Bienvenido a WordPress. Esta es tu primera publicación. Edítala o elimínala, ¡y luego empieza a escribir!<\\/p>\n",
      "\n<p>Este es un bloque de párrafo. Profesionalmente productiza resultados altamente eficientes con competencias esenciales de clase mundial. Objetivamente aprovecha arquitecturas aprovechadas en relación con aplicaciones sin errores. Maximiza completamente portales personalizados a través de métricas totalmente investigadas. Genera entusiastamente elementos de acción de primer nivel a través de mercados electrónicos habilitados por la web. Eficazmente paralelamente gestiona el capital intelectual holístico y los mercados centrados en el cliente.<br><br><\\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Bloque de Imagen (Estándar)<\\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https://d.pr/i/8pTmgY+\" alt=\"\" class=\"wp-image-1755\"/><\\/figure>\n"
    ]
  }
}

Sending objects to translate multiple strings via ChatGPT

Query Translate all properties of a post using ChatGPT fetches all the properties from a single post, and translates those strings to any language using ChatGPT.

Watch this video to see the execution of this query:

Sending objects to translate multiple strings via ChatGPT

This query is similar to the previous one, but it retrieves (and translates) all properties from a single post and exports them as a JSON object.

After running the query, retrieve the translations from under the translatedPostPropertiesAsJSON entry.

query GetPostProperties($postId: ID!) {
  post(by: { id: $postId }) {
    title
    content
    excerpt
      @export(
        as: "postProperties",
        affectAdditionalFieldsUnderPos: [1, 2]
      )
  }
}
 
query TranslatePostPropertiesWithChatGPT(
  $fromLang: String!
  $toLang: String!
  $openAIAPIKey: String!
  $systemMessage: String! = "You are a language translator"
  $promptTemplate: String! = """
I'm working on internationalizing my application.
 
I've created a JSON with sentences in {$fromLang}. Please translate the sentences to {$toLang}.
 
Keep the object properties identical, translate the values only.
 
If a sentence contains HTML, do not translate inside the HTML tags.
 
This is the JSON:
 
{$encodedPostProperties}
"""
  $model: String! = "gpt-4o-mini"
)
  @depends(on: "GetPostProperties")
{
  postProperties: _echo(value: $postProperties)
  encodedPostProperties: _objectEncodeAsJSONString(object: $postProperties)
  prompt: _strReplaceMultiple(
    search: ["{$fromLang}", "{$toLang}", "{$encodedPostProperties}"],
    replaceWith: [$fromLang, $toLang, $__encodedPostProperties],
    in: $promptTemplate
  )
  openAIResponse: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://api.openai.com/v1/chat/completions",
    method: POST,
    options: {
      auth: {
        password: $openAIAPIKey
      },
      json: {
        model: $model,
        messages: [
          {
            role: "system",
            content: $systemMessage
          },
          {
            role: "user",
            content: $__prompt
          },
        ],
        response_format: {
          type: "json_schema",
          json_schema: {
            name: "translation_response",
            strict: true,
            schema: {
              type: "object",
              properties: {
                translations: {
                  type: "array",
                  items: {
                    type: "object",
                    properties: {
                      property: {
                        type: "string"
                      },
                      translation: {
                        type: "string"
                      }
                    },
                    required: ["property", "translation"],
                    additionalProperties: false
                  }
                }
              },
              required: ["translations"],
              additionalProperties: false
            }
          }
        }
      }
    }
  })
    @underJSONObjectProperty(by: { key: "choices" })
      @underArrayItem(index: 0)
        @underJSONObjectProperty(by: { path: "message.content" })
          @export(as: "jsonEncodedTranslatedPostProperties")
}
 
query ExtractTranslatedPostProperties
  @depends(on: "TranslatePostPropertiesWithChatGPT")
{
  jsonEncodedTranslatedPostProperties: _echo(value: $jsonEncodedTranslatedPostProperties)
    @remove
  decodedTranslatedPostProperties: _strDecodeJSONObject(string: $jsonEncodedTranslatedPostProperties)
    @remove
  translatedPostProperties: _objectProperty(
    object: $__decodedTranslatedPostProperties,
    by: { key: "translations" }
  )
  translatedPostPropertiesAsJSON: _arrayOfJSONObjectsExtractPropertiesAndConvertToObject(
    array: $__translatedPostProperties,
    key: "property",
    value: "translation"
  )
}

This is the response of executing the query for translating to Spanish:

{
  "data": {
    "post": {
      "title": "Hello world!",
      "content": "\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n",
      "excerpt": "Welcome to WordPress. This is your first post. Edit or delete it, then start writing!"
    },
    "postProperties": {
      "title": "Hello world!",
      "content": "\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n",
      "excerpt": "Welcome to WordPress. This is your first post. Edit or delete it, then start writing!"
    },
    "encodedPostProperties": "{\"title\":\"Hello world!\",\"content\":\"\\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!<\\/p>\\n\",\"excerpt\":\"Welcome to WordPress. This is your first post. Edit or delete it, then start writing!\"}",
    "prompt": "\nI'm working on internationalizing my application.\n\nI've created a JSON with sentences in English. Please translate the sentences to Spanish.\n\nKeep the object properties identical, translate the values only.\n\nThis is the JSON:\n\n{\"title\":\"Hello world!\",\"content\":\"\\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!<\\/p>\\n\",\"excerpt\":\"Welcome to WordPress. This is your first post. Edit or delete it, then start writing!\"}\n",
    "openAIResponse": {
      "id": "chatcmpl-AlrJK6lIJK7YmtITveYeUrCJbP0JO",
      "object": "chat.completion",
      "created": 1735969706,
      "model": "gpt-4o-mini-2024-07-18",
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "{\"translations\":[{\"property\":\"title\",\"translation\":\"¡Hola mundo!\"},{\"property\":\"content\",\"translation\":\"\\n<p>Bienvenido a WordPress. Este es tu primer artículo. ¡Edítalo o elimínalo, luego comienza a escribir!<\\\\/p>\\n\"},{\"property\":\"excerpt\",\"translation\":\"Bienvenido a WordPress. Este es tu primer artículo. ¡Edítalo o elimínalo, luego comienza a escribir!\"}]}",
            "refusal": null
          },
          "logprobs": null,
          "finish_reason": "stop"
        }
      ],
      "usage": {
        "prompt_tokens": 167,
        "completion_tokens": 92,
        "total_tokens": 259,
        "prompt_tokens_details": {
          "cached_tokens": 0,
          "audio_tokens": 0
        },
        "completion_tokens_details": {
          "reasoning_tokens": 0,
          "audio_tokens": 0,
          "accepted_prediction_tokens": 0,
          "rejected_prediction_tokens": 0
        }
      },
      "system_fingerprint": "fp_0aa8d3e20b"
    },
    "translatedPostProperties": [
      {
        "property": "title",
        "translation": "¡Hola mundo!"
      },
      {
        "property": "content",
        "translation": "\n<p>Bienvenido a WordPress. Este es tu primer artículo. ¡Edítalo o elimínalo, luego comienza a escribir!<\\/p>\n"
      },
      {
        "property": "excerpt",
        "translation": "Bienvenido a WordPress. Este es tu primer artículo. ¡Edítalo o elimínalo, luego comienza a escribir!"
      }
    ],
    "translatedPostPropertiesAsJSON": {
      "title": "¡Hola mundo!",
      "content": "\n<p>Bienvenido a WordPress. Este es tu primer artículo. ¡Edítalo o elimínalo, luego comienza a escribir!<\\/p>\n",
      "excerpt": "Bienvenido a WordPress. Este es tu primer artículo. ¡Edítalo o elimínalo, luego comienza a escribir!"
    }
  }
}

뉴스레터 구독하기

Gato GraphQL의 모든 업데이트를 놓치지 마세요.