Context 管理
Context(上下文)是一個容易產生歧義的術語。你可能會關心兩大類主要的 context:
- 程式碼本地可用的 context:這是指在工具(Tools)函式執行時、像是
on_handoff
這類回呼(callback)、生命週期(lifecycle)hooks 等時,你可能需要的資料與相依套件(dependencies)。 - 提供給大型語言模型 (LLM) 的 context:這是指 LLM 在產生回應時可見的資料。
本地 context
這是透過 [RunContextWrapper
][agents.run_context.RunContextWrapper] 類別以及其內的 [context
][agents.run_context.RunContextWrapper.context] 屬性來表示。其運作方式如下:
- 你可以建立任何你想要的 Python 物件。常見的做法是使用 dataclass 或 Pydantic 物件。
- 將該物件傳遞給各種 run 方法(例如
Runner.run(..., **context=whatever**))
)。 - 所有的工具(Tools)呼叫、生命週期 hooks 等,都會收到一個包裝物件
RunContextWrapper[T]
,其中T
代表你的 context 物件型別,你可以透過wrapper.context
存取。
最重要 的注意事項:每一次 Agent 執行時,所有 Agent、工具函式、生命週期等,都必須使用相同 型別 的 context。
你可以將 context 用於以下情境:
- 執行時的情境資料(例如:使用者名稱/uid 或其他使用者相關資訊)
- 相依套件(例如:logger 物件、資料擷取器等)
- 輔助函式
Note
context 物件不會被傳送到大型語言模型 (LLM)。它純粹是一個本地物件,你可以從中讀取、寫入,也可以呼叫其方法。
import asyncio
from dataclasses import dataclass
from agents import Agent, RunContextWrapper, Runner, function_tool
@dataclass
class UserInfo: # (1)!
name: str
uid: int
@function_tool
async def fetch_user_age(wrapper: RunContextWrapper[UserInfo]) -> str: # (2)!
"""Fetch the age of the user. Call this function to get user's age information."""
return f"The user {wrapper.context.name} is 47 years old"
async def main():
user_info = UserInfo(name="John", uid=123)
agent = Agent[UserInfo]( # (3)!
name="Assistant",
tools=[fetch_user_age],
)
result = await Runner.run( # (4)!
starting_agent=agent,
input="What is the age of the user?",
context=user_info,
)
print(result.final_output) # (5)!
# The user John is 47 years old.
if __name__ == "__main__":
asyncio.run(main())
- 這是 context 物件。我們這裡使用了 dataclass,但你也可以使用任何型別。
- 這是一個工具 (Tool)。你可以看到它接收一個
RunContextWrapper[UserInfo]
。這個工具的實作會從 context 讀取資料。 - 我們使用泛型
UserInfo
標記 Agent,這樣型別檢查器就能捕捉錯誤(例如,如果我們嘗試傳入一個需要不同 context 型別的工具)。 - context 會被傳遞給
run
函式。 - Agent 正確地呼叫工具並取得 age。
Agent/LLM context
當呼叫大型語言模型 (LLM) 時,它唯一能看到的資料就是對話歷史。這代表如果你想讓 LLM 取得新的資料,必須以能讓該資料出現在對話歷史中的方式提供。你可以用幾種方式達成:
- 你可以把資料加到 Agent 的
instructions
。這也被稱為「系統提示詞 (system prompt)」或「開發者訊息 (developer message)」。系統提示詞可以是靜態字串,也可以是接收 context 並輸出字串的動態函式。這是針對總是有用的資訊(例如使用者名稱或當前日期)常見的做法。 - 在呼叫
Runner.run
函式時,將資料加入input
。這和instructions
做法類似,但允許你在指令鏈中較低層級的訊息。 - 透過 function tools 曝露資料。這適合「隨需」context——LLM 需要某些資料時,可以呼叫工具取得。
- 使用檢索 (retrieval) 或網頁搜尋 (web search)。這些是能從檔案或資料庫(檢索),或從網路(網頁搜尋)抓取相關資料的特殊工具。這對於讓回應「有根據」於相關情境資料特別有用。