OpenAI Agents SDK 深度解析(三):执行层——Agent 的“幕后指挥部”

news2026/5/1 18:52:17
开发一个智能体就像训练一名士兵。你给他下达一个任务他最终会交回一个结果。但是如果这名士兵在执行任务的途中开了几枪、呼叫了几次炮火支援、又换了几次频道联络后方基地——你却完全不知道。你只知道“任务完成”或者“任务失败”。这样的士兵你敢重用吗在真实的应用场景中我们需要的 Agent 不是只会说“是”或“不是”的黑箱子而是每一步都可以被观察、被记录、被审计的透明系统。用户问“北京天气怎么样”Agent 到底是靠猜的还是真的去查了天气 API如果查了传的是什么参数API 返回了什么原始数据模型在拿到数据之后又做了哪些推理才给出最终答案这些问题仅靠 final_output 永远无法回答。这正是 OpenAI Agents SDK 设计“执行层”的初衷——为每一次 Agent 的执行安装一个黑匣子记录仪同时在驾驶舱里装上一块实时直播屏幕。在这篇文章中我会用最通俗的语言、最完整的代码带你彻底吃透执行层的四个核心概念输出项、事件流、历史会话以及贯穿它们的一次执行的生命周期——Run。一、执行层到底是什么在 OpenAI Agents SDK 中所有 Agent 的执行都被包装成一个叫做Run的对象。一次 Run就是一个独立的任务执行生命周期。当你写下这行代码时await Runner.run(agent, 帮我查一下天气)SDK 会在背后做以下几件事创建一条空的消息记录准备接收用户输入。调用大模型让模型决定要不要使用工具。如果模型决定用工具SDK 会执行对应的 Python 函数拿到结果再送回给模型。模型基于工具结果生成最终的语言回复。最后把所有中间产物打包成一个 Run 对象返回给你。执行层就是负责管理 Run 内部所有这些状态的组件。具体来说执行层管理了四个最重要的状态第一历史消息。也就是整个对话过程中用户说了什么、模型回复了什么、工具返回了什么。这些消息按时间顺序排列构成了对话的完整时间线。第二工具调用状态。Agent 是否正在等待某个工具执行完成工具执行是成功了还是失败了这些状态信息在执行层被完整记录。第三Agent 路由轨迹。在多 Agent 系统中任务可能会从一个 Agent 转交给另一个 Agent比如从“通用助手”转给“天气专家”。执行层会记录每一次这样的交接包括从谁转给谁以及交接时的上下文。第四流式状态。如果用户要求实时输出那执行层会维护一个流式缓冲区记录已经输出了哪些字符还要输出哪些字符。理解了执行层是什么我们就可以分别深入它的四个核心产出物输出项、事件流和历史会话。二、输出项Agent 的每一处“脚印”输出项是执行层最基础、最完整的数据产物。如果说 Run 是一场完整的演出那么输出项就是这场演出的分镜头剧本——每一幕、每一句台词、每一个动作都被写成了条目。1. 什么是输出项输出项英文叫Output Items。它的定义非常简单在一次 Run 的执行过程中所有“已经发生的事实”被抽象成的结构化对象。我们用一个具体的例子来理解。假设你问 Agent“北京今天的天气怎么样”在没有输出项的黑盒模式下你只能看到最终的回答“北京今天晴天25度。”而在有输出项的白盒模式下SDK 会生成一条又一条的记录就像这样第一条记录模型打算调用一个名为 get_weather 的工具参数是 {city: 北京}。这条记录的类型叫做 ToolCallItem。第二条记录工具 get_weather 执行结束返回值是字符串 北京晴天25度。这条记录的类型叫做 ToolCallOutputItem。第三条记录模型基于工具返回的数据生成了最终的文本回答。这条记录的类型叫做 MessageOutputItem。你看仅仅一个简单的天气查询背后就有至少三条输出项。如果 Agent 做了更复杂的事比如连续调用三个工具、在两个 Agent 之间来回交接输出项的数量会成倍增加。官方文档中有一句话非常值得记住输出项不是模型输出本身不是 Agent 的决策逻辑也不是 Tool 的执行逻辑——它是 Run 对“执行过程”的结构化快照。也就是说它记录的是“发生了什么事实”。对于调试和审计来说“发生了什么”往往比“为什么发生”更关键。2. 五类最核心的输出项在 Agents SDK 中虽然输出项的种类很多但日常开发中最常用的只有五类。我们用文字逐一解释清楚不列表格。第一类MessageOutputItem它代表“模型生成了一段对话消息”这个事实。注意它不是消息本身的内容而是对“生成消息”这个事件的记录。当你看到一条 MessageOutputItem就意味着 Agent 已经产生了一段可以直接展示给用户的文本。通常这就是最终输出的一部分。第二类ToolCallItem它代表“Agent 决定调用某个工具”这个事实。里面记录了工具的名字以及调用时传入的参数JSON 格式。你可以通过 ToolCallItem 精确地知道 Agent 在什么时候、基于什么理由、调用了什么工具。第三类ToolCallOutputItem它代表“某个工具已经执行完成并返回了结果”这个事实。里面包含了工具的执行结果通常是一个字符串或者 JSON 对象。将 ToolCallItem 和 ToolCallOutputItem 对照着看你就能完整还原一次工具调用的全过程传入了什么参数得到了什么结果。第四类HandoffOutputItem它代表“当前 Agent 把控制权转交给了另一个 Agent”这个事实。在多 Agent 架构中非常有用。比如你的主 Agent 负责意图识别发现用户想问天气就立即将任务转交给专门的天气 Agent。这个交接动作就会被记录成一条 HandoffOutputItem包括源 Agent 的名字和目标 Agent 的名字。第五类ReasoningItem它代表“模型进行了一次内部推理”这个事实。有些高级模型比如 OpenAI o1 系列会在输出最终答案之前进行一段“思维链”式的内部推导。这段推导不会显示给最终用户但对开发者调试 Agent 的行为非常宝贵。ReasoningItem 就是用来捕获这段推导过程的。3. 一个容易混淆的问题ResponseXXX 和 XXXItem 的区别很多刚接触 SDK 的开发者会被 ResponseOutputMessage、ResponseReasoningItem、MessageOutputItem、ReasoningItem 这样的命名搞得头晕。这里只需要记住一条原则所有以 Response 开头的类型都来自大模型厂商比如 OpenAI的原始 API 协议。所有以 Item 结尾的类型才是 Agents SDK 对外统一暴露的执行层接口。为什么 SDK 要多做一层包装因为不同大模型厂商的响应格式不一样。OpenAI 的格式和 Anthropic 的格式、和国内通义千问的格式都有差异。SDK 把这些差异全部屏蔽掉对外统一暴露 MessageOutputItem、ToolCallItem 等接口。这样一来你写的代码可以无缝切换底层模型提供商而不用修改任何输出项的处理逻辑。所以在你的业务代码中请优先使用 XXXItem 这一类执行层类型。只有当你需要访问某些非常底层的、厂家特定的字段时才通过 .raw_item 属性去拿到原始的 ResponseXXX 对象。4. 完整的代码示例如何获取并打印输出项下面是一段完整可运行的代码。它会创建一个带天气查询工具的 Agent执行一次询问然后逐个打印出这次 Run 产生的所有输出项。代码中的每一处关键逻辑都有详细的注释。import asyncio from openai import AsyncOpenAI from agents import ( Agent, OpenAIChatCompletionsModel, Runner, function_tool, set_tracing_disabled ) # 配置你的 API 地址和密钥 # 这里以阿里云百炼平台的兼容接口为例你可以换成任何兼容 OpenAI 格式的服务 BASE_URL https://dashscope.aliyuncs.com/compatible-mode/v1 API_KEY sk-your-api-key-here # 请替换成你自己的真实 API Key MODEL_NAME qwen-plus # 创建一个异步的 HTTP 客户端 client AsyncOpenAI(base_urlBASE_URL, api_keyAPI_KEY) # 关闭 SDK 自带的追踪功能仅为了简化输出生产环境建议保留 set_tracing_disabled(disabledTrue) # 定义一个工具函数获取天气 # function_tool 装饰器会把普通 Python 函数自动转换成 Agent 可调用的工具 function_tool def get_weather(city: str) - str: 根据城市名返回天气信息这里为了演示返回静态数据 # 在实际项目中你可以在这里调用真实的天气 API return f天气信息: {city} 是晴天温度 28 度湿度 50%。 async def main(): # 创建一个 Agent # name: Agent 的名字用于调试和交接 # instructions: 系统指令告诉 Agent 应该遵循什么行为准则 # model: 指定使用的大模型这里用 OpenAIChatCompletionsModel 包装第三方接口 # tools: 绑定工具列表 agent Agent( name天气助手, instructions( 你是一个专业的天气助手。每当用户询问某个城市的天气时 你必须调用 get_weather 工具来获取真实数据。 绝对禁止自己编造天气信息。 ), modelOpenAIChatCompletionsModel(modelMODEL_NAME, openai_clientclient), tools[get_weather], ) # 执行一次 Run # 注意这里使用的是 Runner.run 方法它会等待整个 Run 执行完毕 # 然后将所有输出项一次性整理到 result.new_items 中返回。 # 如果你需要实时获取输出项请使用后面的 run_streamed 版本。 result await Runner.run(agent, 武汉今天的天气怎么样) # 遍历并打印所有输出项 print( * 50) print(开始输出 Agent 的执行足迹输出项) print( * 50) for idx, item in enumerate(result.new_items, start1): print(f\n第 {idx} 个输出项:) print(f 类型名称: {type(item).__name__}) # 根据不同的输出项类型打印更有意义的信息 # 注意.raw_item 是原始厂商对象这里我们用最简单的方式打印 print(f 原始内容: {item.raw_item}) print(\n * 50) print(fAgent 最终的返回内容final_output:) print(result.final_output) print( * 50) if __name__ __main__: asyncio.run(main())当你运行这段代码时控制台会依次打印出类似下面的内容 开始输出 Agent 的执行足迹输出项 第 1 个输出项: 类型名称: ToolCallItem 原始内容: ResponseFunctionToolCall(idcall_abc123, nameget_weather, arguments{city:武汉}) 第 2 个输出项: 类型名称: ToolCallOutputItem 原始内容: ResponseFunctionToolOutput(idcall_abc123, output天气信息: 武汉是晴天温度 28 度湿度 50%。) 第 3 个输出项: 类型名称: MessageOutputItem 原始内容: ResponseOutputMessage(roleassistant, content[ResponseOutputText(text武汉今天天气晴朗温度28度湿度50%。)]) Agent 最终的返回内容final_output: 武汉今天天气晴朗温度28度湿度50%。 通过这个输出你可以清晰地看到 Agent 的三步走先决定调用工具ToolCallItem然后拿到工具结果ToolCallOutputItem最后生成自然语言回复MessageOutputItem这就是输出项的威力——让 Agent 的每一次思考与行动都无处遁形。三、事件流Agent 的现场直播输出项非常详细但它们有一个“缺点”它们是事后一次性交付的。也就是说你必须等到整个 Run 彻底执行完毕才能从 result.new_items 里拿到所有的输出项。这种模式对于批处理、离线分析来说没有问题但对于需要实时反馈的交互场景比如一个聊天机器人用户显然无法接受等 10 秒钟然后一次性蹦出一大段话。事件流Stream Event就是为了解决这个问题而生的。它把输出项拆解成一个个实时的事件每发生一件事就立即向外推送。1. 事件流的本质从技术的角度看事件流就是 Run 在执行过程中对自身状态变化的一种实时广播机制。官方文档里有一句非常精辟的概括事件流是执行层的实时可观测接口。翻译成大白话就是如果你把 Run 想象成一部正在拍摄的电影那么输出项就是最终剪辑好的成片每一帧都在但你要等全片拍完才能看到。事件流就是现场的导播信号摄像机拍到一个画面就立刻把这个画面传送到监视器上。由于是实时广播事件流特别适合用来驱动 UI 的进度条、实时日志、打字机效果等需要立即反馈的场景。2. 三种事件类型及其用途Agents SDK 的事件流只定义了三种事件类型。不要被“只有三种”迷惑实际上它们已经覆盖了绝大多数实时监控的需求。第一种事件类型RawResponsesStreamEvent这是最底层、最原始的事件。它直接封装了大模型厂商在流式模式下推送的原始数据包。最常见的子类型有两个ResponseTextDeltaEvent代表模型刚刚产出了一小段文本增量——可能只有几个字符。你在网页上看到的“打字机效果”一个字符一个字符往外蹦的效果就是靠捕获这种事件然后逐字追加到页面上实现的。ResponseReasoningDeltaEvent代表模型在推理阶段产出了一小段思维链增量。这类事件不会显示给最终用户但你可以把它收集起来用于调试或者内部审计。第二种事件类型RunItemStreamEvent这种事件的粒度比 RawResponsesStreamEvent 粗一些但语义更丰富。它不是推送一个字符或一个 token而是推送“一个完整的输出项已经生成完毕”这个事实。也就是说每当 SDK 内部新产生了一个 ToolCallItem、ToolCallOutputItem 或 MessageOutputItem就会触发一个 RunItemStreamEvent。通过监听 RunItemStreamEvent你可以实现更高级的 UI 反馈当收到一个 tool_called 事件时你在界面上显示“正在查询天气接口...”。当收到 tool_output 事件时更新为“天气接口返回数据正在分析...”。当收到 message_output_created 事件时切换回正常的文本输出模式。第三种事件类型AgentUpdatedStreamEvent这种事件只在多 Agent 系统中出现单 Agent 模式下基本不会触发。当一个 Agent 主动将任务交接给另一个 Agent 时就会触发此事件事件中会携带新 Agent 的完整对象。你可以利用这个事件在 UI 上切换头像、改变提示语让用户清楚地知道当前正在由哪个 Agent 处理他的问题。3. 什么时候应该用哪种事件为了帮助你决策下面用纯文字列举几个典型场景以及对应的最佳事件选择。场景一实现逐字输出的打字机效果使用 RawResponsesStreamEvent并进一步判断是否为 ResponseTextDeltaEvent。拿到 delta 字段后将内容实时追加到 UI 上。场景二在界面上显示 Agent 当前的执行阶段使用 RunItemStreamEvent。检查 name 字段是否为 tool_called、tool_output 或 message_output_created然后在 UI 中更新对应的状态标签。场景三调试或记录模型内部的推理过程思维链使用 RawResponsesStreamEvent 中的 ResponseReasoningDeltaEvent。将所有的 delta 片段拼接起来就得到了完整的推理摘要。场景四多 Agent 应用中显示当前工作的 Agent使用 AgentUpdatedStreamEvent从 event.new_agent.name 中读取新 Agent 的名字并刷新界面。4. 完整的事件流代码示例下面这段代码演示了如何用 run_streamed 启动流式执行并完整处理三类事件。你可以直接复制运行代码中逐行添加了注释。import asyncio import sys from openai import AsyncOpenAI from openai.types.responses import ( ResponseTextDeltaEvent, ResponseReasoningSummaryTextDeltaEvent ) from agents import ( Agent, OpenAIChatCompletionsModel, Runner, function_tool, set_tracing_disabled, ModelSettings, ) from agents.items import ToolCallItem, ToolCallOutputItem, MessageOutputItem # 配置 API同样以阿里云百炼为例 BASE_URL https://dashscope.aliyuncs.com/compatible-mode/v1 API_KEY sk-your-api-key-here MODEL_NAME qwen3-max # 这个模型支持推理摘要输出 client AsyncOpenAI(base_urlBASE_URL, api_keyAPI_KEY) set_tracing_disabled(True) # 定义一个简单的天气工具 function_tool def get_weather(city: str) - str: 模拟的天气查询工具 return f天气数据: {city} 地区多云转晴气温 22 度空气质量良好。 async def main(): # 创建 Agent # 注意这里增加了 model_settings 参数强制要求模型必须调用工具 agent Agent( name实时天气分析师, instructions( 你是一个严谨的天气分析师。用户询问天气时 你必须先调用 get_weather 工具获取数据 然后再根据数据回答。 ), modelOpenAIChatCompletionsModel(modelMODEL_NAME, openai_clientclient), tools[get_weather], model_settingsModelSettings(tool_choicerequired), # 强制使用工具 ) # 关键点使用 run_streamed 而不是 run # 这样才能获得实时的事件流 result Runner.run_streamed(agent, 麻烦查一下武汉明天的天气情况) print(开始接收实时事件流正在处理...\n) # 异步迭代事件流 async for event in result.stream_events(): # 处理第一类事件原始模型流事件 if event.type raw_response_event: # 如果是文本增量打字机效果的核心 if isinstance(event.data, ResponseTextDeltaEvent): # 直接打印增量内容不换行实现连续输出效果 print(event.data.delta, end, flushTrue) # 如果是推理摘要增量通常不会显示给用户但可以用于调试 elif isinstance(event.data, ResponseReasoningSummaryTextDeltaEvent): # 为了演示我们把它输出到标准错误不与正常输出混在一起 # 在实际开发中你可能把它写入日志文件 print(f\n[推理中] {event.data.delta}, filesys.stderr, end) # 处理第二类事件输出项级别的事件 elif event.type run_item_stream_event: # 获取事件的名称例如 tool_called, tool_output, message_output_created name getattr(event, name, None) # 当工具被调用时触发 if name tool_called and isinstance(event.item, ToolCallItem): tool_name event.item.raw_item.name tool_args event.item.raw_item.arguments print(f\n[系统] 正在调用工具{tool_name}) print(f[系统] 调用参数{tool_args}) # 当工具执行完成并返回结果时触发 elif name tool_output and isinstance(event.item, ToolCallOutputItem): output_data event.item.output print(f\n[系统] 工具返回结果{output_data}) # 当模型生成了一条完整的消息时触发 elif name message_output_created and isinstance(event.item, MessageOutputItem): print(\n[系统] 最终回答生成完毕实时输出如下) # 处理第三类事件Agent 切换事件单 Agent 下很少触发但为了完整性仍保留 elif event.type agent_updated_stream_event: new_agent_name event.new_agent.name print(f\n[系统] 当前工作的 Agent 切换为{new_agent_name}) # 事件流结束后可以获取最终的完整输出 # 注意final_output 是所有文本增量的拼接结果和实时输出的内容一致 print(\n\n * 50) print(最终完整回答final_output:) print(result.final_output) print( * 50) if __name__ __main__: asyncio.run(main())运行这段代码你会发现控制台上的文字是一个字一个字蹦出来的同时在文字之间会穿插类似 [系统] 正在调用工具get_weather 这样的状态信息。这就是事件流的实时魅力。它让你不仅能展示最终结果还能让用户看到 Agent 正在“努力思考”和“积极行动”的全过程体验提升非常明显。四、历史会话Agent 的长期记忆到目前为止我们讨论的所有内容都局限在单次 Run 内部。一个 Run 从用户输入开始到 Agent 输出结束生命周期很短通常只有几秒钟。对于需要多轮对话的应用来说这显然不够——用户希望 Agent 记得他上一轮说了什么甚至记得三天前说过什么。历史会话Conversation模块就是为这个需求而生的。1. 什么是 Conversation在 Agents SDK 中Conversation 被定义为一次 Run 的完整记忆时间线。更具体地说它就是一个按照时间顺序排列的输出项列表。比如一个 Conversation 可能包含以下内容第 1 条用户说“帮我订一张去北京的机票”。第 2 条Agent 调用了一个名为 search_flight 的工具。第 3 条search_flight 工具返回了航班列表。第 4 条Agent 给出了几个航班选项。第 5 条用户回复“选第一个”。第 6 条Agent 调用 book_flight 工具。第 7 条book_flight 工具返回订票成功信息。第 8 条Agent 说“订票成功您的订单号是 xxx”。你看Conversation 实际上就是把一次完整的用户-Agent-工具三方交互的全部输出项串了起来。多轮对话的本质就是多个 Run 共享同一个 Conversation。也就是说第一轮 Run 结束后Conversation 中已经存了若干条输出项。第二轮 Run 开始时SDK 会自动把 Conversation 中的所有历史输出项作为上下文送给模型这样模型就能“回忆”起之前说过的话。2. 为什么 Conversation 至关重要如果没有 Conversation你的 Agent 将是一个“失忆的专家”。每一轮对话都要重新开始用户必须反复提供背景信息。举个例子用户说“帮我查北京的天气”Agent 查了气温是 25 度。用户接着问“那上海呢”。如果 Agent 失忆了它不知道这个“那”指的是什么就必须反问“您指的是哪个城市的天气”这种体验非常糟糕。Conversation 让 Agent 拥有了跨轮次的记忆能力。更妙的是Agents SDK 会自动处理历史上下文的拼接和截断你完全不需要手动将历史消息拼接到新的 Prompt 中。你只需要在每次调用 Runner.run 时传入相同的 Session 对象SDK 会自动从数据库中读出之前的 Conversation然后自动拼接到本次的模型请求中。Conversation 还带来了另外三个重要的能力可回溯性你可以在任何时候翻开某个 Session 的历史看到每一次工具调用的参数和返回值。可调试性当 Agent 行为异常时你可以重放整个会话定位问题是出在模型推理上还是工具执行上。可持久化SDK 支持将会话写入 SQLite、Redis 等存储后端数据不会因为程序重启而丢失。3. 如何使用 Session 管理历史对话在 SDK 中Conversation 是通过 Session 对象来管理的。最常用的实现是 SQLiteSession它将所有会话数据存储在本地的 SQLite 数据库文件中。下面是完整的使用示例from agents import SQLiteSession # 创建一个 SQLiteSession # 第一个参数是 session_id你可以用用户 ID 或对话 ID 来命名 # 第二个参数是数据库文件的路径 session SQLiteSession(user_zhang_san, conversations.db) # 第一轮对话询问天气 result1 await Runner.run( agent, 武汉今天天气怎么样, sessionsession # 传入同一个 session ) # 第二轮对话追问明天的天气 # Agent 会从 session 的历史中知道“明天”指的是“武汉的明天” result2 await Runner.run( agent, 那明天呢, sessionsession # 使用同一个 session自动续写历史 ) # 第三轮对话验证记忆 result3 await Runner.run( agent, 我刚才问了哪几个城市, sessionsession ) print(result3.final_output) # 输出会类似“您刚才问了武汉今天的天气然后问了武汉明天的天气。”从代码中可以看出开发者不需要做任何额外的事情来维护历史消息。SDK 内部会在每次 Runner.run 调用时自动做以下三件事从 Session 中加载已有的 Conversation 历史。将新的用户输入追加到 Conversation 中。调用大模型时自动将整个 Conversation 作为上下文。将模型的新输出、工具调用、工具结果等全部追加到 Conversation 中并写回 Session。整个过程对开发者完全透明。4. 如何读取历史会话你还可以在任意时刻读取某个 Session 的完整历史用于审计、调试或者迁移数据。# 从 Session 中获取所有历史项 all_items await session.get_items() print(f当前会话共有 {len(all_items)} 个历史记录) for idx, item in enumerate(all_items): print(f{idx}: {type(item)}) # 如果你需要更详细的内容可以尝试打印 item.raw_item历史项的类型包括但不限于MessageOutputItemToolCallItemToolCallOutputItemReasoningItemHandoffOutputItem通过分析这些历史项你可以精确地还原出用户和 Agent 之间的每一次交互细节。5. 持久化的意义使用 SQLiteSession 或者自定义的 Session 后端比如 RedisSession意味着你的 Agent 拥有了长期记忆能力。即使用户隔了一周再次访问只要使用同一个 session_idAgent 就能回忆起一周前的对话内容。这对于需要持续服务的场景——比如私人助理、教育辅导、健康咨询——尤其重要。当然你也要注意隐私和合规问题。如果对话中包含敏感信息你需要对数据库进行加密或者定期清理过期的会话。五、总结文章写到这里我们已经完整地走过了 OpenAI Agents SDK 执行层的每一个角落。现在让我们回过头来把四个核心概念放在一起做一个总体的回顾。第一个概念输出项Output Items它是 Agent 执行过程中每一步事实的结构化记录。通过读取输出项你可以知道 Agent 是否调用了工具、传入了什么参数、工具返回了什么结果、模型基于结果生成了什么文字。输出项让 Agent 从无法探测的黑盒变成了可审计、可调试的白盒。第二个概念事件流Stream Event它是输出项的实时版本。输出项是事后一次性交付的而事件流是在 Run 执行过程中实时广播的。事件流分为三类RawResponsesStreamEvent用于构建打字机效果和捕获推理过程。RunItemStreamEvent用于构建高级 UI 状态反馈。AgentUpdatedStreamEvent用于多 Agent 场景下的界面更新。通过事件流你可以让用户实时看到 Agent 的一举一动极大地提升交互体验。第三个概念历史会话Conversation它是多个 Run 共享的记忆时间线本质上就是输出项的有序集合。通过 Session 对象SDK 自动管理历史消息的存储和加载让 Agent 在多轮对话中保持连续的记忆。你可以将会话持久化到 SQLite、Redis 等数据库中实现跨会话、跨设备的记忆共享。第四个概念Run 生命周期它是执行层的容器一个 Run 包含了从用户输入到最终输出的全部信息历史消息、工具调用状态、Agent 路由轨迹、流式状态等。无论你是用 Runner.run 做普通的同步调用还是用 Runner.run_streamed 做流式调用底层都是一个 Run 对象在运转。掌握了执行层你就掌握了 Agent 开发的“仪表盘”。你不会再对着一个神秘的 final_output 惊慌失措而是可以从输出项中轻松定位问题。你不会再苦恼于大模型的响应速度而是可以用事件流优雅地实现打字机效果。你更不会受限于单轮对话而是可以通过 Session 轻松构建多轮、有记忆的智能应用。在下一篇文章中我们将继续深入 Agents SDK 的更高阶特性——多 Agent 协作、交接协议、以及如何构建一个生产级的 Agent 系统。如果你觉得这篇文章对你有帮助欢迎分享给更多对 AI Agent 开发感兴趣的朋友。在 AI 工程化的道路上唯有把黑盒拆成白盒才能走得更稳、更远。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2572787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…