STERFIELD

OpenAIのチャットAPIを再帰的に呼び出す方法を検証してみた

OpenAIのチャットAPIを再帰的に呼び出す方法を検証してみた

はじめに

ChatGPTなどのAPIを使うことで、これまで難しかった書類から必要な情報をピックアップする処理や、多言語への変換などがとても容易に行えるようになりました。 しかしながら、その処理はある程度の曖昧さを含まざるを得ないため、1回だけで最適な答えを出すこと難しいケースは多々あります。 そこで今回は、再帰的にChatGPTのAPIへ指示を出すことで、答えを洗練させられるかどうか、検証してみました。

OpenAIチャットAPIでアイディアを再帰的に洗練させる

OpenAIのチャットAPIとTypeScriptを使い、アイディアを段階的に洗練させるプログラムを紹介します。

作ってみたプログラム

1import dotenv from "dotenv"; 2import OpenAI from "openai"; 3import { zodResponseFormat } from "openai/helpers/zod"; 4import { z } from "zod"; 5 6dotenv.config({ path: `${__dirname}/.env` }); 7 8// APIの返答の形式を安定化させるため、Zodを使ってフォーマット指定を行います 9const responseFormat = z.object({ 10 idea: z.string() 11}); 12 13const main = async () => { 14 // OpenAIの初期設定 15 const client = new OpenAI({ 16 organization: process.env.CHAT_GPT_ORGANIZATION_ID, 17 project: process.env.CHAT_GPT_PROJECT_ID, 18 apiKey: process.env.CHAT_GPT_API_KEY 19 }); 20 21 const MAX_COUNT = 5; // 再帰処理で呼び出す回数制限 22 23 const getIdeas = async ( 24 question: string, 25 ideas: string[], 26 count: number = 1 27 ) => { 28 // 最初の指示 29 let content = `## 指示 30次に挙げる議題について、アイディアを出してください 31${question}32 33## 制限事項 34- 200文字程度で出してください`; 35 36 // 再帰的に呼び出された時の指示 37 if (count > 1) { 38 content = `## 指示 39次に挙げるアイディアを類推を使って洗練させてください 40課題: ${question} 41アイディア:「${ideas[ideas.length - 1]}42 43## 制限事項 44- 200文字程度で出してください`; 45 } 46 47 // チャットAPIの実行 48 const chatCompletion = await client.chat.completions.create({ 49 model: "gpt-4o-mini", 50 response_format: zodResponseFormat(responseFormat, "idea"), 51 messages: [ 52 { 53 role: "user", 54 content 55 } 56 ] 57 }); 58 59 // APIのレスポンスをパースして、情報を取得 60 const responseMessage = 61 JSON.parse(chatCompletion?.choices?.[0]?.message?.content ?? "{}") 62 ?.idea ?? ""; 63 64 // 過去データに追加 65 ideas.push(responseMessage); 66 67 // 再帰的に呼び出す 68 if (count < MAX_COUNT) { 69 return getIdeas(question, ideas, count + 1); 70 } 71 72 return { 73 question, 74 ideas 75 }; 76 }; 77 78 // 関数の実行 79 const result = await getIdeas( 80 "アジア向け越境ECを国内メーカーの販売担当者へ広告する場合の効果的なバナーデザイン", 81 [] 82 ); 83 84 console.log(result); 85}; 86 87main() 88 .then(() => { 89 console.log("Done"); 90 }) 91 .catch((error) => { 92 console.error("Error:", error); 93 });

プログラムの解説

  • 1.env
    ファイルに定義されたAPIキーなどの環境変数を
    1dotenv
    で読み込みます。
  • Zodを使い、APIレスポンスの形式(idea: string)を指定することで、レスポンスの型を保証し、安定性を高めます。
  • 1getIdeas
    関数は、指定回数(MAX_COUNT)まで再帰的にChatGPT APIへリクエストを送り、毎回新しいアイディアを生成・洗練します。
  • 1回目は議題からアイディアを生成し、2回目以降は直前のアイディアをさらに洗練するよう指示します。
  • すべてのアイディアは配列に蓄積され、最終的にまとめて出力されます。

実行結果例

1回目

11. クリーンでモダンなデザインを使用し、アジア市場を象徴する色彩(赤、金など)を取り入れる。 22. 商品写真を大きく配置し、目立たせることで視覚的インパクトを強調。 33. アジア顧客のニーズを反映したメッセージ(例:トレンド性や伝統的価値)を強調。 44. 言語はターゲット地域に応じたローカリゼーションを施し、親しみやすさを演出。 55. "越境ECで新市場開拓!"などのキャッチコピーで興味を引く。

3回目

1アジア向け越境ECのバナーデザインには、 21. アジア特有の色(赤、金)を取り入れたクリーンでモダンなデザインが効果的。 32. 大きな商品写真でインパクトを与え、 43. トレンドと伝統を融合させたメッセージで興味を引く。 54. 各地域の言語で親しみやすさを演出し、 65. "新市場開拓のチャンス!"などの魅力的なキャッチコピーを加えることで、販売担当者の関心を高める。

5回目

1「アジア向け越境ECのバナーデザインでは、 21. アジアの文化に根ざした明るい色合い(特に赤や金)を使用し、パッと目を引くデザインに。 32. 商品の魅力を伝えるために、大きな商品画像を配する。 43. トレンドと伝統を融合したキャッチコピーで感情に訴えかけ、 54. 地域ごとの言語で表記して親しみを感じさせる。 65. 更に、「新市場開拓は今がチャンス!」というポジティブなフレーズで顧客の関心を引く。

感想

結果を見てみると、アイディアそのものが洗練されているというより、文章として洗練されていっているという感じでした。 「洗練させる」ということが、人間にとっても解釈が難しいように、そもそも曖昧な指示なのが原因かもしれませんね。 また、ただ繰り返せばいいというわけではなさそうです。 ただし、情報を絞り込んでいくなど、プロンプトや利用目的を工夫すれば、この方法も有効に活用できる可能性があります。

注意

  • 実案件でAPIを再帰的に利用する場合、API利用コストの増大や、レスポンスの質が頭打ちになる可能性についても、さらなる検証が必要です。

参考サイト

Author Profile

著者近影

NINOMIYA

Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。

SHARE

合わせて読みたい