For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
メインナビゲーション
Theme

ChatKit の高度な統合

自前のインフラで ChatKit を運用すると、カスタマイズの幅が広がります。

独自の認証方式、データレジデンシー、オンプレミスへのデプロイ、エージェントの独自のオーケストレーションなど、構成や運用を全面的に制御する必要がある場合は、自前のインフラで ChatKit を実行できます。OpenAI が提供する高度なセルフホスト方式では、ChatKit をカスタマイズして自前のサーバーで運用できます。

Agent Builder がホストする ChatKit ワークフローは現在、移行期間中です。新しい ChatKit アプリでは、ChatKit SDK と Agents SDK を使ってサーバー側にエージェントを実装し、その実装を基にアプリを構築してください。詳しくは ChatKit の移行ガイド →

自前のインフラでの ChatKit の運用

ChatKit の高度な統合では、自前の ChatKit サーバーを構築し、ウィジェットを追加してチャット画面を作成します。OpenAI の API と ChatKit サーバーを使って、OpenAI モデルを利用した独自のチャットを構築します。

OpenAI がホストする ChatKit

ChatKit サーバーのセットアップ

まず、GitHub のサーバーガイドに沿って、受信したリクエストを処理し、ツールを実行して、結果をクライアントにストリーミングする方法を確認してください。以下のコード例では、実装の主要な部分を示します。

1. サーバーパッケージのインストール

pip install openai-chatkit

2. サーバークラスの実装

ChatKitServer が会話の進行を管理します。respond をオーバーライドして、ユーザーメッセージやクライアントツールの出力を受け取るたびにイベントをストリーミングします。stream_agent_response などのヘルパーを使うと、サーバーを Agents SDK に接続できます。

class MyChatKitServer(ChatKitServer[RequestContext]):
    async def respond(
        self,
        thread: ThreadMetadata,
        input: UserMessageItem | ClientToolCallOutputItem | None,
        context: RequestContext,
    ) -> AsyncIterator[Event]:
        items_page = await self.store.load_thread_items(
            thread.id,
            after=None,
            limit=20,
            order="desc",
            context=context,
        )
        input_items = await simple_to_agent_input(list(reversed(items_page.data)))
        agent_context = AgentContext(
            thread=thread,
            store=self.store,
            request_context=context,
        )
        result = Runner.run_streamed(
            assistant_agent,
            input_items,
            context=agent_context,
        )
        async for event in stream_agent_response(agent_context, result):
            yield event

3. エンドポイントの公開

任意のフレームワークを使って、HTTP リクエストをサーバーインスタンスに転送します。以下は FastAPI を使う例です。

from fastapi import FastAPI, Request, Response
from fastapi.responses import StreamingResponse

app = FastAPI()
data_store = MemoryStore()
server = MyChatKitServer(data_store)


@app.post("/chatkit")
async def chatkit_endpoint(request: Request):
    result = await server.process(await request.body(), {})
    if isinstance(result, StreamingResult):
        return StreamingResponse(result, media_type="text/event-stream")
    return Response(content=result.json, media_type="application/json")

4. データストアのインターフェースの実装

データの保存には chatkit.store.Store を実装して、スレッド、メッセージ、ファイルを任意のデータベースに永続化します。ローカル開発では、データをメモリ内に保持する Store 実装を使えます。本番環境では永続ストレージを使用してください。データモデルを JSON ブロブとして保存することも検討してください。こうすると、ライブラリの更新に伴ってスキーマが変わっても、マイグレーションが不要になります。

5. ファイルストアのインターフェースの実装

アップロードをサポートする場合は、FileStore を実装してください。ChatKit は、クライアントがエンドポイントに POST でファイルを送信する直接アップロードと、クライアントが署名付き URL をリクエストしてからクラウドストレージにファイルをアップロードする 2 段階アップロードに対応しています。チャット内にサムネイルを表示できるようにプレビューを提供し、スレッドが削除されたときにはファイルの削除も処理してください。

6. サーバーからのクライアントツールの呼び出し

クライアントツールは、クライアントのオプションとエージェントの両方に登録する必要があります。ctx.context.client_tool_call を使って、Agents SDK のツールからクライアントツールの呼び出しをキューに追加します。

@function_tool(description_override="Add an item to the user's todo list.")
async def add_to_todo_list(ctx: RunContextWrapper[AgentContext], item: str) -> None:
    ctx.context.client_tool_call = ClientToolCall(
        name="add_to_todo_list",
        arguments={"item": item},
    )


assistant_agent = Agent[AgentContext](
    model="gpt-6-astra",
    name="Assistant",
    instructions="You are a helpful assistant",
    tools=[add_to_todo_list],
    tool_use_behavior=StopAtTools(stop_at_tool_names=[add_to_todo_list.name]),
)

