👋

OpenAIのgpt-image-1のような対話型の画像生成を自前で実装してみた(Function Calling)

に公開

はじめに

最近、OpenAIからgpt-image-1という新しい画像生成モデルが公開され、社内APIでも利用可能になったので使ってみました。チャット形式で自然な対話から画像を生成できるこの仕組みは、CopilotやStella AIといったサービスがすでに実装していましたが、APIレベルで簡単に利用できるようになったのは便利だと感じました。

一方で、OpenAIの画像生成APIは、個人開発者であればTier制限により利用が難しいです。さらに、コスト面では品質により1枚あたり0.01〜0.17と、ある程度の品質で生成するとそれなりに費用が発生します。

そこで、Function Callingを活用すれば、同様にチャット形式での画像生成ができる仕組みを作ることができるのではないかと考えました。

Function Calling自体は以前から存在し、今さら感がありますが、もしかしたら、OpenAI自身も内部的には似たような仕組みで画像生成を実現しているのではないか?――そんな仮説から、改めてこの技術に注目しました。

本記事では、Function Callingを活用して任意の画像生成サービスを組み込むことで、gpt-image-1と同等の体験を低コストで実現する方法を紹介します。

前提知識

OpenAI GPT Image 1: 2025年4月に公開されたOpenAIの最新画像モデル。
特徴的なのは、これまでのAPI呼び出し形式(v1/images/generations)だけでなく、チャット対話形式から画像を生成できるresponse API(v1/responses)も提供されている点です。

Function Calling: APIのリクエストとして、Toolの説明とJSONスキーマを定義しておけば、いいタイミングでToolを呼び出してくれる仕組み。Claudeでは"Tool Use"と呼ばれている。

画像生成AI: テキスト生成のLLMの世界では超大手3〜4社が圧倒的な性能を誇っているのに対し、画像生成モデルではまだ群雄割拠の状態です。20Bパラメーター程度の小型モデルでも、それなりにいい感じに動くのがすごい。

方針

OpenAIのResponse APIでgpt-image-1を呼ぶと、ユーザーの入力に対して生成された画像と共に、改善されたプロンプト(revised prompt)が返ってきます。
この仕組みから推測すると、OpenAIは、内部的には、ただ単に画像生成プロンプトを作成し、ツールとして画像生成モデルに渡しているのではないかと考えました。

この仮説が正しいならば、我々のような一般市民でも、Function Callingを活用して全く同じ仕組みを構築できるはずです。

推測したOpenAIのgpt-image-1:
ユーザーの指示 → [プロンプト生成エンジン] → 詳細なプロンプト → [内部の画像生成エンジン] → 生成画像

市民の実装: 
ユーザーの指示 → [LLM (Function Calling)] → 詳細なプロンプト(JSON) → [外部の画像生成API] → 生成画像

※実際には、OpenAIの凄腕エンジニアがプロンプトエンジニアリングやモデルのチューニング等をしていると思うので、こんなに簡単な話ではないはず。

実装

Function Callingに、画像生成用のParametersを設定するだけです。

ステップ1:画像生成サービスの選択とAPI準備

まず、Function Callingから呼び出す画像生成サービスを選びます。
今回はコストパフォーマンスに優れたReplicateを使用します。Replicateでは多数の画像生成モデルが利用可能ですが、ここでは「Seedream 4」を例に進めます。

Seedream 4のJSONパラメータはこんな感じ。

{
  "size": "2K",
  "width": 2048,
  "height": 2048,
  "prompt": "a photo of a store front called \"Seedream 4\", it sells books, a poster in the window says \"Seedream 4 now on Replicate\"",
  "max_images": 1,
  "image_input": [],
  "aspect_ratio": "4:3",
  "enhance_prompt": true,
  "sequential_image_generation": "disabled"
}

ステップ2:Function Callingの定義

次に、OpenAI互換のAPIにFunction Callingとして画像生成ツールを定義します。
以下は、Seedream 4モデル用のツール定義例です.

