跳过内容

运行 agents

您可以通过 Runner 类运行代理。您有 3 个选项

  1. Runner.run(),它异步运行并返回一个 RunResult
  2. Runner.run_sync(),这是一个同步方法,只是在底层运行 .run()
  3. Runner.run_streamed(),它异步运行并返回一个 RunResultStreaming。它以流式模式调用 LLM,并将这些事件在接收到时流式传输给您。
from agents import Agent, Runner

async def main():
    agent = Agent(name="Assistant", instructions="You are a helpful assistant")

    result = await Runner.run(agent, "Write a haiku about recursion in programming.")
    print(result.final_output)
    # Code within the code,
    # Functions calling themselves,
    # Infinite loop's dance

更多信息请参阅 结果指南

代理循环

当您在 Runner 中使用 run 方法时,您传入一个起始代理和输入。输入可以是字符串(被视为用户消息),也可以是输入项的列表,这些项是 OpenAI Responses API 中的项。

然后,runner 运行一个循环

  1. 我们为当前代理和当前输入调用 LLM。
  2. LLM 产生其输出。
    1. 如果 LLM 返回一个 final_output,循环结束,我们返回结果。
    2. 如果 LLM 执行交接,我们会更新当前代理和输入,并重新运行循环。
    3. 如果 LLM 产生工具调用,我们会运行这些工具调用,附加结果,并重新运行循环。
  3. 如果超过传递的 max_turns,我们会引发一个 MaxTurnsExceeded 异常。

注意

LLM 输出是否被视为“最终输出”的规则是,它产生具有所需类型的文本输出,并且没有工具调用。

流式传输

流式传输还允许您在 LLM 运行时接收流式传输事件。一旦流式传输完成,RunResultStreaming 将包含有关运行的完整信息,包括所有产生的新输出。您可以调用 .stream_events() 获取流式传输事件。更多信息请参阅 流式传输指南

运行配置

run_config 参数允许您配置代理运行的一些全局设置

  • model:允许设置全局 LLM 模型以供使用,无论每个 Agent 的 model 如何。
  • model_provider:用于查找模型名称的模型提供程序,默认值为 OpenAI。
  • model_settings:覆盖特定代理的设置。例如,您可以设置全局 temperaturetop_p
  • input_guardrailsoutput_guardrails:要在所有运行中包含的输入或输出防护栏列表。
  • handoff_input_filter:应用于所有交接的全局输入过滤器,如果交接本身没有过滤器。输入过滤器允许您编辑发送到新代理的输入。有关更多详细信息,请参阅 Handoff.input_filter 中的文档。
  • nest_handoff_history:当为 True(默认值)时,runner 在调用下一个代理之前会将先前的对话记录折叠成单个助手消息。助手会将内容放在一个 <CONVERSATION HISTORY> 块中,该块会随着后续交接的发生而不断追加新的对话轮次。如果您想恢复旧行为,请将此设置为 False 或提供自定义交接过滤器。单个交接可以通过 Handoff.nest_handoff_history 覆盖此设置。
  • handoff_history_mapper:可选的可调用对象,每当 nest_handoff_historyTrue 时,都会接收规范化的对话记录(历史记录 + 交接项)。它必须返回要转发给下一个代理的确切输入项列表,允许您替换内置摘要,而无需编写完整的交接过滤器。
  • tracing_disabled:允许您为整个运行禁用 追踪
  • trace_include_sensitive_data:配置追踪是否包含潜在的敏感数据,例如 LLM 和工具调用的输入/输出。
  • workflow_nametrace_idgroup_id:设置运行的追踪工作流名称、追踪 ID 和追踪组 ID。我们建议至少设置 workflow_name。组 ID 是一个可选字段,允许您将多个运行的追踪关联起来。
  • trace_metadata:要在所有追踪中包含的元数据。

默认情况下,SDK 现在会在代理交接给另一个代理时,将先前的对话轮次嵌套在单个助手摘要消息中。这减少了重复的助手消息,并将完整的对话记录保存在一个新代理可以快速扫描的单个块中。如果您想恢复旧行为,请传递 RunConfig(nest_handoff_history=False) 或提供一个 handoff_input_filter(或 handoff_history_mapper),以精确地转发对话。您还可以通过设置 handoff(..., nest_handoff_history=False)True 为特定的交接选择退出(或加入)。要更改生成的摘要中使用的包装器文本而不编写自定义映射器,请调用 set_conversation_history_wrappers(和 reset_conversation_history_wrappers 以恢复默认值)。

对话/聊天线程

调用任何运行方法都可能导致一个或多个代理运行(因此一个或多个 LLM 调用),但它代表了聊天对话中的单个逻辑轮次。例如

  1. 用户轮次:用户输入文本
  2. Runner 运行:第一个代理调用 LLM,运行工具,交接给第二个代理,第二个代理运行更多工具,然后产生输出。

