編按:之前寫過一篇提及用 OpenAI Agents SDK 寫 Function Calling 的部分,在這幾個月來 OpenAI 又有做不少更新,而且個人認為「很重要」的更新,因此又整理了這篇。
本篇為2025/9/1改寫自 OpenAI Agents SDK - Agents v0.2.10 版本。
OpenAI Agents SDK 中的 Agents模組與設定方式,涵蓋以下重點:
Agent 是什麼?
Agents 是 LLM 為核心(可配置 Instruction、工具、模型等)的應用主體,能執行指定任務。基本設定
name
:代理人的名稱(必填)。instructions
:系統提示/開發者說明。model
:指定 LLM 模型 & 可選擇 model_settings(如 temperature, top_p 等)。tools
:可接入的工具清單。
from agents import Agent, ModelSettings, function_tool
@function_tool
def get_weather(city: str) -> str:
"""returns weather info for the specified city."""
return f"The weather in {city} is sunny"
agent = Agent(
name="Haiku agent",
instructions="Always respond in haiku form",
model="o3-mini",
tools=[get_weather],
)
要串接的 Function Call,要用「@function_tool
」包起來,詳見前一篇文章。
沒有 tool 純粹定義 Agents() 的話 ,其實就是相當於基礎的 AI 呼叫,也是可行的喔!
from agents import Agent
agent = Agent(
name="Math Tutor",
instructions="You provide help with math problems. Explain your reasoning at each step and include examples",
)
Context(上下文)
Context 在 OpenAI Agents SDK 中,是一個依賴注入(dependency injection)工具,用來在 Agent 執行時傳遞依賴和狀態。簡單來說:
- Context 是你自訂的 Python 物件,可以包含資料、函式、連線等任何你執行 Agent 過程中所需要共用的資訊。
- 當你用
Runner.run()
執行 agent 時,把 context 傳進去,這個 context 會自動被傳給所有 agent、tools、handoff 等執行過程的每個步驟。 - 這種設計讓你不需要在全域環境裡硬塞依賴或參數,也不用反覆在 function 間手動傳遞資料。
- 舉例:或許可以放資料庫連線、API token、計數器、用戶 session 狀態等。
(編按:暫時我自己也沒有實作的案例,歡迎各位網友分享><)
@dataclass
class UserContext:
name: str
uid: str
is_pro_user: bool
async def fetch_purchases() -> list[Purchase]:
return ...
agent = Agent[UserContext](
...,
)
Output types(輸出型別)*筆者常用*必備*
支援指定 Pydantic 類型(或 dataclass、TypedDict 等),讓 Agent 直接產生結構化輸出。
from pydantic import BaseModel
from agents import Agent
class CalendarEvent(BaseModel):
name: str
date: str
participants: list[str]
agent = Agent(
name="Calendar extractor",
instructions="Extract calendar events from text",
output_type=CalendarEvent
)
- 只要有傳入
output_type
,模型回應就會使用structured outputs 機制,不再只是文字描述,而是 JSON 結構返回(或對應型別物件)。 - 這能大幅提升後端處理、前端呈現及跨服務串接的便利性與安全性。
- 雖然設定 JSON 結構化輸出,但你仍然可以指定特定欄位 Streaming 返回結果。
Handoffs(轉交機制)
Handoffs 就像公司裡的協作分工。當主 Agent 處理到某個階段,可以自動或依條件「轉派」指定子 Agent 或子工作去執行,最後將結果匯總或回傳。
假設你有一個主 Agent,負責處理客戶回饋,並根據內容分流給不同專長的子 agents(如維修 agent、退款 agent):
from agents import Agent
booking_agent = Agent(...)
refund_agent = Agent(...)
triage_agent = Agent(
name="Triage agent",
instructions=(
"Help the user with their questions."
"If they ask about booking, handoff to the booking agent."
"If they ask about refunds, handoff to the refund agent."
),
handoffs=[booking_agent, refund_agent],
)
執行流程中,當主 agent 判斷用戶需求屬於「退款」,就 handoff 給 refund_agent 處理。
優勢:
- 模組化管理:不同邏輯或任務分開維護,程式結構清晰。
- 彈性強:主 agent 可根據指令動態決定是否 handoff,以及選擇哪個子 agent。
編按:筆者開發的內容暫時沒有這麼複雜多層次的 Agents,但如果牽涉到多個層次的 Agent 轉交,值得使用此功能。
強迫工具使用(Forcing tool use)
預設情況下,當你給 Agent 提供了工具,LLM 不一定會真的選擇使用工具。
如果要明確控制工具使用行為,可以透過 ModelSettings.tool_choice
屬性來設定。設定方式及其行為如下:
"auto"
:讓 LLM 自行決定「是否」要用工具(預設值)"required"
: 強制 LLM 必須選擇一個工具(但可以自行選哪個)"none"
:強制 LLM 不允許用任何工具"my_tool"
:指定某個具體工具的名稱,強制 LLM 必須只用該工具
from agents import Agent, Runner, function_tool, ModelSettings
@function_tool
def get_weather(city: str) -> str:
"""Returns weather info for the specified city."""
return f"The weather in {city} is sunny"
agent = Agent(
name="Weather Agent",
instructions="Retrieve weather details.",
tools=[get_weather],
model_settings=ModelSettings(tool_choice="get_weather")
)
Tool Use Behavior(工具使用行為控制)
Tool Use Behavior(工具使用行為)是在 OpenAI Agents SDK 中專門用來控制 agent 工具呼叫後資料如何被處理、何時終止任務的設定參數。
這可精細決定 agent 執行工具後,該「直接把工具結果當回答」還是「再讓 LLM 推理一次」或「自訂複雜決策」,極大提升 agent 任務流程設計的彈性。
編按:有了這個設定超級重要!!
以下是主要幾個選項:
- "
run_llm_again
":預設值。工具結果完成後,再把結果送回 LLM,讓 LLM 綜合推理產生最終回應(適合多步推理、總結複雜訊息、或對工具結果不用太在乎(以LLM回覆是可接受的))。 - "
stop_on_first_tool
":第一次工具呼叫之結果直接作為最終回應,不再經過 LLM 處理。
from agents import Agent, Runner, function_tool, ModelSettings
@function_tool
def get_weather(city: str) -> str:
"""Returns weather info for the specified city."""
return f"The weather in {city} is sunny"
agent = Agent(
name="Weather Agent",
instructions="Retrieve weather details.",
tools=[get_weather],
tool_use_behavior="stop_on_first_tool"
)
StopAtTools
(stop_at_tool_names=[...])
:指定工具名稱,當呼叫到其中一個工具時,立刻結束並返回該工具結果。
from agents import Agent, Runner, function_tool
from agents.agent import StopAtTools
@function_tool
def get_weather(city: str) -> str:
"""Returns weather info for the specified city."""
return f"The weather in {city} is sunny"
@function_tool
def sum_numbers(a: int, b: int) -> int:
"""Adds two numbers."""
return a + b
agent = Agent(
name="Stop At Stock Agent",
instructions="Get weather or sum numbers.",
tools=[get_weather, sum_numbers],
tool_use_behavior=StopAtTools(stop_at_tool_names=["get_weather"])
)
- 自訂 function (
ToolsToFinalOutputResult
):提供自訂函式,根據工具回傳結果靈活決定要不要終止或繼續傳給 LLM 處理下一步。
from agents import Agent, Runner, function_tool, FunctionToolResult, RunContextWrapper
from agents.agent import ToolsToFinalOutputResult
from typing import List, Any
@function_tool
def get_weather(city: str) -> str:
"""Returns weather info for the specified city."""
return f"The weather in {city} is sunny"
def custom_tool_handler(
context: RunContextWrapper[Any],
tool_results: List[FunctionToolResult]
) -> ToolsToFinalOutputResult:
"""Processes tool results to decide final output."""
for result in tool_results:
if result.output and "sunny" in result.output:
return ToolsToFinalOutputResult(
is_final_output=True,
final_output=f"Final weather: {result.output}"
)
return ToolsToFinalOutputResult(
is_final_output=False,
final_output=None
)
agent = Agent(
name="Weather Agent",
instructions="Retrieve weather details.",
tools=[get_weather],
tool_use_behavior=custom_tool_handler
)
- (A)自訂工具 function
get_weather
:把 get_weather 定義為 agent 工具,只需傳入 city 字串,回傳天氣描述。 - (B)自訂 Tool Use Behavior:這個
custom_tool_handler
會檢查所有工具回傳(tool_results),只要 output 內包含 "sunny",即直接設定這就是 agent 最終輸出,中斷任務流程。 - 上面這段 code 展示可理解為「如何讓 agent 工具根據複雜邏輯 early stop」:agent 工具呼叫時會自訂一個 handler,依 tool output 決定是否立刻 return 結果,不必再走 LLM、用於最佳化回應流。
- (A)自訂工具 function
其他功能(不贅述)
個人覺得有點雞肋(或較簡易的功能),條列如下,就不贅述:
- 動態 instructions
Instruction 就是傳統的「system prompt」,其實你可以讓系統提示「更靈活」,只要摻雜變數,就可以讓系統提示動態根據情況調整。 - Agent 生命週期 Hooks
可設置 hooks 監控 agent 執行流程(如 log, 資料預取等)。 - Guardrails(欄杆/檢查)
可在 Agent 輸入/輸出階段做額外校驗或檢查,如可防止 prompt injection。 - clone() 複製 Agent
可快速複製一個 Agent 並改名或調整個別屬性。編按:實在想不到用在哪個地方XD
本篇翻譯改寫自官方文件: