Agent Builderだけで全て完結できると分かりやすいのですが、そういう訳にもいかないみたいです。
Agent BuilderのToolsのメニューにChatKitというカテゴリがあります。そこに含まれるClient ToolはAgent BuilderだけではなくChatKitを使わないと動かせません。
Widget Builderを使うとボタン付きのウィジェットを作れますが、Agent Builderだけではボタンをクリックしても何もおきません。ボタンをクリックした際の処理を動かすにはChatKitが必要です。
今回はClient Toolの動かし方とウィジェットのアクションの動かし方を解説します。
Client Tool
Client Toolとは?
Client Toolはブラウザに処理を委譲します。エージェントの処理中にブラウザへ何かを反映したい場合に使えます。サンプルで紹介されているのはテーマの変更です。本記事でもテーマ変更を例に解説します。
AgentノードにClient Toolを登録する
AgentノードのToolsからClient Toolをクリックすると、以下のような画面が表示されます。JSONで関数の定義を記述します。記述の仕方はFunction Callingの定義と同じです。

Client Toolで動かす関数が作成済みであればAIでJSON定義を作成することもできます。サンプル(openai-chatkit-starter-app)のChatKitPanel.tsxのonClientToolに以下のコードがあります。
if (invocation.name === "switch_theme") {
const requested = invocation.params.theme;
if (requested === "light" || requested === "dark") {
if (isDev) {
console.debug("[ChatKitPanel] switch_theme", requested);
}
onThemeRequest(requested);
return { success: true };
}
return { success: false };
}
ポップアップの Generate ボタンを押すと表示される入力欄に上記のコードを入力して Create ボタンをクリックするとJSONが作成されます。


ChatKitで動かす
ChatKitでエージェントを動かす方法は前の記事を参考にしてください。
「ダークテーマに変更してください。」と指示すると……

ダークテーマに変更されました!

ウィジェットのアクション
Widget Builderでは簡単にボタンを持つウィジェットを作成することができます。しかし、このボタンをクリックしても何もおきません。OpenAIのページにはonActionを実装すればアクションを処理できると書いてあるのですが、そのままでは動きません。
アクションが動く場所
実はアクションが動く場所には2つあります。
| 動く場所 | ChatKit | 実装場所 |
|---|---|---|
| サーバー側 | chatkit-python | ChatKitServerのaction |
| クライアント側 | chatkit-js | WidgetOptionのonAction |
Widget Builderで作ったウィジェットはサーバー側で動くようになっています。そのため、クライアント側の実装であるonActionに処理を書いても動きません。
ウィジェットのActionをクライアント側で動かす方法
ポイントは .widget のActionConfigです。Widget Builderでダウンロードした .widget を開くと以下のようなコードになっています。actionに handler: "client" を追加することでクライアント側で動くようになります。 handler: "client" を追加して保存した .widget ファイルをAgentノードにアップロードしてください。
<Card
size="sm"
padding={0}
confirm={{
label: "OK",
action: {
type: "agent.flight.confirm",
payload: {
decision: "ok",
flightNumber,
departureCity,
departureTime,
arrivalCity,
arrivalTime,
},
},
}}
cancel={{
label: "NG",
action: {
type: "agent.flight.confirm",
payload: {
decision: "ng",
flightNumber,
departureCity,
departureTime,
arrivalCity,
arrivalTime,
},
},
}}
>
ActionConfigについて
ActionConfigには2つのプロパティがあります。アクションを処理するにはこの2つのパラメータが重要です。
| プロパティ | 内容 |
|---|---|
| type | Actionを識別する文字列 |
| payload | ウィジェットから送信される値 |
Actionを処理するコード
クライアント側(chatkit-js)
クライアント側の実装ではWidgetsのonActionに処理を記述します。
const chatkit = useChatKit({
~中略~
widgets: {
onAction: async (action, widgetItem) => {
if (action.type == "agent.flight.confirm") {
if (action.payload?.decision == "ok") {
await sendUserMessageRef.current?.({
text: `承認しました。`,
});
}
}
},
},
~中略~
});
サーバー側(chatkit-python)
ChatKitServerにactionメソッドを実装します。
async def action(
self,
thread: ThreadMetadata,
action: Action[str, Any],
sender: WidgetItem | None,
context: RequestContext,
) -> AsyncIterator[ThreadStreamEvent]:
if action.type == "agent.flight.confirm":
if action.payload['decision'] == 'ok':
# ユーザーメッセージ
result_item=UserMessageItem(
id = _gen_id("msg"),
thread_id = thread.id,
created_at = datetime.now(),
type="user_message",
content=[
UserMessageTextContent(
type="input_text",
text="承認しました。"
)
],
inference_options=InferenceOptions(
tool_choice=None,
model=None,
)
)
# スレッドにアイテムを追加
yield ThreadItemAddedEvent(
type="thread.item.added",
item=result_item
)
# スレッドの完了
yield ThreadItemDoneEvent(item=result_item)
まとめ
ChatKitを使わないと動かせない機能2つをご紹介しました。Client Toolを使えばブラウザを操作できます。アクションを使えばエージェントでユーザーの入力を受け付けることができます。
どちらもOpenAIのページに記述はあるのですが、完全ではないためそのまま真似しても動きません。動かすのに苦労している人の参考になればと思います。
この記事を書いた人
