• Dify 是一个开源的 LLM 应用开发平台。其直观的界面结合了 AI 工作流、RAG 管道、Agent、模型管理、可观测性功能等,让您可以快速从原型到生产。

    AI+Web3: 从理论到实战的进阶之路

    大模型炼成

    image-20250317211316601

    引用自 https://www.youtube.com/watch?v=bZQun8Y4L2A

    局限:幻觉;实时知识;复杂推理;私有数据;交互决策;数学(9.9和9.11哪个大);复杂文字逻辑/歧义,等等。所以使用LLM仍要谨慎。

    大模型应用

    01 提示词工程

    情境学习(In Context Learning):提供少量样本示例,Few-shot

    思维链(Chain of Thought / CoT)

    提示词工程(Prompt Engineering):明确问题、提供上下文、明确期望、人类反馈(多轮对话)、英文提示词

    提示词注入/泄露/越狱:比如被问出了windows11专业版的序列号

    02 RAG

    (Retrieval-Augmented Generation)

    1.什么是Embedding/嵌入向量

    Embedding是由AI算法生成的高维度的向量数据,代表着数据的不同特征。

    2.多模态Embedding

    CLIP模型 embedding维度:512,768

    3.RAG的核心思路

    image-20250318135212132

    类似于开卷考试。检索出相关信息,和问题一起交给大模型。

    03 智能体

    智能体Agent的概念,还处于非常早期的阶段。

    理想很美好:给出指令,并观察其自动化执行,节约做事的时间成本。

    但现实很骨感:生成内容不可靠,过程不稳定,严重依赖人工经验判断。

    image-20250318141751597

    定义:LLM+工具,外部工具(Function Call)实现LLM能力的显式扩展,生成过程可溯源、可解释。

    示例:图中有几个穿着红白条纹毛衣的人?

    ChatGPT无法完成处理图片,但是通过外接工具,这项任务可以完成。(1) 调用SAM 找到图中所有的人 (2) 调用CLIP判断这些人中哪些符合条件。 并且这些操作由智能体自主进行。

    04 大模型的下游任务

    例如:文本摘要、文本分类、机器翻译、问答、关系抽取、NL2SQL(自然语言问题转化为SQL查询语句)

    对某个下游任务进行针对性微调。

    大模型Agent开发框架

    低代码框架无需代码即可完成Agent开发

    Coze(零代码,编排系统基于FlowGram)、Dify(低代码,编排系统基于React Flow)、LangFlow(低代码,LangChain家族的)、FastGPT(开源

    基础框架:借助大模型原生能力进行Agent开发

    function calling、tool use

    代码框架:借助代码完成Agent开发

    LangChain、LangGraph(LangChain家族的,更灵活复杂)、LlamaIndex

    Multi-Agent框架/架构

    CrewAI(基于LangChain构建的一个更加上层的框架)、Swarm(轻量、开源,用于教学和实验)、Assistant API(OpenAI的、闭源)、openai-agents(Swarm 的升级版,可投入生产)

    热门项目AutoGen、MetaGPT

     

    Coze

    Dify

    Note

    Dify 一词源自 Define + Modify,意指定义并且持续的改进你的 AI 应用,它是为你而做的(Do it for you)。

    是一款低代码(low code)生成式AI应用创新引擎。最大的竞品是字节的Coze(扣子)。

    Dify官方文档

    Dify 是一款开源的低代码LLM应用开发平台。它融合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者可以快速搭建生产级的生成式 AI 应用。

    由于 Dify 内置了构建 LLM 应用所需的关键技术栈,包括对数百个模型的支持、直观的 Prompt 编排界面、高质量的 RAG 引擎、稳健的 Agent 框架、灵活的流程编排,并同时提供了一套易用的界面和 API。这为开发者节省了许多重复造轮子的时间,使其可以专注在创新和业务需求上。

    为什么使用 Dify?

    Dify 能做什么?

    下一步行动

    Dify实践

    你可以通过 3 种方式在 Dify 的工作室内创建应用:

    聊天助手

    对话型应用采用一问一答模式与用户持续对话。

    对话型应用的编排支持:对话前提示词,变量,上下文,开场白和下一步问题建议。

    Tip

    应用工具箱:

    • 对话开场白

    • 下一步问题建议

    • 文字转语音

    • 语音转文字

    • 引用与归属

    • 内容审查

    • 标注回复

    多模型调试

    你可以同时批量检视不同模型对于相同问题的回答效果。

    发布应用
    智能体

    Agent 定义

    智能助手(Agent Assistant),利用大语言模型的推理能力,能够自主对复杂的人类任务进行目标规划、任务拆解、工具调用、过程迭代,并在没有人类干预的情况下完成任务。

    工作流

    工作流通过将复杂的任务分解成较小的步骤(节点)降低系统复杂度,减少了对提示词技术和模型推理能力的依赖,提高了 LLM 应用面向复杂任务的性能,提升了系统的可解释性、稳定性和容错性。

    Dify 工作流分为两种类型:

    如何开始
    关键概念

    Dify实操

    Dify 是一个开源的 LLM 应用开发平台。其直观的界面结合了 AI 工作流、RAG 管道、Agent、模型管理、可观测性功能等,让您可以快速从原型到生产。

    启动Dify

    cd dify/docker路径下:

    启动服务 docker compose up -d

    查看容器运行状况 docker compose ps

    关闭服务 docker compose down

    更新dify

    访问 Dify

    你可以先前往管理员初始化页面设置设置管理员账户:

    Dify 主页面:

    自定义配置

    编辑 .env 文件中的环境变量值。然后重新启动 Dify:

    完整的环境变量集合可以在 docker/.env.example 中找到。

     

    Swarm to OpenAI-Agents

    OpenAI Agents SDK 是一个轻量级但功能强大的框架,用于构建多智能体工作流。

    OpenAI Agents SDK 是我们之前针对智能体的实验项目 Swarm 的生产级升级版。

    核心概念:

    关于

    为什么用Agents SDK

    该 SDK 具有两个主要设计原则:

    SDK 的主要功能

    安装

    pip install openai-agents

    Hello world示例

    export OPENAI_API_KEY=sk-...

    如果运行此程序,请确保设置 OPENAI_API_KEY 环境变量,参考

    快速开始

     

    Note

    Agent(name='Math Tutor', instructions='You provide help with math problems. Explain your reasoning at each step and include examples', handoff_description=None, handoffs=[], model=None, model_settings=ModelSettings(temperature=None, top_p=None, frequency_penalty=None, presence_penalty=None, tool_choice=None, parallel_tool_calls=None, truncation=None, max_tokens=None, reasoning=None, metadata=None, store=None), tools=[], mcp_servers=[], mcp_config={}, input_guardrails=[], output_guardrails=[], output_type=None, hooks=None, tool_use_behavior='run_llm_again', reset_tool_choice=True)

    追踪

    要查看智能体运行期间发生的情况,请在 OpenAI 控制面板中导航到追踪查看器,以查看智能体运行的追踪记录。

    下一步

    了解如何构建更复杂的智能体流程:

    文档

    1. 智能体

    智能体是你应用中的核心构件。智能体是一个大型语言模型(LLM),经过配置,包含指令和工具。

    1.1 泛型

    Agent 类,使用了泛型。下面是对这段代码的逐部分解读:

    class Agent(Generic[TContext]):

    泛型的作用

    通过使用 TContextAgent 类可以与不同类型的上下文(context)配合使用。上下文的类型是泛型的,可以根据需要进行定义。

    示例:

    上下文被用作依赖注入工具。这是指上下文可以用于传递所需的依赖项(如配置、服务等)给智能体。

    Agents are generic on their context type. Context is a dependency-injection tool: it's an object you create and pass to Runner.run(), that is passed to every agent, tool, handoff etc, and it serves as a grab bag of dependencies and state for the agent run. You can provide any Python object as the context.

    1.2 输出类型

    默认情况下,智能体生成纯文本(即字符串)输出。如果你希望智能体生成特定类型的输出,可以使用 output_type 参数。常见的选择是使用 Pydantic 对象。

    我们支持任何可以被 Pydantic 的 TypeAdapter 包装的类型,如数据类、列表、TypedDict 等。

    Note

    当你传递 output_type 时,这告诉模型使用 结构化输出 而不是常规的纯文本响应。

    1.3 交接

    交接(Handoffs)是智能体可以委托的子智能体。你可以提供一个交接列表,智能体可以在相关时选择委托给它们。这是一种强大的模式,可以协调模块化的、专门化的智能体,使其在单一任务上表现出色。

    1.4 动态指令

    在大多数情况下,你可以在创建智能体时提供指令。不过,你也可以通过函数提供动态指令。该函数将接收智能体和上下文,并必须返回提示。使用常规函数和异步函数都被允许。

    1.5 生命周期事件(钩子)

    有时,你可能想观察智能体的生命周期。例如,你可能希望在某些事件发生时记录事件或预取数据。你可以通过 hooks 属性挂钩到智能体生命周期。通过子类化 AgentHooks 类,并重写你感兴趣的方法。

    1.6 护栏

    护栏(Guardrails)允许你在智能体运行的同时,对用户输入进行检查和验证。例如,你可以筛选用户的输入以判断其相关性。

    1.7 复制智能体

    通过在智能体上使用 clone() 方法,你可以复制一个智能体,并可以选择更改任何属性。

    1.8 强制使用工具

    提供工具列表并不总意味着 LLM 会使用某个工具。你可以通过设置 ModelSettings.tool_choice 来强制使用工具。有效值包括:

    Note

    为了防止无限循环,框架在每次工具调用后会自动将 tool_choice 重置为 "auto"。此行为可以通过 agent.reset_tool_choice 进行配置。无限循环的原因是工具结果会被发送给 LLM,随后 LLM 可能会生成另一个工具调用,从而导致无限循环。

    如果你希望智能体在工具调用后完全停止(而不是继续使用自动模式),可以设置 Agent.tool_use_behavior="stop_on_first_tool",这将直接使用工具输出作为最终响应,而不进行进一步的 LLM 处理。

     

    2. 运行智能体

    你可以通过 Runner 类运行智能体,有三种选项:

    1. Runner.run():异步运行并返回 RunResult

    2. Runner.run_sync():同步方法,实质上运行 run()

    3. Runner.run_streamed():异步运行并返回 RunResultStreaming。它以流式模式调用 LLM,并在接收事件时将其流式传输给你。

    2.1 智能体循环

    当你在 Runner 中使用 run 方法时,你需要传入一个起始智能体和输入。输入可以是一个字符串(视为用户消息),也可以是一个输入项的列表。

    Runner 会运行一个循环:

    1. 调用当前智能体的 LLM,使用当前输入。

    2. LLM 生成输出。

      1. 如果 LLM 返回 final_output,循环结束,我们返回结果。

      2. 如果 LLM 进行移交(handoff),我们更新当前智能体和输入,并重新运行循环。

      3. 如果 LLM 产生工具调用,我们执行这些工具调用,附加结果,并重新运行循环。

    3. 如果超过传入的 max_turns,则引发 MaxTurnsExceeded 异常。

    Note

    判断 LLM 输出是否被视为final_output的规则是:它生成了符合所需类型的文本输出,且没有工具调用。

    2.2 流式
    2.3 运行配置

    run_config 参数让你可以配置一些全局设置以供智能体运行使用:

    2.4 对话/聊天线程

    调用任何 run 方法可能会导致一个或多个智能体运行(因此会有一个或多个 LLM 调用),但这代表了聊天对话中的一个逻辑轮次。例如:

    在智能体运行结束时,你可以选择向用户展示什么内容。例如,你可以展示智能体生成的每个新项,或者仅展示最终输出。无论哪种情况,用户可能会问后续问题,此时你可以再次调用 run 方法。

    你可以使用 RunResultBase.to_input_list() 方法获取下一个轮次的输入。

    2.5 异常

    SDK 在某些情况下会引发异常。完整列表见 agents.exceptions。以下是概述:

    3. 结果

    当你调用 Runner.run 方法时,你会获得以下其中之一:

    这两者都继承自 RunResultBase,其中包含大多数有用的信息。

    3.1 最终输出

    final_output 属性包含最后运行的智能体的最终输出。为以下两种情况之一:

    Note

    final_output 的类型为 Any。我们无法静态类型化它,因为在移交时,最后的智能体可能是任何一个,因此我们无法静态确定可能的输出类型集合。

    3.2 下一轮次的输入

    你可以使用 result.to_input_list() 方法将结果转换为输入列表,该列表将你提供的原始输入与智能体运行期间生成的项连接起来。这使得将一个智能体运行的输出传递到另一个运行中变得方便,或者在循环中运行并每次附加新的用户输入。

    3.3 最后智能体

    last_agent 属性包含最后运行的智能体。根据你的应用情况,这通常在用户下次输入时很有用。例如,如果你有一个分诊智能体,它会移交给特定语言的智能体,你可以存储最后的智能体,并在用户下次消息时重用它。

    3.4 新项

    new_items 属性包含在运行期间生成的新项。这些项是 RunItems,每个项封装了 LLM 生成的原始项。

    1. MessageOutputItem:表示 LLM 生成的消息。原始项是具体的消息内容。

    2. HandoffCallItem:表示 LLM 调用了移交工具。原始项是发起的工具调用信息。

    3. HandoffOutputItem:表示发生了移交,原始项是移交工具的响应。此项也可以访问交接的源/目标智能体的信息。

    4. ToolCallItem:表示 LLM 调用了一个工具,记录了调用的动作。

    5. ToolCallOutputItem:表示工具被调用后的响应,包含工具的输出。

    6. ReasoningItem:表示 LLM 生成的推理结果,记录了其推理过程。

    3.5 其他信息
    1. Guardrail 结果

      • input_guardrail_resultsoutput_guardrail_results 包含 guardrails 的结果,可能包含有用的信息,开发者可以选择记录或存储。

    2. 原始响应

      • raw_responses 包含 LLM 生成的具体输出ModelResponses

    3. 原始输入

      • input 属性包含你提供的原始输入,通常不需要,但可以在特定情况下使用。

    4. 流式

    流式处理允许你在智能体运行过程中订阅更新。这对于向最终用户显示进度更新和部分响应非常有用。

    4.1 原始响应事件

    RawResponsesStreamEvent 是直接从 LLM 传递的原始事件,采用 OpenAI Responses API 格式。每个事件都有一个类型(如 response.createdresponse.output_text.delta 等)和数据。

    这些事件在你希望实时向用户传输生成的响应消息时非常有用。

    4.2 运行项事件和智能体事件

    RunItemStreamEvents 是更高级的事件,通知你某个项目已完全生成。这使你能够在“消息生成”、“工具运行”等级别推送进度更新,而不是逐个 Token。同样,AgentUpdatedStreamEvent 在当前智能体发生变化时提供更新(例如,因交接而变化)。

    5. 工具

    工具使智能体能够执行各种操作,例如获取数据、运行代码、调用外部 API,甚至使用计算机。在 Agent SDK 中有三类工具:

    1. 托管工具:这些工具在 LLM 服务器上与 AI 模型一起运行。OpenAI 提供检索、网页搜索和计算机使用作为托管工具。

    2. 函数调用:允许你将任何 Python 函数用作工具。

    3. 智能体作为工具:这允许你将智能体作为工具使用,使智能体能够调用其他智能体,而无需进行交接。

    5.1 托管工具

    OpenAI 在使用 OpenAIResponsesModel 时提供了一些内置工具:

    5.2 函数工具

    你可以将任何 Python 函数用作工具。Agents SDK 会自动设置工具:

    我们使用 Python 的 inspect 模块提取函数签名,并使用 griffe 解析文档字符串,使用 pydantic 进行 schema 创建。

    5.3 智能体作为工具

    在某些工作流中,您可能希望有一个中央智能体来协调一组专业智能体,而不是进行控制交接。您可以通过将智能体建模为工具来实现这一点。

    5.4 在函数工具中处理错误

    当您通过 @function_tool 创建一个函数工具时,可以传递 failure_error_function。这是一个在工具调用崩溃时向 LLM 提供错误响应的函数。

    如果您手动创建 FunctionTool 对象,则必须在 on_invoke_tool 函数内处理错误。

    6. 模型上下文协议 (MCP)

    模型上下文协议(MCP)是一种为 LLM 提供工具和上下文的方法。根据 MCP 文档:

    Note

    MCP 是一个开放协议,标准化了应用程序向 LLM 提供上下文的方式。可以将 MCP 类比于 AI 应用的 USB-C 接口。正如 USB-C 为设备连接各种外设和配件提供了标准化的方式,MCP 也为 AI 模型连接不同的数据源和工具提供了标准化的方式。

    Agents SDK 支持 MCP。这使您能够使用广泛的 MCP 服务器为您的智能体提供工具。

    6.1 MCP 服务器

    目前,MCP 规范定义了两种类型的服务器,基于它们使用的传输机制:

    您可以使用 MCPServerStdioMCPServerSse 类来连接这些服务器。

    以下是一个简单的示例,演示如何使用官方 MCP 文件系统服务器:

    6.2 使用 MCP 服务器

    MCP 服务器可以添加到智能体中。每次运行智能体时,Agents SDK 将调用 MCP 服务器上的 list_tools()。这使得 LLM 了解 MCP 服务器的工具。当 LLM 调用 MCP 服务器上的工具时,SDK 会在该服务器上调用 call_tool()

    6.3 缓存

    每次智能体运行时,它都会在 MCP 服务器上调用 list_tools()。这可能会导致延迟,尤其是当服务器是远程服务器时。为了自动缓存工具列表,可以将 cache_tools_list=True 传递给 MCPServerStdioMCPServerSse。您只有在确定工具列表不会更改时才应这样做。

    如果您想使缓存失效,可以在服务器上调用 invalidate_tools_cache()

    可在 example/mcp 查看完整的工作示例。

    6.4 跟踪

    跟踪功能会自动捕获 MCP 操作,包括:

    7. 交接

    交接允许一个智能体将任务委托给另一个智能体。这在不同智能体专注于不同领域的场景中尤其有用。例如,一个客户支持的app可能有专门处理订单状态、退款、FAQ等任务的智能体。

    交接被表示为 LLM 的工具。因此,如果有一个交接给名为“Refund(退款) Agent”的智能体,则该工具将被称为 transfer_to_refund_agent

    7.1 创建交接

    所有智能体都有一个 handoffs 参数,该参数可以直接接受一个智能体,或接受一个自定义的 Handoff 对象。

    您可以使用 Agents SDK 提供的 handoff() 函数创建任务移交。这个函数允许您指定要移交的智能体,并提供可选的覆盖和输入过滤器。

    7.2 通过 handoff() 函数自定义交接

    handoff() 函数允许您自定义以下内容:

    7.3 交接输入

    在某些情况下,您希望 LLM 在调用移交时提供一些数据。例如,想象一下移交给“向上反映(Escalation)智能体”。您可能希望提供一个原因,以便进行记录。

    通过在 handoff() 函数中使用适当的参数,您可以指定所需的输入数据,从而确保在移交时传递必要的信息。

    7.4 输入过滤器

    当发生移交时,新的智能体会接管对话,并能够看到整个之前的对话历史。如果您想更改这一点,可以设置一个输入过滤器。

    输入过滤器是一个接收现有输入的函数,通过 HandoffInputData 传递,并必须返回一个新的 HandoffInputData

    一些常见的模式(例如从历史记录中移除所有工具调用)已经在 agents.extensions.handoff_filters 中为您实现。这样,您可以轻松地应用这些标准过滤器,或根据需要自定义自己的过滤器。

    7.5 推荐提示词

    为了确保 LLM 正确理解任务移交,我们建议在您的智能体中包含有关移交的信息。我们提供了一个建议的前缀,您可以在 agents.extensions.handoff_prompt.RECOMMENDED_PROMPT_PREFIX 中找到,或者可以调用 agents.extensions.handoff_prompt.prompt_with_handoff_instructions 来自动将推荐数据添加到您的提示中。

    通过这些方法,您可以增强智能体对移交的理解,确保更顺畅的任务转移。

    8. 追踪

    Agents SDK 包含内置追踪功能,可以全面记录智能体运行期间的事件,包括:LLM 生成、工具调用、任务移交、保护措施,以及发生的自定义事件。使用 Traces dashboard,您可以在开发和生产过程中调试、可视化和监控您的工作流程。

    8.1 追踪和跨度

    追踪代表一个“工作流”的单一端到端操作,由多个 跨度 组成。追踪具有以下属性:

    跨度代表具有开始和结束时间的操作。跨度具有以下属性:

    8.2 默认追踪

    默认情况下,SDK 会追踪以下内容:

    默认情况下,追踪命名为“Agent trace”。如果您使用 trace,可以设置此名称,或者可以通过 RunConfig 配置名称及其他属性。

    此外,您可以设置自定义追踪处理器,将追踪推送到其他目标(作为替代或次要目标)。

    8.3 更高层次的追踪

    有时,您可能希望将多个 run() 调用作为单个追踪的一部分。您可以通过将整个代码块封装在 trace() 中来实现这一点。这样,所有包含的操作都将被记录为同一个追踪,提高了整体监控的连贯性。

    8.4 创建追踪

    您可以使用 trace() 函数来创建追踪。追踪需要启动和结束,您有两种选择:

    1. 推荐方式: 将 trace 用作上下文管理器,例如 with trace(...) as my_trace。这将自动在正确的时间启动和结束追踪。

    2. 手动方式: 您也可以手动调用 trace.start()trace.finish()

    当前追踪通过 Python 的 contextvar 进行跟踪,这意味着它会自动处理并发。如果您手动启动/结束追踪,您需要在 start()/finish() 中传递 mark_as_currentreset_current 以更新当前追踪。

    8.5 创建跨度

    您可以使用各种 *_span() 方法来创建跨度。通常情况下,您不需要手动创建跨度。

    8.6 敏感数据

    某些跨度可能会捕获潜在的敏感数据。

    8.7 自定义追踪处理器

    追踪的高层架构如下:

    1. 初始化时,我们创建一个全局 TraceProvider,负责创建追踪。

    2. 我们使用 BatchTraceProcessor 配置 TraceProvider,该处理器将追踪/跨度批量发送到 BackendSpanExporter,后者将这些跨度和追踪批量导出到 OpenAI 后端。

    要自定义此默认设置,以将追踪发送到替代或附加后端或修改导出器行为,您有两个选项:

    8.8 外部追踪处理器列表

    比如 Weights & Biases

    9. 上下文管理

    “上下文”是一个多义词。您可能关心的主要有两类上下文:

    1. 本地上下文:这是您的代码在工具函数运行时、回调(如 on_handoff)、生命周期钩子等情况下可能需要的数据和依赖项。

    2. LLM 上下文:这是 LLM 在生成响应时所看到的数据。

    这两类上下文在不同的场景中发挥着关键作用。

    9.1 本地上下文

    本地上下文通过 RunContextWrapper 类及其中的 context 属性表示。其工作原理如下:

    1. 创建任意 Python 对象。常见的模式是使用数据类(dataclass)或 Pydantic 对象。

    2. 将该对象传递给各种运行方法(例如 Runner.run(..., **context=whatever**))。

    3. 所有的工具调用、生命周期钩子等将接收一个包装对象 RunContextWrapper[T],其中 T 代表您的上下文对象类型,可以通过 wrapper.context 访问。

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

    您可以利用上下文进行以下操作:

    Note

    上下文对象不会被发送到 LLM。它纯粹是一个本地对象,您可以从中读取、写入并调用其方法。

    9.2智能体/LLM 上下文

    当调用 LLM 时,它只能看到对话历史中的数据。这意味着如果要向 LLM 提供新数据,必须以可以在历史中访问的方式进行。以下是几种方法:

    1. 添加到智能体指令:这称为“系统提示”或“开发者消息”。系统提示可以是静态字符串,也可以是接收上下文并输出字符串的动态函数。这对于始终有用的信息(例如用户名或当前日期)是常见的策略。

    2. 在调用 Runner.run 函数时添加输入

    3. 通过工具函数暴露:适用于按需上下文,LLM 根据需要调用工具以获取数据。

    4. 使用检索或网络搜索:这些特殊工具能够从文件或数据库(检索)或从网络(网络搜索)中获取相关数据。比如RAG。

    10. 护栏

    护栏与智能体同时运行,可以对用户输入进行检查和验证。

    例如,假设你有一个使用非常智能(因此较慢/昂贵)模型来处理客户请求的智能体。你不希望恶意用户请求模型帮助他们做数学作业。因此,你可以使用一个快速/便宜的模型来运行护栏。如果护栏检测到恶意使用,它可以立即引发错误,阻止昂贵模型的运行,从而节省时间和金钱。

    保护机制有两种类型:

    1. 输入保护机制:作用于用户初始输入

    2. 输出保护机制:作用于智能体最终输出

    10.1 输入护栏

    输入护栏分为三步:

    1. 首先,护栏接收传递给智能体的相同输入。

    2. 接下来,护栏函数运行,得到一个 GuardrailFunctionOutput,并将其封装在 InputGuardrailResult 中。

    3. 最后,我们检查 .tripwire_triggered 是否为真。如果为真,则会引发 InputGuardrailTripwireTriggered 异常,以便您可以适当地响应用户或处理该异常。

    Tip

    输入护栏旨在处理用户输入,因此智能体的护栏仅在其为第一个智能体时运行。你可能会问,为什么输入护栏属性在智能体上,而不是传递给 Runner.run

    这是因为护栏通常与实际智能体相关——不同的智能体会运行不同的护栏,因此将代码放在一起有助于提高可读性。

    输出护栏同理。

    10.2 输出护栏

    输出护栏也分为三步:

    1. 首先,护栏接收传递给智能体的相同输入。

    2. 接下来,护栏函数运行,生成一个 GuardrailFunctionOutput,并将其封装在 OutputGuardrailResult 中。

    3. 最后,我们检查 .tripwire_triggered 是否为真。如果为真,则会引发 OutputGuardrailTripwireTriggered 异常,以便您可以适当地响应用户或处理该异常。

    10.3 触发器

    tripwire | BrE ˈtrɪpˌwʌɪə, AmE ˈtrɪpˌwaɪ(ə)r | noun (working a trap) 绊脚线; (setting off an explosion) 触发线; (working an alarm) 拉发线; (in computing context) 触发器

    如果输入或输出未通过护栏,护栏可以通过触发器发出信号。一旦我们检测到,就会立即引发 {Input,Output}GuardrailTripwireTriggered 异常,并停止智能体的执行。

    Tip

    输入护栏的示例可参考 - 快速开始 -,输出护栏是类似的。

    11. 协调多个智能体

    协调指的是应用中智能体的流动。哪些智能体运行,顺序如何,以及它们如何决定接下来发生什么?协调智能体主要有两种方式:

    1. 允许LLM做决定:利用LLM的智能来规划、推理和决定采取哪些步骤。

    2. 通过代码协调:通过代码确定智能体的流动。

    你可以混合使用这些模式。每种方式都有其优缺点,下面进行描述。

    11.1 通过LLM协调

    智能体是一个配备了指令、工具和移交机制的LLM。这意味着在面对开放性任务时,LLM可以自主规划如何处理任务,利用工具采取行动和获取数据,并通过移交将任务委派给子智能体。例如,一个研究智能体可以配备以下工具:

    这种模式在开放性任务里非常有效,尤其是在希望依赖LLM智能的情况下。这里最重要的策略包括:

    1. 投资于良好的提示:清楚说明哪些工具可用、如何使用它们以及必须遵循的参数。

    2. 监控应用并进行迭代:查看问题出现的地方,并对提示进行迭代。

    3. 允许智能体自我反思和改进:例如,循环运行,让它自我批评;或者提供错误信息,让它进行改进。

    4. 拥有擅长单一任务的专业智能体,而不是期待通用智能体在任何任务上都表现良好。

    5. 投资评估:这让你可以训练智能体,帮助它们在任务中不断提升。

    11.2 通过代码协调

    虽然通过LLM协调非常强大,但通过代码协调使任务在速度、成本和效果方面更加确定和可预测。常见模式包括:

    1. 使用结构化输出:生成可以通过代码检查的格式良好的数据。例如,可以要求智能体将任务分类为几个类别,然后根据类别选择下一个智能体。

      Tip

      JSON 是世界上应用程序交换数据最广泛使用的格式之一。

      结构化输出 是一项功能,它能确保模型始终生成符合您提供的 JSON Schema 的响应,因此您无需担心模型遗漏必要键值、或生成无效的枚举值。

      结构化输出的优势包括:

      1. 可靠的类型安全 无需验证或重试格式错误的响应

      2. 显式拒绝机制 基于安全策略的模型拒绝行为可通过编程方式检测

      3. 更简洁的提示设计 无需使用强约束性提示词即可实现一致的格式输出

       

    2. 链式多个智能体:将一个智能体的输出转化为下一个智能体的输入。可以将写博客文章的任务分解为一系列步骤——进行研究、写提纲、撰写博客文章、进行批评,然后改进。

    3. 在循环中运行执行任务的智能体:与评估并提供反馈的智能体一起,直到评估者表示输出符合特定标准。

    4. 并行运行多个智能体:例如,通过Python原语如asyncio.gather。当有多个相互独立的任务时,这样做可以提高速度。

    我们在examples/agent_patterns中有许多示例

    12. 模型

    Agents SDK 原生支持两种 OpenAI 模型调用方式:

    1. 推荐方案 OpenAIResponsesModel - 通过全新的 Responses API 调用 OpenAI 接口

    2. 传统方案 OpenAIChatCompletionsModel - 使用标准的 Chat Completions API 调用 OpenAI 接口

    12.1 混合和匹配模型

    在单个工作流中,您可能希望为每个智能体使用不同的模型。例如,您可以使用一个较小、较快的模型进行分诊,同时使用一个较大、更强大的模型处理复杂任务。在配置智能体时,您可以通过以下方式选择特定模型:

    Note

    虽然我们的 SDK 支持 OpenAIResponsesModel 和 OpenAIChatCompletionsModel 两种形状,但我们建议每个工作流程使用单一模型形状,因为这两种形状支持不同的功能和工具。如果您的工作流程需要混合和匹配模型形状,请确保您使用的所有功能在两者中均可用。

    当您希望进一步配置智能体使用的模型时,可以传递 ModelSettings,它提供了可选的模型配置参数,例如温度。

    12.2 使用其他 LLM 提供商

    您可以通过三种方式使用其他 LLM 提供商(参考示例:examples/model_providers):

    1. set_default_openai_client 在您希望全局使用 AsyncOpenAI 实例作为 LLM 客户端的情况下非常有用。这适用于 LLM 提供商具有与 OpenAI 兼容的 API 端点的情况,您可以设置 base_urlapi_key。请参见 examples/model_providers/custom_example_global.py 中的可配置示例。

    2. ModelProvider 位于 Runner.run 级别。这样您可以指定“在此运行中为所有智能体使用自定义模型提供商”。请参见 examples/model_providers/custom_example_provider.py 中的可配置示例。

    3. Agent.model 允许您在特定的智能体实例上指定模型。这使您能够为不同的智能体混合和匹配不同的提供商。请参见 examples/model_providers/custom_example_agent.py 中的可配置示例。

    在您没有来自 platform.openai.com 的 API 密钥的情况下,我们建议通过 set_tracing_disabled() 禁用追踪,或设置不同的追踪处理器。

    Note

    在这些示例中,我们使用 Chat Completions API/模型,因为大多数 LLM 提供商尚不支持 Responses API。如果您的 LLM 提供商支持该 API,我们建议使用 Responses。

    12.3 使用其他 LLM 提供商时的常见问题
    12.3.1 追踪客户端错误 401

    如果您遇到与追踪相关的错误,这是因为追踪信息被上传到 OpenAI 服务器,而您没有 OpenAI API 密钥。您有三种解决方案:

    1. 完全禁用追踪:set_tracing_disabled(True)

    2. 为追踪设置 OpenAI 密钥:set_tracing_export_api_key(...)。此 API 密钥仅用于上传追踪信息,必须来自 platform.openai.com。

    3. 使用非 OpenAI 的追踪处理器。请参见追踪文档。

    12.3.2 Responses API 支持

    SDK 默认使用 Responses API,但大多数其他 LLM 提供商尚不支持它。您可能会看到 404 或类似的问题。要解决此问题,您有两种选择:

    1. 调用 set_default_openai_api("chat_completions")。如果您通过环境变量设置了 OPENAI_API_KEYOPENAI_BASE_URL,此方法有效。

    2. 使用 OpenAIChatCompletionsModel这里有示例。

    12.3.3 结构化输出支持

    一些模型提供商不支持结构化输出。这有时会导致类似以下的错误:

    这是某些模型提供商的一个局限性——它们支持 JSON 输出,但不允许您指定用于输出的 json_schema。我们正在努力解决此问题,但建议依赖那些确实支持 JSON schema 输出的提供商,因为否则您的应用程序可能会因格式错误的 JSON 而频繁崩溃。

    12.4 OpenRouter配置

    EXAMPLE_API_KEYhttps://openrouter.ai/settings/keys 创建。

    EXAMPLE_MODEL_NAME 从各个模型的API里查看,如 https://openrouter.ai/deepseek/deepseek-r1:free/api

    OPENAI_API_KEYhttps://platform.openai.com/api-keys 创建,以支持追踪器

    12.5 通过 LiteLLM 使用任何模型

    pip install "openai-agents[litellm]"

    LiteLLM 集成目前处于测试阶段。如果发现任何问题,请通过 GitHub 提交问题,我们会尽快修复。

    我们添加了 LiteLLM 集成,以便您在 Agents SDK 中通过单一接口使用任何 AI 模型。

    13. 配置 SDK

    1. API 密钥和客户端

    默认情况下,SDK 在导入时会查找 OPENAI_API_KEY 环境变量以进行 LLM 请求和跟踪。如果您无法在应用启动之前设置该环境变量,可以使用 set_default_openai_key() 函数来设置密钥。

    2. 追踪器

    跟踪默认是启用的。它默认使用上述部分中的 OpenAI API 密钥(即环境变量或您设置的默认密钥)。您可以通过使用 set_tracing_export_api_key 函数来专门设置用于跟踪的 API 密钥。您也可以通过使用 set_tracing_disabled() 函数完全禁用跟踪。

    3. 调试日志 SDK 有两个 Python 日志记录器,但没有设置任何处理器。默认情况下,这意味着警告和错误会发送到stdout,而其他日志则被抑制。

    要启用详细日志记录,请使用 enable_verbose_stdout_logging() 函数。

    您也可以通过添加处理器、过滤器、格式化器等来自定义日志。您可以在 Python 日志指南中了解更多信息。

    4. 日志中的敏感数据

    某些日志可能包含敏感数据(例如用户数据)。如果您希望禁用这些数据的记录,请设置以下环境变量。

    要禁用 LLM 输入和输出的日志记录:

    要禁用工具输入和输出的日志记录:

    14. 可视化智能体

    智能体可视化允许您使用 Graphviz 生成智能体及其关系的结构化图形表示。这对于理解智能体、工具和交接在应用程序中的交互非常有用。

    1. 安装

    安装可选的 viz 依赖组:pip install "openai-agents[viz]"

    2. 生成图形

    您可以使用 draw_graph 函数生成智能体可视图。此函数创建一个有向图,其中:

    15. 语音智能体

    1. 安装

    从 SDK 中安装可选的语音依赖项:pip install 'openai-agents[voice]'