在代理运行结束时,您可以选择向用户显示什么。例如,您可能向用户显示代理生成的所有新项,或者只显示最终输出。无论哪种方式,用户都可能提出后续问题,在这种情况下,您可以再次调用 run 方法。

手动对话管理

您可以使用 RunResultBase.to_input_list() 方法手动管理对话历史记录,以获取下一轮次的输入

async def main():
    agent = Agent(name="Assistant", instructions="Reply very concisely.")

    thread_id = "thread_123"  # Example thread ID
    with trace(workflow_name="Conversation", group_id=thread_id):
        # First turn
        result = await Runner.run(agent, "What city is the Golden Gate Bridge in?")
        print(result.final_output)
        # San Francisco

        # Second turn
        new_input = result.to_input_list() + [{"role": "user", "content": "What state is it in?"}]
        result = await Runner.run(agent, new_input)
        print(result.final_output)
        # California

使用会话自动对话管理

对于更简单的方法,您可以使用 会话 自动处理对话历史记录,而无需手动调用 .to_input_list()

from agents import Agent, Runner, SQLiteSession

async def main():
    agent = Agent(name="Assistant", instructions="Reply very concisely.")

    # Create session instance
    session = SQLiteSession("conversation_123")

    thread_id = "thread_123"  # Example thread ID
    with trace(workflow_name="Conversation", group_id=thread_id):
        # First turn
        result = await Runner.run(agent, "What city is the Golden Gate Bridge in?", session=session)
        print(result.final_output)
        # San Francisco

        # Second turn - agent automatically remembers previous context
        result = await Runner.run(agent, "What state is it in?", session=session)
        print(result.final_output)
        # California

会话自动

  • 在每次运行之前检索对话历史记录
  • 在每次运行后存储新消息
  • 为不同的会话 ID 维护单独的对话

更多详细信息请参阅 会话文档

服务器管理的对话

您还可以让 OpenAI 对话状态功能在服务器端管理对话状态,而不是使用 to_input_list()Sessions 在本地处理它。这允许您在不手动重新发送所有过去消息的情况下保留对话历史记录。更多详细信息请参阅 OpenAI 对话状态指南

OpenAI 提供了两种跨轮次跟踪状态的方法

1. 使用 conversation_id

您首先使用 OpenAI Conversations API 创建一个对话,然后为后续的每个调用重用其 ID

from agents import Agent, Runner
from openai import AsyncOpenAI

client = AsyncOpenAI()

async def main():
    agent = Agent(name="Assistant", instructions="Reply very concisely.")

    # Create a server-managed conversation
    conversation = await client.conversations.create()
    conv_id = conversation.id

    while True:
        user_input = input("You: ")
        result = await Runner.run(agent, user_input, conversation_id=conv_id)
        print(f"Assistant: {result.final_output}")

2. 使用 previous_response_id

另一种选择是 响应链式调用,其中每个轮次显式链接到前一个轮次的响应 ID。

from agents import Agent, Runner

async def main():
    agent = Agent(name="Assistant", instructions="Reply very concisely.")

    previous_response_id = None

    while True:
        user_input = input("You: ")

        # Setting auto_previous_response_id=True enables response chaining automatically
        # for the first turn, even when there's no actual previous response ID yet.
        result = await Runner.run(
            agent,
            user_input,
            previous_response_id=previous_response_id,
            auto_previous_response_id=True,
        )
        previous_response_id = result.last_response_id
        print(f"Assistant: {result.final_output}")

长期运行的代理和人工参与循环

您可以使用 Agents SDK Temporal 集成来运行持久的、长期运行的工作流程,包括人工参与循环的任务。观看 Temporal 和 Agents SDK 协同工作完成长期运行任务的演示 在此视频中,并 在此处查看文档

异常

SDK 在某些情况下会引发异常。完整的列表在 agents.exceptions 中。总览如下

  • AgentsException:这是 SDK 中引发的所有异常的基类。它充当所有其他特定异常的通用类型。
  • MaxTurnsExceeded:当代理的运行超过传递给 Runner.runRunner.run_syncRunner.run_streamed 方法的 max_turns 限制时,会引发此异常。它表示代理无法在指定的交互轮次数内完成其任务。
  • ModelBehaviorError:当底层模型(LLM)产生意外或无效的输出时,会发生此异常。这包括
    • 格式错误的 JSON:当模型为工具调用或其直接输出提供格式错误的 JSON 结构时,尤其是在定义了特定的 output_type 时。
    • 意外的工具相关故障:当模型未能以预期的方式使用工具时
  • UserError:当您(使用 SDK 编写代码的人)在使用 SDK 时出错时,会引发此异常。这通常是由于不正确的代码实现、无效的配置或 SDK API 的错误使用造成的。
  • InputGuardrailTripwireTriggeredOutputGuardrailTripwireTriggered:当输入防护栏或输出防护栏的条件满足时,会引发此异常。输入防护栏检查传入消息,然后再进行处理,而输出防护栏检查代理的最终响应,然后再进行交付。