関数ツールを使うと、エージェントからアプリケーションのコードを呼び出せます。関数とその引数は開発者が定義します。エージェントが呼び出しをリクエストし、コードが結果を返すと、ハーネスがターンを続行します。
ハンドラーは、アプリケーションサーバー、ワーカー、または開発者が管理する環境で実行できます。セッションに環境を接続しても、その環境で関数ツールが自動的に実行されるわけではありません。
Responses API の Function Calling を使用している場合は、ここで説明するセッションのフローでも既存の関数実装を再利用できます。
エージェントの設定時に、agent.tools に関数定義を追加します。名前、説明、引数の JSON Schema を指定します。
1234567891011{
"type": "function",
"name": "get_customer",
"description": "Look up a customer by ID.",
"parameters": {
"type": "object",
"properties": { "customer_id": { "type": "string" } },
"required": ["customer_id"],
"additionalProperties": false
}
}
エージェントが関数の結果を必要とすると、セッションは agent.session.requires_action を発行します。event.session.required_actions から保留中の呼び出しを読み取ってください。ストリーミングを使わずに、セッションを取得して session.required_actions を読み取ることもできます。
required_actions 内の関数エントリは次のようになります。
1234567{
"type": "function_call",
"turn_id": "turn_123",
"call_id": "call_123",
"name": "get_customer",
"arguments": { "customer_id": "123" }
}
指定された名前の関数を、渡された引数で実行します。どの呼び出しに結果が必要かは、required_actions を使って判断してください。セッション履歴に function_call アイテムがあるだけでは、結果待ちであるとは判断できません。
agent.session.input.tool_result をセッションイベントのエンドポイントに送信します。保留中のアクションから turn_id と call_id をコピーしてください。
- 成功した場合は
success: true を設定し、output を文字列またはサポートされているコンテンツ配列として渡します。JSON オブジェクトは文字列にシリアライズしてください。
- エラーの場合は
success: false を設定し、エージェントが利用できるメッセージを error に指定します。
保留中の get_customer 呼び出しごとに検索処理を実行し、その結果を返します。ここで、action は required_actions のエントリです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16const result = {
turn_id: action.turn_id,
call_id: action.call_id,
};
let outcome;
outcome = {
success: true,
output: JSON.stringify(getCustomer(action.arguments)),
};
await client.beta.agents.sessions.events.create(sessionId, {
events: [
{ type: "agent.session.input.tool_result", ...result, ...outcome },
],
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14import json
action = action.to_dict()
result = {
"type": "agent.session.input.tool_result",
"turn_id": action["turn_id"],
"call_id": action["call_id"],
}
output = get_customer(action["arguments"])
result.update(success=True, output=json.dumps(output))
client.beta.agents.sessions.events.create(session_id, events=[result])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24result := openai.AgentSessionInputParamAgentSessionInputToolResult{
TurnID: action.TurnID,
CallID: action.CallID,
}
arguments := action.Arguments.(map[string]any)
customerID := arguments["customer_id"].(string)
var customer any
if customerID == "123" {
customer = map[string]any{"name": "Example Customer", "plan": "pro"}
}
output, err := json.Marshal(map[string]any{"found": customer != nil, "customer": customer})
if err != nil {
panic(err)
}
result.Success = true
result.Output = openai.AgentFunctionCallOutputParamUnion{OfString: openai.String(string(output))}
err = client.Beta.Agents.Sessions.Events.New(ctx, session.ID, openai.BetaAgentSessionEventNewParams{
Events: []openai.AgentSessionInputParamUnion{{OfParamAgentSessionInputToolResult: &result}},
})
if err != nil {
panic(err)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25var json = new JsonMapper();
var result =
AgentSessionInputParam.AgentSessionInputToolResult.builder()
.turnId(action.turnId())
.callId(action.callId());
var arguments = json.valueToTree(action._arguments());
boolean found = arguments.path("customer_id").asText().equals("123");
var output = json.createObjectNode().put("found", found);
if (found)
output.putObject("customer").put("name", "Example Customer").put("plan", "pro");
else output.putNull("customer");
result.success(true).output(json.writeValueAsString(output));
client
.beta()
.agents()
.sessions()
.events()
.create(
EventCreateParams.builder()
.sessionId(sessionId)
.addEvent(result.build())
.build());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18require "json"
result = {
type: "agent.session.input.tool_result",
turn_id: action.turn_id,
call_id: action.call_id
}
arguments = action.arguments
customer_id = arguments[:customer_id] || arguments["customer_id"]
customer = (customer_id == "123") ? {
name: "Example Customer",
plan: "pro"
} : nil
result[:success] = true
result[:output] = JSON.generate(found: !customer.nil?, customer: customer)
client.beta.agents.sessions.events.create(session.id, events: [result])
ハーネスは、必要な結果を受け取るとターンを続行します。セッションのイベントとアイテムを追跡して、ターンの結果を確認し、出力を取得してください。
セッションを取得して、保留中のアクションを確認します。すでに関数を実行している場合は、保存済みの結果を同じ turn_id と call_id で送信してください。
副作用のある関数では、セッション、ターン、呼び出し ID に紐づけて結果を永続的に保存してください。実行が成功した可能性があるものの、結果が保存されていない場合は、関数を再実行する前に実行結果を確認してください。
デフォルトでは、関数は事前に読み込まれます。関数の読み込みを遅延させるには、その定義に defer_loading: true を設定し、agent.tools に { "type": "tool_search" } を含めます。完全な例については、ツール検索を参照してください。