{
    "model": "gemini-2.5-pro",
    "messages": [
        {
            "role": "system",
            "content": "You are a helpful assistant."
        },
        {
            "role": "user",
            "content": "Hi"
        }
    ],
    # ここから下がFunction Callingの定義
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "generate_image",
                # Tool定義(画像生成用Parameterを生成してね)
                "description": "Generate or edit images using Seedream 4.0 model. Any images attached by the user are automatically forwarded for editing or reference.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "prompt": {
                            "type": "string",
                            "description": "Detailed text description for image generation. Recommended: under 600 words in English."
                        },
                        "size": {
                            "type": "string",
                            "description": "Image resolution. Use \"1K\", \"2K\", \"4K\" or \"WIDTHxHEIGHT\" format (e.g., \"2048x2048\"). Pixel range: 1024x1024 to 4096x4096, aspect ratio: 1/16 to 16.",
                            "default": "2048x2048"
                        },
                        "sequential_image_generation": {
                            "type": "string",
                            "description": "Enable sequential generation mode. \"auto\" for automatic batch generation, \"disabled\" for single image.",
                            "enum": [
                                "auto",
                                "disabled"
                            ],
                            "default": "disabled"
                        },
                        "max_images": {
                            "type": "number",
                            "description": "Maximum number of images to generate (1-15). Only applies when sequential_image_generation is \"auto\". Total of reference images + generated images cannot exceed 15.",
                            "default": 15
                        },
                        "watermark": {
                            "type": "boolean",
                            "description": "Add watermark to bottom-right corner. Default is false.",
                            "default": false
                        }
                    },
                    "required": [
                        "prompt"
                    ]
                }
            }
        }
    ],
}

ちなみにReplicateの場合、Function callにほぼそのまま使えるJson Schemeが提供されています。
https://replicate.com/bytedance/seedream-4/api/schema


これだけで、いい感じに画像生成ができるようになります。

実装例

実際にHuddleLLM に実装した様子が以下のスクリーンショットです。

HuddleLLMについて

Chrome Web Store
https://chromewebstore.google.com/detail/huddlellm/edjbcjkcabpmpcpnpfjfcehegjkacgod
GitHub
https://github.com/bondICha/HuddleLLM---Chat-with-multiple-AI-API-together

HuddleLLMの実装では、画像出力と同時に、Tool Useで呼ばれたJSONも表示するようにしています。
画像を見ていただくと、いい感じでParameterが生成されていることがわかると思います。

Function Calling側のモデル選択の注意点

ChatbotエージェントとしてFunction Callingを利用する際、モデル選択が重要になります。私はZ.AIのGLMをよく使用しています(筆者はGLM Codingに加入中)。

Openなモデルとして最も有名なDeepSeekもFunction call対応を謳っていますが、OpenAIの仕様では以下のフォーマットで出力するところ、筆者が試す限りではDeepSeekはプレーンテキストとして直接出力してしまうので、使わないようにしています。

{
  "type": "function_call_output",
  "content": "..."
}

予算に余裕がある場合は、OpenAIやGeminiなどがやはり優れているように感じます。特にFunction callは正確にTool定義に従ってもらわないと困るので、そこは節約しないほうが良いかもしれません。

まとめ

画像に関しては、正直現時点ではどれが圧倒的に優れているというようなことはまだ起きておらず、どのモデルでも、うまく行ったり行かなかったり、うまくユースケースにハマったり思い通りにならなかったり、ということを繰り返しています(皆さんはどうですか?)。

Function Callでチャット形式で揃えておくことで、Nano bananaやOpenAIの画像生成と同じ枠組みで他の画像生成モデルも呼び出せるので、いろんなモデルを試しやすくなったのがこの方法の一番の利点であるように感じました。

また、今回Function callを始めて使ったのですが、すごくいい感じにToolを呼び出してくれますね。
以前、自然言語でうまくToolを呼び出させようと、プロンプトエンジニアリングに苦労していたのですが、こんなに簡単に外部APIを呼び出せるのは本当に便利になりました。

今さらですが、Function Callingの可能性を再発見するきっかけとなりました。

Discussion