7. スレッドのメタデータと状態の利用

スレッドの thread.metadata には、前回の Responses API の実行 ID や独自のラベルなど、サーバー側の状態を保存できます。メタデータはクライアントには公開されませんが、respond が呼び出されるたびに参照できます。

8. ツールの進捗状況の取得

実行に時間がかかるツールは、ProgressUpdateEvent を使って進捗状況を UI にストリーミングできます。ChatKit は、次のアシスタントメッセージまたはウィジェットの出力が届くと、進捗イベントをその内容で置き換えます。

9. サーバーコンテキストの利用

独自のコンテキストオブジェクトを server.process(body, context) に渡すと、アクセス権限を適用したり、データストアやファイルストアの実装にユーザーの識別情報を引き継いだりできます。

チャット画面への対話型ウィジェットの追加

ウィジェットを使うと、エージェントはチャット画面にカード、フォーム、テキストブロック、リストなど、さまざまなレイアウトの UI を表示できます。ヘルパー stream_widget を使えば、ウィジェットをすぐに表示することも、更新が届くたびにストリーミングすることもできます。

async def respond(
    self,
    thread: ThreadMetadata,
    input: UserMessageItem | ClientToolCallOutputItem | None,
    context: RequestContext,
) -> AsyncIterator[Event]:
    widget = Card(
        children=[
            Text(
                id="description",
                value="Generated summary",
            )
        ]
    )
    async for event in stream_widget(
        thread,
        widget,
        generate_id=lambda item_type: self.store.generate_item_id(
            item_type, thread, context
        ),
    ):
        yield event

ChatKit には、カード、リスト、フォーム、テキスト、ボタンなど、多様なウィジェットノードが用意されています。コンポーネントとプロパティの一覧やストリーミングの方法については、GitHub のウィジェットガイドを参照してください。

ウィジェットを試したり作成したりするには、Widget Builder の対話型 UI を利用できます。

アクションの利用

アクションを使うと、ユーザーメッセージを送信せずに ChatKit の UI から処理を開始できます。ActionConfig は、対応する任意のウィジェットノードに設定できます。ボタンや選択フィールドなどのコントロールから、新しいスレッド項目をストリーミングしたり、表示中のウィジェットをその場で更新したりできます。ウィジェットが Form 内にある場合、ChatKit はフォームから収集した値をアクションのペイロードに含めます。

サーバー側では、action メソッドを ChatKitServer に実装してペイロードを処理し、必要に応じて追加のイベントをストリーミングします。クライアント側でアクションを処理することもできます。その場合は handler="client" を設定し、JavaScript で応答してから、後続の処理をサーバーに転送します。

アクションを連鎖させる方法、厳密に型付けされたペイロードを作成する方法、クライアントとサーバーのハンドラーを連携させる方法については、GitHub のアクションガイドを参照してください。

リソース

統合を仕上げる際には、以下のリソースとリファレンスを活用してください。

デザインリソース

  • フォント OpenAI Sans Variable をダウンロードします。
  • ファイルを複製し、製品に合わせてコンポーネントをカスタマイズします。

イベントリファレンス

ChatKit は Web コンポーネントから CustomEvent インスタンスを発行します。ライフサイクルイベントをリッスンし、event.detail からペイロードのデータを読み取ります。

chatkit.addEventListener("chatkit.error", (event) => {
  console.error(event.detail.error);
});

chatkit.addEventListener("chatkit.response.start", () => {
  console.log("Response started");
});

chatkit.addEventListener("chatkit.response.end", () => {
  console.log("Response ended");
});

chatkit.addEventListener("chatkit.thread.change", (event) => {
  console.log("Active thread:", event.detail.threadId);
});

chatkit.addEventListener("chatkit.log", (event) => {
  console.log(event.detail.name, event.detail.data);
});

オプションリファレンス

オプション 型 説明 デフォルト値
apiURL string ChatKit サーバープロトコルを実装するエンドポイントを指定します。 必須
fetch typeof fetch fetch の呼び出しを上書きして、独自のヘッダーや認証を使用できます。 window.fetch
theme "light" | "dark" UI のテーマを指定します。 "light"
initialThread string | null マウント時に開くスレッドを指定します。null の場合は新規スレッド画面を表示します。 null
clientTools Record<string, Function> クライアント側で実行するツールのうち、モデルに公開するものを指定します。
header object | boolean ヘッダーの設定を指定します。false にするとヘッダーを非表示にします。 true
newThreadView object 挨拶文と会話を始めるためのプロンプトをカスタマイズします。
messages object フィードバックや注釈など、メッセージに関する機能を設定します。
composer object 添付ファイル、エンティティタグ、プレースホルダーテキストを設定します。
entities object エンティティの検索、クリック時の処理、プレビュー表示に使うコールバックを指定します。