跳转至

上下文管理

“上下文”是一个多义词。你可能会关注两类主要的上下文: 1. 代码本地可用的上下文:这是工具函数运行时、on_handoff 等回调中、生命周期钩子等过程中可能需要的数据和依赖项。 2. 大语言模型(LLM)可用的上下文:这是大语言模型生成响应时所看到的数据。

本地上下文

这通过RunContextWrapper类及其内部的context属性来表示。其工作方式如下:

  1. 创建所需的任何Python对象。常见模式是使用数据类或Pydantic对象。
  2. 将该对象传递给各种运行方法(例如Runner.run(..., **context=whatever**))。
  3. 所有工具调用、生命周期钩子等都会收到一个包装器对象RunContextWrapper[T],其中T表示上下文对象类型,可通过wrapper.context访问。

最重要的是要注意:对于给定的智能体运行,每个智能体、工具函数、生命周期等都必须使用相同类型的上下文。

可以将上下文用于以下方面:

  • 运行的上下文数据(例如用户名/用户ID或其他有关用户的信息)
  • 依赖项(例如日志记录器对象、数据获取器等)
  • 辅助函数

注意

上下文对象不会发送到大语言模型(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)!
    # 这是一个工具。可以看到它接收一个`RunContextWrapper[UserInfo]`。工具实现从上下文中读取数据。
    return f"User {wrapper.context.name} is 47 years old"

async def main():
    user_info = UserInfo(name="John", uid=123)

    agent = Agent[UserInfo](  # (3)!
        # 我们使用泛型`UserInfo`标记智能体,以便类型检查器可以捕获错误(例如,如果我们尝试传递一个接受不同上下文类型的工具)。
        name="Assistant",
        tools=[fetch_user_age],
    )

    result = await Runner.run(  # (4)!
        # 上下文被传递给`run`函数。
        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())
1. 这是上下文对象。这里我们使用了数据类,但你可以使用任何类型。 2. 这是一个工具。可以看到它接收一个RunContextWrapper[UserInfo]。工具实现从上下文中读取数据。 3. 我们使用泛型UserInfo标记智能体,以便类型检查器可以捕获错误(例如,如果我们尝试传递一个接受不同上下文类型的工具)。 4. 上下文被传递给run函数。 5. 智能体正确调用工具并获取年龄。

智能体/大语言模型上下文

调用大语言模型(LLM)时,它能看到的 唯一 数据来自对话历史记录。这意味着,如果你想让大语言模型获取一些新数据,必须以某种方式将其添加到对话历史记录中。有几种方法可以做到这一点:

  1. 你可以将数据添加到智能体的 instructions 中。这也被称为 “系统提示词” 或 “开发者消息”。系统提示词可以是静态字符串,也可以是动态函数,接收上下文并输出字符串。对于始终有用的信息(例如,用户姓名或当前日期),这是一种常见策略。
  2. 在调用 Runner.run 函数时,将数据添加到 input 中。这与 instructions 策略类似,但允许你在 命令链 中使用级别较低的消息。
  3. 通过函数工具公开数据。这对于 按需 上下文很有用——大语言模型决定何时需要某些数据,并可以调用工具来获取该数据。
  4. 使用检索或网页搜索。这些是特殊工具,能够从文件或数据库(检索),或从网页(网页搜索)中获取相关数据。这对于将响应基于相关上下文数据很有用。