ブログ

🤖 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 のすべてのアップデートを把握しましょう。