拓冰建站拓冰建站
首页 / 资讯中心 / 正文

笔记:从0开始学习ai agent(基于openai官方文档)

纯干货配置python3.14需要# Pythonpip install openai-agents本文章底层模型均为deepseek因为便宜首先我们需要配置deepseek调用api_Key记得把api_key放在.env文件中不要将密钥暴露出来。import asyncio# 导入 asyncioPython 异步编程库用于运行 async/await 协程 import os# 导入 os读取环境变量、操作系统相关功能 import sys# 导入 sys访问 Python 解释器信息如平台、标准输出 import requests from pathlib import Path# 导入 Path以对象方式处理文件路径 from dotenv import load_dotenv# 从 python-dotenv 导入 load_dotenv从 .env 文件加载密钥到环境变量 from agents import Agent, Runner, RunConfig# 从 openai-agents 导入核心类 from agents.models.openai_provider import OpenAIProvider# 导入 OpenAIProvider模型提供方 from agents import function_tool if sys.platform win32: sys.stdout.reconfigure(encodingutf-8)# 若在 Windows 上运行把终端输出编码设为 UTF-8避免中文乱码 _script_dir Path(__file__).resolve().parent# 获取当前脚本所在目录的绝对路径 load_dotenv(_script_dir / .env)# 尝试加载 /.env load_dotenv(_script_dir.parent / .env)# 尝试加载你实际放密钥的位置 # 从环境变量读取 DeepSeek API Key api_key os.getenv(DEEPSEEK_API_KEY) # 若未读到密钥打印提示并退出避免后续调用 API 时报错 if not api_key: raise SystemExit( 未检测到 DEEPSEEK_API_KEY。请在 .env 里填入\n DEEPSEEK_API_KEY你的DeepSeek密钥 ) # 创建 DeepSeek 模型提供方 # DeepSeek 接口兼容 OpenAI只需改 base_url无需换 SDK deepseek_provider OpenAIProvider( api_keyapi_key, base_urlhttps://api.deepseek.com, )一、AGENTquick start快速创建你的第一个ai agent学会让agent调用tools同时创建tools给agent调用创建多个agent负责各领域的任务function_tool def get_history_fact(topic: str) - str: #获取关于特定历史话题的冷知识。 url https://uselessfacts.jsph.pl/api/v2/facts/random response requests.get(url) data response.json() fact data.get(text, ) return fact # 定义一个 Agent智能体 history_tutor Agent( nameHistory tutor, # Agent 名称用于日志和调试 instructionsYou answer history questions clearly and concisely., # 系统指令定义角色与回答风格 tools[get_history_fact], modeldeepseek-chat, ) math_tutor Agent( nameMath tutor, handoff_descriptionSpecialist for math questions., instructionsExplain math step by step and include worked examples., modeldeepseek-chat, ) triage_agent Agent( nameHomework triage, instructionsRoute each homework question to the right specialist., handoffs[history_tutor, math_tutor], modeldeepseek-chat, ) # 定义异步主函数openai-agents 的 Runner.run 是异步的需在 async 函数里 await async def main() - None: # 运行 Agent把用户问题发给它并等待结果 result await Runner.run( triage_agent, # 要运行的 Agent Who was the first president of the United States?, # 用户输入问题 run_configRunConfig( model_providerdeepseek_provider, tracing_disabledTrue, ), ) print(result.final_output) if __name__ __main__: asyncio.run(main())agent 定义1.在以下三个配置选项上你需要格外留心优先使用静态指令instructions。当你的引导内容需要根据当前用户、租户或运行时上下文发生变化时请改用动态指令回调dynamic instructions callback千万不要在调用处用代码去生硬地拼接字符串。保持移交描述handoff_description简短且具体。这样负责路由的分诊智能体才能准确知道在什么情况下该把任务交给这个专属智能体。当下游代码需要结构化数据而不是随意的自然语言文本时请使用output_type。2.何时将单个智能体拆分为多个当某个专属智能体Specialist不应该独立承担完整的回复或者各项功能之间存在实质性差异时就应该进行拆分。常见的原因包括工具或接口不同某个专属智能体需要使用不同的工具或 MCPModel Context Protocol模型上下文协议接口。安全策略不同某个专属智能体需要应用不同的审批策略或安全护栏Guardrails。模型或输出风格不同工作流中的某个分支需要使用不同的底层模型或者需要呈现不同的输出风格。链路追踪更清晰你希望在运行追踪Traces中看到明确的路由分发过程而不是依赖一个庞大且复杂的单一提示词Prompt。3.重要的边界如果模型需要事实就把它放在指令、输入、检索或工具中。如果只是运行时需要就放在本地上下文中。模型看到的是对话历史。运行上下文是你的代码看到的。增加上下文边界增加handoff_description:class CalendarEvent(BaseModel): name: str date: str participants: list[str] dataclass class UserInfo: name: str uid: int function_tool async def fetch_user_age(wrapper: RunContextWrapper[UserInfo]) - str: Fetch the age of the current user. return fThe user {wrapper.context.name} is 47 years old. calendar_agent Agent( namecalendar_agent, handoff_descriptionSpecialist for extracting calendar events from text., instructionsExtract calendar events from text., output_typeCalendarEvent, modeldeepseek-chat, ) age_agent Agent( nameage_Assistant, handoff_descriptionSpecialist for fetching user age information., instructionsUse fetch_user_age to get the users age, then answer clearly., modeldeepseek-chat, tools[fetch_user_age], ) triage_agent Agent( nametriage, instructionsRoute each question to the right specialist., handoffs[calendar_agent, age_agent], modeldeepseek-chat, ) async def main() - None: result await Runner.run( triage_agent, What is the age of the user?, contextUserInfo(nameJohn, uid123), run_configRunConfig( model_providerdeepseek_provider, modeldeepseek-chat, tracing_disabledTrue, ), ) print(result.final_output) if __name__ __main__: asyncio.run(main())Models and providers从明确指定模型开始在生产环境中建议你显式指定模型而不是依赖你的 SDK 版本碰巧自带的运行时默认模型。在智能体Agent级别设置model当某个专属智能体持续需要不同的质量、延迟或成本配置时单独为它指定模型。在运行Run级别设置默认值当某一个工作流需要同时覆盖override多个智能体的模型时在运行层设置默认值。设置环境变量OPENAI_DEFAULT_MODEL当你希望为那些没有显式指定model的智能体提供一个全局进程级别的兜底默认模型时使用此配置。运行的agent智能体循环The Agent Loop一次 SDK 的运行SDK run代表一个应用级别的回合turn。运行器Runner会持续进行循环直到达到一个真正的停止点调用模型使用准备好的输入调用当前智能体的底层模型。检查输出检查模型返回的结果。执行工具如果模型产生了工具调用tool calls则执行这些工具并继续循环。移交任务如果模型将任务移交handed off给了另一个专属智能体则切换智能体并继续循环。返回结果如果模型生成了最终答案且不再需要执行任何工具则返回最终结果并结束循环。选择对话状态管理策略四种策略本质上是在权衡“控制力”与“便捷度”result.to_input_list()自己管你把所有的聊天记录存在自己的数据库里每次发消息都把完整历史发给 AI。优点是绝对安全、完全可控缺点是消息越长每次发给 AI 的 Token 消耗越大。session半托管SDK 帮你管理一部分你负责持久化存储。适合需要保存用户长期记忆、甚至支持断网重连的复杂应用。conversationId全托管-长对话把记忆交给 OpenAI 的服务器。你只需要传一个 ID 和新消息服务器会自动帮你拼接历史。适合跨服务器部署的复杂应用。previous_response_id全托管-极简最轻量的做法。你连完整的 ID 都不用管只要告诉 AI “接着上一次的回复继续说”并给出新消息即可。适合快速开发、不需要复杂状态管理的场景。在大多数应用中一次对话最好只选择一种状态管理策略。除非你刻意去对齐这两层的数据否则把本地重放local replay和服务器托管状态混在一起用很容易导致上下文被重复记录如果你需要持久化的记忆、可恢复的审批流程或者由你的应用程序自行掌控的存储那么 Sessions会话是最好的默认选择##session agent Agent( nameTour guide, instructionsAnswer with compact travel facts., modeldeepseek-chat, ) session SQLiteSession(conversation_123) async def main() - None: first_turn await Runner.run( agent, What city is the Golden Gate Bridge in?, sessionsession, run_configRunConfig( model_providerdeepseek_provider, tracing_disabledTrue ), ) print(first_turn.final_output) second_turn await Runner.run( agent, What state is it in?, sessionsession, run_configRunConfig( model_providerdeepseek_provider, tracing_disabledTrue ), ) print(second_turn.final_output)使用agents框架实现流式输出Streaming也就是我们在聊天界面中常见的“打字机”逐字显示效果。#Stream runs incrementally agent Agent( namePlanet guide, instructionsAnswer with short facts., modeldeepseek-chat, ) async def main() - None: stream Runner.run_streamed( agent, Give me three short facts about Saturn., run_configRunConfig( model_providerdeepseek_provider, tracing_disabledTrue ), ) async for event in stream.stream_events(): if event.type raw_response_event and isinstance( event.data, ResponseTextDeltaEvent ): print(event.data.delta, end, flushTrue) print(f\nFinal: {stream.final_output})有三条实用的规则至关重要在将某次运行run视为“已确定/已结算”之前必须等待流stream完全结束。如果运行因需要审批而暂停应解决审批后从原有的状态state恢复而不是开启一个全新的用户对话轮次user turn。如果在对话中途取消了流式输出且希望后续能继续同一个对话轮次请从该状态state恢复未完成的轮次。要刻意主动地处理暂停与失败情况。这里有两类非正常流程non-happy-path的结果需要特别关注运行时或校验失败例如达到了最大轮次限制、触发了安全护栏异常或者工具调用报错。预期内的暂停例如请求人工审批。此时任务是被故意中断的后续应该能从当前状态继续往下走。要把“审批”当作“暂停的任务”而不是“新的一轮对话”。保持这个区分非常重要它能确保你的轮次计数、历史记录以及服务器用来追踪进度的 continuation ID 都能保持一致不会乱套。function_tool(needs_approvalTrue) def delete_file(path: str) - str: Delete a file on the server (demo only). return fDeleted {path} function_tool def ping() - str: Health check tool. return pong approval_agent Agent( nameFile assistant, instructionsWhen the user asks to delete a file, call delete_file., tools[delete_file], modelDEFAULT_MODEL, ) loop_agent Agent( nameLoop agent, instructionsAlways call ping before answering., tools[ping], modelDEFAULT_MODEL, ) chat_agent Agent( namePlanet guide, instructionsAnswer with short facts., modelDEFAULT_MODEL, ) def print_section(title: str) - None: print(\n * 60) print(title) print( * 60) async def demo_stream_must_finish_before_finalize() - None: 规则 1必须等 stream 结束再视为 run 已结算。 print_section(示例 1流式输出 — 等 stream 完全结束) stream Runner.run_streamed( chat_agent, Give me two short facts about Saturn., run_configRUN_CONFIG, ) print(流式输出: , end) async for event in stream.stream_events(): if event.type raw_response_event and isinstance( event.data, ResponseTextDeltaEvent ): print(event.data.delta, end, flushTrue) # ✅ 正确stream_events() 消费完后再检查异常和最终结果 if stream.run_loop_exception: raise stream.run_loop_exception # ❌ 错误在 async for 之前就 print(stream.final_output)通常还是 None print(f\n\n流结束后 final_output: {stream.final_output}) async def demo_approval_resume_from_state_not_new_turn() - None: 规则 2 6审批 暂停的任务恢复时传 RunState不传新用户消息。 print_section(示例 2审批暂停 — 从 state 恢复不是新一轮对话) session SQLiteSession(approval_demo_session) # 第一次 run会在工具审批处暂停 paused await Runner.run( approval_agent, Delete the file /tmp/demo.txt, sessionsession, run_configRUN_CONFIG, ) print(f暂停时 final_output: {paused.final_output!r}) print(f待审批数量: {len(paused.interruptions)}) if not paused.interruptions: print(模型未触发审批跳过恢复示例。) return approval paused.interruptions[0] print(f待审批工具: {approval.tool_name}) # ✅ 正确审批后从 state 恢复继续同一轮任务 state paused.to_state() state.approve(approval) resumed await Runner.run( approval_agent, state, # 注意这里不是新的用户输入字符串 sessionsession, run_configRUN_CONFIG, ) print(f恢复后 final_output: {resumed.final_output}) # ❌ 错误做法不要这样 # resumed await Runner.run(approval_agent, 批准删除, sessionsession) # 这会被当成新的 user turn轮次计数和 continuation 都会乱 async def demo_streamed_approval_resume() - None: 规则 1 2流式 run 也要等结束后再从 interruptions 恢复。 print_section(示例 3流式 审批 — 先等 stream 结束再恢复) stream Runner.run_streamed( approval_agent, Delete the file /tmp/stream-demo.txt, run_configRUN_CONFIG, ) async for _event in stream.stream_events(): pass if stream.run_loop_exception: raise stream.run_loop_exception if not stream.interruptions: print(未触发审批。) return state stream.to_state() state.approve(stream.interruptions[0]) resumed await Runner.run(approval_agent, state, run_configRUN_CONFIG) print(f恢复结果: {resumed.final_output}) async def demo_runtime_failure_max_turns() - None: 规则 4运行时失败 — 例如超过 max_turns需要显式捕获。 print_section(示例 4运行时失败 — max_turns 超限) try: await Runner.run( loop_agent, Say hello., max_turns1, run_configRUN_CONFIG, ) except MaxTurnsExceeded: print(已捕获 MaxTurnsExceeded这是运行时失败不是审批暂停。) print(处理方式提高 max_turns、简化任务或检查是否陷入工具循环。) async def main() - None: await demo_stream_must_finish_before_finalize() await demo_approval_resume_from_state_not_new_turn() await demo_streamed_approval_resume() await demo_runtime_failure_max_turns() if __name__ __main__: asyncio.run(main())沙盒助手何时使用沙箱Sandbox当智能体Agent的回答依赖于在沙箱工作区中实际执行的工作而不仅仅是对提示词Prompt上下文的逻辑推理时请使用沙箱。常见的痛点场景包括任务需要处理一整个文档目录而不是仅仅处理单条提示词。智能体需要生成/写入文件以便你的应用程序在稍后进行审查或检查。智能体需要执行特定的命令、安装软件包或运行脚本来完成工作。工作流会产出各类实体产物Artifacts例如 Markdown 文件、CSV、JSONL、截图或生成的网页。需要在开放的端口上运行某项服务、Notebook笔记本或报告预览。工作流需要暂停以等待人工审查随后在同一个工作区内继续恢复运行。沙箱需要什么组件 (Piece)所有权/职责 (What it owns)核心设计问题 (Design question)SandboxAgent (沙箱智能体)智能体的定义以及沙箱的默认配置这个智能体应该做什么哪些沙箱默认配置应该与它绑定Manifest (清单/配置清单)全新会话fresh-session的工作区契约工作区初始化时应该包含哪些文件、目录、代码仓库、挂载项、环境变量、用户或用户组Capabilities (能力集)附加在智能体上的沙箱原生行为这个智能体需要哪些沙箱工具、指令或运行时行为Sandbox client (沙箱客户端)提供商的集成对接实际的工作区应该在哪里运行本地 Unix 环境、Docker 容器还是托管的云端提供商Sandbox session (沙箱会话)实时运行的执行环境命令在哪里执行文件在哪里被修改端口在哪里开放提供商的状态保存在哪里Sandbox run config (沙箱运行配置)每次运行的沙箱会话来源、客户端选项及全新输入这一次运行应该注入inject、恢复resume还是创建create沙箱会话Saved state (保存的状态)RunState运行状态、序列化的会话状态以及快照(注原文此处未列出设计问题通常指如何持久化并恢复上述所有运行环境的状态)创建工作环境创建工作区Create the workspace清单Manifest用于描述全新沙箱工作区期望的初始内容和目录布局。你可以用它来定义智能体Agent在启动时应该看到的文件、代码仓库、输入产物、辅助文件、挂载项、输出目录以及环境配置。请将清单视为一份“全新会话的契约fresh-session contract”而不是每个实时运行沙箱的绝对唯一事实来源source of truth。某次运行的实际工作区也可以来自一个被复用的实时沙箱会话、序列化的沙箱会话状态或者在运行时选择的某个快照。清单中的条目路径必须是相对于工作区的。它们不能是绝对路径也不能通过..等方式逃逸出工作区边界。这一限制确保了工作区契约在本地环境、Docker 容器以及托管客户端之间具有可移植性。简单来说Manifest 就像是沙箱的“初始装修图纸”。它规定了沙箱刚建好时里面有什么。但如果你中途暂停了沙箱下次恢复时就不需要再看这份图纸了而是直接恢复之前的状态。同时为了保证安全这份图纸里的路径必须是相对路径绝不能让 AI 有机会去读写沙箱外面的系统文件。良好的清单设计意味着把仓库、输入工件和输出目录放进清单里。在工作区文件如 或 中放入更长的任务规格和本地仓库指令。repo/task.mdAGENTS.md在指令中使用相对工作区路径例如。repo/task.mdoutput/report.md保持挂载存储对应代理应读写输入的范围。将挂载条目视为临时工作区条目快照和持久化流跳过挂载的远程存储而不是将其复制到已保存的工作区内容中。挂载文件与存储有用的数据通常已经存在于其他地方。与其将庞大的文档直接粘贴到上下文中不如将它们挂载到沙箱中让智能体Agent直接处理这些文件。示例挂载尽职调查数据室data room并要求智能体生成一份带引用的摘要。挂载客服导出的数据并要求智能体将问题聚类成一份报告。挂载生成的产物以便其他系统进行审查。各提供商的集成会暴露它们自己的挂载辅助工具、凭证处理逻辑和持久化行为。但应用层的契约应保持一致只挂载智能体需要使用的输入数据告诉智能体去哪里读取和写入并在使用生成的产物前进行检查。处理密钥与凭证请将沙箱凭证视为“运行时配置runtime configuration”而不是提示词prompt的内容。智能体可能需要访问包管理器、存储挂载或提供商 API 的凭证但这些凭证绝不应出现在用户提示词、智能体指令、任务文件、提交的清单manifests或生成的产物中。请遵循以下规则对于托管型沙箱提供商优先使用提供商原生的密钥管理系统。云存储凭证的作用域应严格限制在需要它们的挂载项或提供商选项中。使用Manifest.environment来传递沙箱进程启动时所需的值如果你希望敏感或生成的条目在每次运行时重建而不是被持久化保存请将其标记为临时ephemeral。避免保存密钥、生成的挂载配置、本地令牌或任何不应在运行结束后保留的文件。在将产物移出沙箱之前务必进行审查尤其是当智能体能够读取私有文档或挂载的存储时。SDK 支持清单环境变量manifest environment values和特定提供商的挂载凭证。通用的密钥存储集成取决于具体的提供商因此本页的重点在于契约本身你的运行时或沙箱提供商应该负责注入凭证而不是将这些凭证作为指令教给模型。赋予代理功能将沙箱原生行为附加到一个他们能塑造运行开始前的工作区附加沙盒专用指令提供这些工具可以绑定到实时沙盒会话并调整模型行为或输入为agent处理。装载skillsagent SandboxAgent( nameTax prep assistant, # 智能体名称报税助手 instructionsUse the mounted skill before preparing the return., # 指令在准备报税之前先使用挂载的技能 capabilitiesCapabilities.default() # 使用默认能力集 [ # 将技能配置为从 Git 仓库加载指定了仓库地址和 main 分支 Skills(from_GitRepo(repoowner/tax-prep-skills, refmain)), ], )选择skill懒加载Lazy适合“大仓库”AI 先看目录Index用到哪个再去加载哪个节省资源。全量预加载Local适合“小文件”启动时一次性全部塞进沙箱。Git 仓库Git Repo适合“独立维护的插件”方便版本控制和多端共享暴露预览与端口Expose previews and ports有时产物artifact并不是一个文件而是一个正在运行的进程。当智能体在沙箱内创建了一个本地应用、Notebook笔记本、报告服务器、浏览器预览或其他需要在沙箱外部进行审查的服务时请使用“暴露端口exposed port”功能。运行沙箱智能体Run a sandbox agent最精简且实用的沙箱运行闭环如下构建一个描述工作区的清单Manifest。创建一个包含模型所需能力的沙箱智能体SandboxAgent。选择一个沙箱客户端sandbox client以决定工作将在哪种环境中运行。使用针对单次运行的沙箱配置来运行该智能体。检查、复制、恢复或快照那些对你的应用程序至关重要的产物高级模式Advanced patterns一旦基础循环basic loop跑通当智能体需要沙箱工作区sandbox workspace而不是更多提示词上下文prompt context时沙箱就会在各类工作流中发挥巨大作用。以下这些示例是工作流模式workflow patterns而不是独立的 API同一个运行框架harness可以负责工作流的路由、暂停、恢复和追踪而每个沙箱则负责将执行过程紧贴其所需的文件、工具和端口。恢复或为未来的工作提供初始输入在实际运行中运行器Runner会按照以下优先级顺序来解析并确定沙箱会话如果你直接传入了一个活跃的沙箱会话live sandbox session运行器将直接复用该会话。否则如果本次运行是从RunState运行状态恢复的运行器将从存储的沙箱会话状态中恢复。否则如果你显式传入了序列化的沙箱状态serialized sandbox state运行器将从该状态恢复。如果以上都不满足运行器将创建一个全新的沙箱会话。对于这个全新会话如果提供了针对单次运行的清单per-run manifest则使用该清单如果没有提供则使用智能体agent的默认清单。全新会话的输入Fresh-session inputs例如manifest和snapshots仅在运行器Runner创建全新的沙箱会话时才会生效。如果你注入的是一个活跃的会话live session能力处理capability processing机制可以添加兼容的“非挂载类non-mount”条目但它不能执行以下操作更改根目录root、环境变量environment、用户users或用户组groups移除现有的条目替换条目的类型在已经运行的沙箱上添加或更改挂载mount条目。这种职责分离split的设计使得运行框架harness能够在恢复智能体运行循环agent loop的同时让沙箱提供商在后台去恢复或重建工作区。跨运行持久保存内存沙盒内存让未来的沙盒代理运行能从之前的运行中学习。是 与SDK管理的会话内存分离会话保持 消息历史而沙盒记忆则从之前汲取有用的经验教训 工作空间运行到代理可以之后读取的文件中。Orchestration and handoffs1.当专家应负责工作的不同部分时多代理工作流程非常有用。第一个设计选择是决定在工作流程的每个分支中谁拥有最终面向用户的答案。2.使用agent作为管理者式工作流程的工具。3.只有当专家实质性提升了能力隔离、政策隔离、及时清晰或追踪可读性时才加入agent。护栏与人工审核护栏Guardrails自动验证输入、输出或工具行为。人工审核Human Approval暂停运行等待个人或策略批准/拒绝敏感操作。何时使用哪种控制使用场景推荐控制方式在主模型运行前阻止用户请求输入护栏(Input Guardrail)在最终输出离开系统前验证或编辑输出护栏(Output Guardrail)围绕函数工具调用检查参数或结果工具护栏(Tool Guardrail)出现副作用前暂停如取消订单、执行 Shell 命令人工参与审批(Human Approval)核心机制详解A. 输入护栏阻断请求作用在昂贵或高风险的工作流开始前快速验证。实现定义一个专门用于检查的 Agent如检查是否为数学作业使用input_guardrail装饰器。如果触发阈值tripwire_triggeredTrue会抛出InputGuardrailTripwireTriggered异常阻断请求。策略如果启动主 Agent 成本高用阻塞执行如果低延迟更重要用并行护栏。B. 人工审核暂停与恢复作用模型决定需要执行动作但运行会暂停直到你批准或拒绝。实现在工具定义时加上needs_approvalTrue如cancel_order。流程运行返回后检查result.interruptions。如果有中断调用result.to_state()获取状态对中断项执行state.approve()然后从同一个 state 恢复运行。C. 审批生命周期关键原则运行记录的是“批准中断”而不是直接执行工具。结果返回时带有可恢复的state。应用层决定是否批准待处理项。从同一轮次state继续而不是开启新的用户回合。如果审核耗时可以序列化、存储 state稍后继续它仍然是同一个运行。重要的架构边界与注意事项护栏的作用域限制输入护栏只为链中的第一个 Agent 运行。输出护栏只针对产生最终输出的 Agent 运行。工具护栏运行在它绑定的功能工具上。建议如果需要检查每个自定义工具调用不要只依赖 Agent 级的护栏应把验证逻辑放在产生副作用的工具旁边。网络安全与执行前审查对于授权的安全工作流必须在副作用发生前评估敏感工具调用。检查拟议目标、动作、参数、身份及调用窗口。拒绝超出范围的操作如凭证盗窃、数据外泄、破坏性变更等。强制独立的文件系统、网络、身份边界并记录决策。注意Responses API 和 Agents SDK不会自动继承 Codex 的自动审查你需要自己加上这道“安全带”。流式传输Streaming与状态模型流式传输不会创建独立的审批系统。如果流式运行暂停等待它稳定finish检查interruptions解决审批然后从同一个 state 继续。如果复核发生在后期存储序列化 state决策到来后继续执行同样的运行。结果与状态如果你需要的话用途最终答案是要展示给用户final_output本地可重播历史to_input_list()通常应该掌控下一回合的专家last_agentOpenAI 管理的响应链last_response_id待审批及可恢复快照interruptions加to_state()MCP 工具和trace需求推荐方案原因让智能体访问公开的远程托管 MCP 工具SDK 内的 Hosted MCP tools托管式模型直接通过模型表面调用远程 MCP 服务器从你的运行时连接本地或私有 MCP 服务器SDK 管理的 MCP 服务器走 stdio 或流式 HTTP由你的运行时自己掌控连接、审批和网络边界调试提示词、工具、交接或审批内置 Tracing链路追踪在正式建立评估eval体系之前追踪能先给你端到端的完整记录MCP托管式公开的远程服务器信任模型匹配即可用。本地/私有式需要运行时掌控连接、过滤、审批时选它。Tracing 的两个用途调试追踪某一次工作流运行搞清楚到底发生了什么。评估等你准备好系统性地给行为打分时把高信号高质量的样例喂给智能体工作流评估eval。评估代理工作流程使用追踪、评分器、数据集和评估运行来提升代理质量。二、工具tools工具名称核心功能与描述函数调用 (Function Calling)调用自定义代码让模型能够访问更多外部数据和业务能力。网络搜索 (Web Search)在模型生成响应时实时检索并包含来自互联网的最新数据。远程 MCP 服务器 (Remote MCP Servers)通过模型上下文协议MCP赋予模型访问外部新功能服务器的能力。技能 (Skills)在托管的 Shell 环境中上传并重用版本化的技能包包含指令、脚本等。Shell (命令行)在托管的容器或你自己的本地运行时中运行 Shell 命令。计算机应用 (Computer Use)创建能够让模型直接控制计算机界面的智能工作流。图像生成 (Image Generation)使用 GPT Image 模型生成或编辑图片。文件搜索 (File Search)对上传的文件进行检索为模型生成响应提供上下文。工具搜索 (Tool Search)动态加载相关工具到模型上下文中以优化 Token 使用量。程序化工具调用 (Programmatic Tool Calling)让模型编写并运行 JavaScript 代码来协调和编排其他工具的调用。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门