함수

함수 (Functions)

함수 도구는 에이전트가 애플리케이션 코드를 호출하게 해 줘요. 함수와 인자를 정의하면 에이전트가 호출을 요청하고, 코드가 결과를 반환하며, 하네스가 턴을 이어가요.

출처: 문서

본문

핸들러는 애플리케이션 서버, 워커, 또는 사용자가 제어하는 환경에서 실행할 수 있어요. 세션에 환경을 연결한다고 해서 함수 도구가 자동으로 거기서 실행되는 건 아니에요.

Responses API에서 함수 호출을 사용한다면, 여기 설명하는 세션 흐름에 함수 구현을 그대로 재사용할 수 있어요.

함수 정의하기 (Define a function)

에이전트를 구성할 때 agent.tools에 함수 정의를 추가하세요. 이름, 설명, 그리고 인자용 JSON Schema를 넣어요:

{
  "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
  }
}

필수 작업 처리하기 (Handle required actions)

에이전트가 함수 결과를 필요로 하면 세션이 agent.session.requires_action을 내보내요. event.session.required_actions에서 대기 중인 호출을 읽으세요. 스트리밍 없이 세션을 검색하고 session.required_actions를 읽을 수도 있어요.

required_actions의 함수 항목은 이렇게 생겼어요:

{
  "type": "function_call",
  "turn_id": "turn_123",
  "call_id": "call_123",
  "name": "get_customer",
  "arguments": { "customer_id": "123" }
}

제공된 인자로 해당 함수를 실행하세요. required_actions를 사용해 어떤 호출에 결과가 필요한지 결정하세요. 세션 기록에 function_call 항목만 있다고 해서 결과가 대기 중이라는 뜻은 아니에요.

결과 반환하기 (Return the result)

세션 이벤트 엔드포인트에 agent.session.input.tool_result를 보내세요. 대기 중인 작업에서 turn_id와 call_id를 복사하세요:

  • 성공 시 success: true로 설정하고 output을 문자열 또는 지원되는 콘텐츠 배열로 제공하세요. JSON 객체는 문자열로 직렬화하세요.
  • 오류 시 success: false로 설정하고 에이전트가 사용할 수 있는 error 메시지를 제공하세요.

대기 중인 각 get_customer 호출에 대해 조회를 실행하고 결과를 반환하세요. 여기서 action은 required_actions의 항목이에요:

함수 결과 반환하기

const 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 },
  ],
});
import 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])
result := 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)
}
var 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());
require "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])

하네스는 필요한 결과를 받은 뒤 턴을 이어가요. 턴의 결과를 확인하고 출력을 검색하려면 세션 이벤트와 아이템을 따라가세요.

연결 끊김 후 복구하기 (Recover after a disconnect)

세션을 검색해 대기 중인 작업을 찾으세요. 이미 함수를 실행했다면 같은 turn_id와 call_id로 저장된 결과를 제출하세요.

부작용이 있는 함수라면 결과를 세션, 턴, 호출 ID별로 영구히 저장하세요. 실행이 성공했을 수도 있는데 결과가 저장되지 않았다면, 함수를 다시 실행하기 전에 결과를 확인하세요.

함수 주문형 로드하기 (Load functions on demand)

함수는 기본적으로 즉시 로드돼요. 함수를 지연하려면 정의에 defer_loading: true를 설정하고 agent.tools에 { "type": "tool_search" }를 포함하세요. 전체 예시는 Tool search를 참고하세요.

더 알아보기 (Learn more)