Skip to content

代理 (Agents)

代理 (Agents) 是應用程式中的核心組件。Agent 是一個大型語言模型 (LLM),並經過指令與工具的設定。

基本設定

你最常需要設定的 agent 屬性包括:

  • name:必填字串,用於識別你的 agent。
  • instructions:也稱為開發者訊息或系統提示詞 (system prompt)。
  • model:指定要使用哪個大型語言模型 (LLM),以及可選的 model_settings,用於設定模型調整參數,例如 temperature、top_p 等。
  • tools:Agent 可用來完成任務的工具 (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],
)

Context

代理(Agents)在其 context 類型上是泛型的。Context(上下文)是一種相依套件注入(dependency-injection)工具:它是一個你自行建立並傳遞給 Runner.run() 的物件,該物件會被傳遞給每個代理、工具(Tools)、交接(Handoffs)等,並作為代理執行期間的相依套件與狀態的集合。你可以提供任何 Python 物件作為 context。

@dataclass
class UserContext:
    name: str
    uid: str
    is_pro_user: bool

    async def fetch_purchases() -> list[Purchase]:
        return ...

agent = Agent[UserContext](
    ...,
)

輸出類型

預設情況下,代理(Agent)會產生純文字(即 str)輸出。如果你希望代理產生特定類型的輸出,可以使用 output_type 參數。常見的選擇是使用 Pydantic 物件,但我們也支援任何可以包裝在 Pydantic TypeAdapter 中的類型——例如 dataclasses、lists、TypedDict 等。

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,
)

Note

當你傳遞 output_type 時,這會告訴模型使用結構化輸出,而不是一般的純文字回應。

多代理 (multi-agent) 系統設計模式

設計多代理 (multi-agent) 系統有許多方式,但我們常見到兩種廣泛適用的設計模式:

  1. 管理者(作為工具的 agent):一個中央管理者/協調者會將專門的子代理 (sub-agents) 當作工具來呼叫,並持續掌控對話流程。
  2. 交接 (Handoffs):同層級的代理會將控制權交接給專門的代理,由其接管對話。這屬於去中心化設計。

更多細節請參閱我們的代理 (Agents) 實作指南

管理者(作為工具的 agent)

customer_facing_agent 處理所有使用者互動,並呼叫以工具 (Tools) 形式公開的專門子代理 (sub-agents)。詳細內容請參閱 工具 (Tools) 文件。

from agents import Agent

booking_agent = Agent(...)
refund_agent = Agent(...)

customer_facing_agent = Agent(
    name="Customer-facing agent",
    instructions=(
        "Handle all direct user communication. "
        "Call the relevant tools when specialized expertise is needed."
    ),
    tools=[
        booking_agent.as_tool(
            tool_name="booking_expert",
            tool_description="Handles booking questions and requests.",
        ),
        refund_agent.as_tool(
            tool_name="refund_expert",
            tool_description="Handles refund questions and requests.",
        )
    ],
)

交接 (Handoffs)

交接 (Handoffs) 是 Agent 可以委派給的子代理 (sub-agents)。當發生交接時,被委派的 Agent 會接收對話歷史,並接手後續的對話。這種模式讓 Agent 可以模組化,並專注於單一任務,發揮專業能力。更多資訊請參閱 handoffs 文件。

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, hand off to the booking agent. "
        "If they ask about refunds, hand off to the refund agent."
    ),
    handoffs=[booking_agent, refund_agent],
)

動態指令

在大多數情況下,你可以在建立 Agent 時提供指令。不過,你也可以透過函式動態提供指令。該函式會接收 Agent 和 context,並且必須回傳提示詞 (prompts)。一般函式與 async 函式皆可接受。

def dynamic_instructions(
    context: RunContextWrapper[UserContext], agent: Agent[UserContext]
) -> str:
    return f"The user's name is {context.context.name}. Help them with their questions."


agent = Agent[UserContext](
    name="Triage agent",
    instructions=dynamic_instructions,
)

生命週期事件(hooks)

有時候,你可能希望觀察 Agent 的生命週期。例如,你可能想要記錄事件,或是在特定事件發生時預先擷取資料。你可以透過 hooks 屬性來掛接 Agent 的生命週期。只需繼承 [AgentHooks][agents.lifecycle.AgentHooks] 類別,並覆寫你感興趣的方法即可。

Guardrails

Guardrails(防護欄)允許你在 Agent 執行時,對使用者輸入進行平行檢查/驗證,以及在 Agent 輸出產生後對其進行檢查。例如,你可以篩選使用者輸入與 Agent 輸出的相關性。詳情請參閱 guardrails 文件。

複製/拷貝 Agent

透過在 Agent 上使用 clone() 方法,你可以複製一個 Agent,並可選擇性地修改任何你想變更的屬性。

pirate_agent = Agent(
    name="Pirate",
    instructions="Write like a pirate",
    model="o3-mini",
)

robot_agent = pirate_agent.clone(
    name="Robot",
    instructions="Write like a robot",
)

強制工具 (Tool) 使用

僅僅提供工具 (Tools) 清單,並不代表大型語言模型 (LLM) 一定會使用工具。你可以透過設定 [ModelSettings.tool_choice][agents.model_settings.ModelSettings.tool_choice] 來強制 LLM 使用工具。有效的設定值包括:

  1. auto,允許 LLM 自行決定是否要使用工具。
  2. required,要求 LLM 必須使用工具(但可以智慧地選擇要用哪一個工具)。
  3. none,要求 LLM 不得 使用工具。
  4. 設定特定字串,例如 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")
)

工具 (Tools) 使用行為

Agent 設定中的 tool_use_behavior 參數用於控制工具 (Tools) 輸出的處理方式:

  • "run_llm_again":預設值。工具會被執行,且大型語言模型 (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=[...]): 當呼叫到任何指定的工具 (Tools) 時即停止,並將其輸出作為最終回應。
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"])
)
  • ToolsToFinalOutputFunction: 一個自訂函式,用於處理工具 (Tools) 的結果,並決定是否要停止或繼續與大型語言模型 (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
)

Note

為了防止無限迴圈,該框架會在工具 (Tool) 呼叫後自動將 tool_choice 重設為 "auto"。此行為可透過 [agent.reset_tool_choice][agents.agent.Agent.reset_tool_choice] 進行設定。無限迴圈的原因在於工具結果會被傳送給大型語言模型 (LLM),而 LLM 因為 tool_choice 而再次產生新的工具呼叫,如此反覆無窮。