YAOTU INSIGHTS

1M上下文+Codex联网搜索+多Agent协作实战配置指南

1M上下文+Codex联网搜索+多Agent协作实战配置指南
最近不少朋友在同一个项目上卡住了手里有一个支持1M 上下文的大语言模型代号就叫 GPT-5.4想把它接进一个能执行代码的 Agent 环境也就是标题里的 Codex同时还要开启联网搜索最后再配好几个互相协作的 Agents。光看这些关键词就知道这东西不是改一行配置就能跑的里面牵扯到上下文管理、工具调用、Agent 通信协议、成本控制等一大堆细节。这篇文章我想换个讲法不堆官方文档而是从“我实际配下来之后才搞明白的那些事”出发把开启 1M 上下文、接 Codex 联网搜索、配置多 Agents 的完整链路讲清楚。阅读大概需要十分钟适合已经跑过基础 API 调用、但对 Agent 编排还处于“看得懂例子、自己搭不起来”阶段的开发者。哪怕是刚入门的新手只要照着第三章的代码走也能把一个可用的搜索链路跑起来。1. 1M上下文到底意味着什么先别被参数忽悠了1.1 从“能记住多长”到“能解决多复杂”很多人第一次看到 1M 这个数字第一反应是“好大”第二反应是“那我是不是可以把整本小说、整个代码仓库都丢进去”。理论上确实是这样按 Token 估算1M Token 大概能容纳几十万汉字或者几千行代码的多个文件。但问题在于“能容纳”和“能高效利用”是两回事。我做一个非常粗糙的类比。普通模型的上下文窗口像一张书桌桌子越大你能摊开的东西越多但如果你真的把所有材料堆成一摞翻找时反而更慢。1M 上下文更像一个房间房间够大可你如果连角落里发霉的旧报纸都不舍得扔最后住起来一定很难受。模型也一样塞满 1M Token 之后推理延迟会明显上升并且可能出现注意力漂移——它明明看到了关键段落却在无关日志里打转。所以真正值得利用 1M 上下文解决的是那些“整体理解比逐段检索更有价值”的任务。比如一次性读完整份几十页的需求文档同时对比前后章节里的矛盾点再比如把一个包含几百个文件的项目源码作为背景让模型在答复时不用反复去查“函数是在哪个文件里定义的”。对这种场景来说把完整材料送进上下文比做一个半吊子的 RAG 检索链路靠谱得多。1.2 为什么这个能力需要和Codex放在一起用单独一个大模型即使有 1M 上下文也只是“很能记”而已。它不能帮你查实时信息不能帮你跑代码更不可能把改好的文件直接写回目录。这就是 Codex 这类代码执行环境存在的意义。这三个能力组合起来的价值是叠加的1M 上下文给 Agent 提供了一个超长的项目记忆Codex 环境给了它操作代码和文件系统的“手”联网搜索则补上了“获取最新信息”的眼睛。我习惯称这套组合为“一个可以查资料、能动手干活、并且记得住整件事前因后果的临时员工”。但组合起来也是麻烦的开始。当你把一个能联网搜索的工具和一个能写文件的执行环境交到模型手里就必须想清楚谁来决定什么时候搜索搜索结果是直接丢回上下文还是先做摘要Agent 之间怎么共享信息如果不提前设计好这些能力越多越乱最后模型会被自己调用的工具结果淹没。提示配置这类系统前先把目标想清楚。你是要它“读长文档后写作”还是要它“看代码后改代码”还是要它“边查资料边写报告”目标不同上下文策略和 Agent 分工完全不同。2. 开始配置前的四件事环境、权限、工具、预算2.1 确认模型版本和API入口第一步别看演示截图先去官方 API 文档里查你想用的模型标识符到底支不支持“超大上下文”和“工具调用”。这两项是后续所有配置的前提。有些模型虽然在宣传页上写了 1M但实际通过 API 调用时还需要在请求里额外加一个参数或者在后台开通某个配置项否则你填了 context length 也没有用。我踩过的第一个坑就在这里当时我按照旧版代码直接传入一个普通的会话参数模型虽能响应但一旦输入超过几十万 Token 就会报“长度超限”。后来发现是因为该服务商把 1M 上下文做成了独立模型标识符需要显式指定新的 model 名称而不是靠传参硬开。这不算罕见所以请把“确认模型标识符”当成第一优先级花五分钟查文档比事后排查省出两小时。另外API Key 的管理一定不要硬编码。放在环境变量里是目前最通用的习惯我一般会写一个.env文件并在启动脚本中加载。如果团队协作还要区分开发与生产两套 Key避免有人误操作把测试费用打上去。2.2 准备运行环境本机沙箱或云环境Codex 环境本质上是让模型在受控的沙箱里执行代码所以本地机器或云端主机的内存、磁盘和隔离措施都要提前准备好。我的推荐配置是 Python 3.10 以上版本内存至少 16GB工作目录里至少留出 20GB 空间。如果你要分析大型代码仓库建议把仓库单独 clone 到一个不被 Agent 随意修改的只读目录执行目录另建一个workspace两边分开避免模型把原始代码改坏了。安装依赖的时候记得建虚拟环境别图省事直接装在全局环境里。我已经不止一次看到有人因为全局包版本冲突导致 Agent 执行代码时诡异报错最后发现是requests或json解析工具的版本不兼容。虚拟环境虽不能完全避免问题但至少能把变量隔离。2.3 开启联网搜索的权限开关联网搜索不是模型天然自带的能力它通常属于“工具调用”里的一个扩展工具。你要做的有两步第一步在账号或服务后台确认开通了联网搜索权限第二步在每次 API 请求时把搜索能力的定义写进工具列表。不同平台的开关位置不一样但底层逻辑是一样的模型生成一个“调用某工具的请求”本地代码捕获这个请求后执行真实的 HTTP 搜索请求把结果拼接成文本再送还给模型。所以联网搜索本质上是你自己写的一段桥接代码平台只负责告诉模型“你有这个工具可以用”。为了便于理解我给你一个最小可用的工具定义 JSON 片段{ type: function, function: { name: web_search, description: 在互联网上搜索最新信息返回标题、链接和摘要。适用于查询实时资料、官方文档更新、技术公告等。, parameters: { type: object, properties: { query: { type: string, description: 搜索关键词或完整问题 }, max_results: { type: integer, description: 最多返回几条结果默认5条 } }, required: [query] } } }这个 JSON 的作用是告诉模型你有一个函数叫web_search参数是query必填和max_results选填。后续本地代码一旦在模型输出里识别到这个调用请求就立刻执行搜索并把结果包成一个新的“工具消息”送回模型。2.4 预算与限流意识我必须提醒一件事1M 上下文很强但它很贵。你在请求里塞进去多少 Token就要为多少 Token 买单哪怕模型只输出了一个“好的”。如果你每天高频调用当月账单可能高出几个数量级。所以在配置阶段就应养成两个习惯。第一打开服务的缓存机制让相同前缀的输入内容命中缓存能省掉相当一部分重复计费。第二只在真正需要全局理解的环节使用 1M 上下文日常对话、简单问答改用普通小上下文模型不要一个模型吃遍所有场景。3. 把联网搜索接进Codex环境的步骤含完整代码片段3.1 先定义一个“搜索工具”在实际代码里我会把工具定义抽成一个单独的配置模块。这样做的原因很简单模型侧需要 JSON Schema 格式而本地执行函数需要 Python 函数两者要保持同一个 schema否则模型以为能调用的工具本地却找不到对应实现。下面这段 Python 代码演示了工具定义和数据结构的对应关系。实际使用时你需要把WEB_SEARCH_ENDPOINT替换成你所用服务商提供的真实搜索服务地址。import os import json import requests from typing import Any SEARCH_ENDPOINT os.getenv(SEARCH_ENDPOINT, https://api.example-search-service.com/v1/search) SEARCH_KEY os.getenv(SEARCH_API_KEY, ) def web_search(query: str, max_results: int 5) - dict[str, Any]: 执行真实联网搜索返回结构化结果。 headers {Authorization: fBearer {SEARCH_KEY}} params { q: query, num: max_results, format: json } resp requests.get(SEARCH_ENDPOINT, headersheaders, paramsparams, timeout10) resp.raise_for_status() items resp.json().get(items, []) results [] for item in items[:max_results]: results.append({ title: item.get(title, ), url: item.get(link, ), snippet: item.get(snippet, ), }) return {results: results}搜索结果的“干净程度”很重要。我建议把返回结果限制在标题、链接、摘要这三点上不要把整个网页正文都拉回来。否则模型回复时一引用几十个网页正文就把上下文撑爆了1M 也扛不住几次。3.2 让Codex环境具备“搜索→调用→执行”循环有了工具函数接下来是主循环。模型并不直接执行代码它只能输出“我想调用 web_search参数是 xxx”。我们的程序负责捕获这个意图执行函数再把结果返回给模型。如果你用的是 Codex 这类代码执行环境“执行代码”也是同样逻辑模型输出一个代码执行请求沙箱把它跑掉结果传回上下文。我把这个流程拆成三步发送对话请求、识别工具调用、执行并回传结果。核心代码大致如下import json messages [{ role: user, content: 帮我查一下最近发布的稳定版本特性重点关注新增的 API 行为。 }] # 预设模型标识符与工具列表 model_config { model: gpt-5.4-1m, max_tokens: 4096, tools: [ { type: function, function: { name: web_search, description: 在互联网上搜索最新信息返回标题、链接和摘要。, parameters: { type: object, properties: { query: {type: string}, max_results: {type: integer} }, required: [query] } } } ] } # 第一轮模型可能直接回答也可能请求调用工具 response client.chat.completions.create( **model_config, messagesmessages ) message response[choices][0][message] # 判断是否产生工具调用请求 if message.get(tool_calls): for tool_call in message[tool_calls]: fn_name tool_call[function][name] args json.loads(tool_call[function][arguments]) if fn_name web_search: result web_search(**args) messages.append({ role: tool, tool_call_id: tool_call[id], content: json.dumps(result, ensure_asciiFalse) }) # 把执行结果连同原上下文再次发给模型 messages.append(message) final_response client.chat.completions.create( **model_config, messagesmessages ) print(final_response[choices][0][message][content])这里有个细节值得强调工具调用结果必须挂在对应的tool_call_id下否则模型无法把结果关联到它最初发出的请求上。很多初学者会遗漏这一步导致模型根本“看不到”搜索结果然后反复请求同一个搜索白白浪费 Token。3.3 实测联网搜索链路配置完成后的第一次实测我建议不要直接上复杂任务先用一个单点查询验证链路。比如问“某框架最新稳定版是什么版本有什么重大变更”期待中的过程是模型先调用web_search搜索返回几条链接和摘要模型再基于摘要组织一段最终回答。如果整个链路正常日志里应该能看到一次tool_calls记录说明模型确实选择了使用搜索工具而不是凭空编造答案。如果模型始终不调用搜索工具别急着怀疑模型。先检查工具定义里的description是否写清楚了搜索的使用场景。模型工具调用的触发很大程度依赖这段描述是否让它“意识”到该用这个工具。把“适用于查询实时资料、官方文档更新、技术公告等”写清楚效果往往立竿见影。4. 多Agents配置不是越多越好而是分工合理4.1 Agent角色设计把模型接入 Codex 环境只是第一步。真正让系统具有生产力的是为它配置多个各司其职的 Agents。我见过很多人把一堆 Agent 堆在一起任务来了大家一起处理结果上下文互相污染输出质量惨不忍睹。Agent 数量的增加并不会自动提升效果反而放大了协调成本。我的配置经验是先定角色再定消息协议。在一个典型的“分析代码库并修复问题”项目里我通常配置四个角色主控 Agent负责任务拆分、进度管理、最终汇总。它拥有最高层次的上下文但不轻易进入具体细节。研究员 Agent负责联网搜索查询官方文档、相关 issue、最佳实践并输出结构化的调研摘要。编码 Agent只在 Codex 环境里写代码、改代码、跑测试。审查 Agent对编码 Agent 的产出做代码审查关注逻辑漏洞、风格问题和测试遗漏。这样的分工逻辑在于每个 Agent 只需保留自己职能范围内的上下文不需要把整个项目历史和所有搜索结果都扛在肩上。主控 Agent 掌握全局但它只存摘要和决策不存细节细节分散在子 Agent 的局部上下文里。4.2 实现多Agent协作的消息协议多 Agent 之间不能靠“把消息随便塞进同一个对话历史”来协作。我需要一种结构化消息至少包含这几个字段任务 ID、发送者、接收者、消息类型、内容、时间戳。用 Python 字典表达大概是这样agent_message { task_id: TASK-20250321-01, sender: coordinator, receiver: researcher, msg_type: request_search, content: {query: stable version changelog, max_results: 3}, created_at: 1732060800, }每个 Agent 处理完消息后要产出结构化结果回传给主控而不是把一大段原始文本直接塞回去。研究员 Agent 的产出应该是“调研摘要”编码 Agent 的产出应该是“补丁文件路径 测试结果摘要”。这样主控 Agent 的上下文始终能保持精简不至于被细节淹没。这里有一个我一开始没想明白的点虽然模型本身有 1M 上下文但多 Agent 场景下上下文不是越大越好。因为每个 Agent 都要在有限窗口内做决策一旦它看到过多不相关信息判断力就会下降。所以正确的做法是“给每个 Agent 一个足够小但足够完整的上下文”。4.3 给Agent配“子上下文”的小技巧在上一节的基础上我推荐一种“父子上下文”模式一个全局共享目录用于存放任务状态和中间产物各 Agent 只读取自己需要的那部分。具体实现可以是文件系统也可以是一个简单的内存消息队列。我常用的目录规划是project/ ├── shared/ # 全局共享信息所有Agent可读 │ ├── task_status.json │ └── final_decision.md ├── researcher/ # 研究员Agent独有 │ └── research_notes/ ├── coder/ # 编码Agent独有 │ └── patches/ └── reviewer/ # 审查Agent独有 └── review_logs/这种设计虽然简单但能避免一个很常见的翻车事故多个子 Agent 同时修改同一个文件互相覆盖都不自知。把每个 Agent 的写入范围限制在独立子目录里冲突率能下降一个数量级。5. 一个迷你实战让整套系统帮我分析一个开源项目并产出修复方案5.1 实战目标与输入理论说了这么多下面跑一个可以完全复现的迷你实战。我把目标定为一个某社区成员提报的崩溃问题用户在一个中等规模的项目里触发了某个异常日志显示崩溃发生在某个函数调用链的深处。我们需要完成“定位问题 → 查最新资料 → 修改代码 → 回归测试 → 输出报告”这一整套流程。第一步主控 Agent 先读取崩溃日志和项目结构目录把整个仓库的关键路径文件按重要性排个序然后把最重要的几十个文件内容纳入 1M 上下文。这一步正好发挥长上下文的优势不用提前做复杂的 RAG 分块模型可以直接对照多个文件之间的定义关系减少“张冠李戴”。5.2 观察整套流水线如何协同实战里主控 Agent 先自己做了初步判断崩溃可能和某个依赖库的新版本行为变化有关但它不确定于是派发了一个“搜索任务”给研究员 Agent。研究员 Agent 收到任务后通过联网搜索查到该依赖库在最新版本里的一个破坏性变更公告同时找到两个相关 issue 讨论帖。它把搜索摘要回传给主控摘要里附带了来源 URL 和变更点说明。主控 Agent 拿到摘要后把相关背景注入编码 Agent 的上下文。编码 Agent 在 Codex 环境里定位到具体代码片段修改了参数校验逻辑再调用命令行工具跑了一遍单元测试。测试日志显示通过后编码 Agent 把补丁文件路径和测试摘要回传。最后审查 Agent 对补丁做了代码审查没有发现明显副作用然后把结论交回主控。主控生成最终报告崩溃根因是什么改了哪个文件跑过什么测试遗留风险有哪些。整个流程里没有哪个 Agent 从头到尾看过所有信息。主控看的摘要研究员看的是网络搜索结果编码 Agent 看的是源码和相关性脚本审查 Agent 看的是补丁和测试结果。每个 Agent 接触的信息与它的职责严格匹配。5.3 结果与耗时评估我实际跑通这套流程的耗时大约在十几分钟左右其中大部分时间是等待模型多次推理和工具执行。如果人工来做先读日志、再查资料、翻源码、写补丁、跑回归动作熟练的话也需要几个小时。更关键的是这套系统可以反复执行你只需要把它包装成一个流水线脚本后续再遇到类似任务提交一条消息就能开跑。当然它还没有到“全自动无人值守”的程度。比如研究员 Agent 搜索时可能被低质量内容带偏编码 Agent 可能修改了错误的代码分支。这些都是实际使用中需要接受的现状Agent 系统不是一次配置就永久稳定它更像一个需要定期校准的协作团队。6. 我踩过的坑上下文管理、搜索超时、Agent上下文泄漏6.1 上下文窗口看着大但别什么都塞我曾在一次长文档分析任务里真的把一个大约 800K Token 的项目日志全部塞进上下文然后等模型回复。结果那个请求花了两分多钟才返回而且最后的结论偏离了核心问题。这件事给我的教训是1M 上下文是上限不是推荐值。现在的习惯是进入上下文的材料必须先做粗筛。项目源码可以全读但日志只保留接近崩溃时间段的文档可以全读但已经淘汰的旧版本说明就不要放进去。你可以为模型做个“资料清单”让它在上下文里只保存资料索引和摘要需要细节时再用工具读取对应文件而不是把所有原件一股脑全塞给它。6.2 联网搜索的结果质量不高怎么办联网搜索接进来之后你不会马上得到完美的信息。最典型的问题是模型搜索 “最新发布版本” 时搜索引擎返回了一堆过时页面或无关内容。这并不能全怪模型搜索工具的query构造方式对结果影响极大。我的优化方法是在工具描述里引导模型先拆解用户问题再生成多组关键词组合。比如用户问“某功能在发版后为什么变了”模型应分别搜索“功能名 变更公告”和“功能名 最新文档”而不是把整句话原封不动复制进去。另一个有效动作是为搜索结果加上时间过滤参数让模型优先采用近几个月内的来源避免被老文章误导。6.3 Agent之间互相覆盖上下文多 Agent 协作最隐蔽的坑是“上下文泄漏”。例如研究员 Agent 把自己搜到的资料原样写入了全局共享目录编码 Agent 因为读取了这份完整资料导致它的上下文被无关历史信息占满最终决策质量下降。解决思路是“写入共享目录前先做摘要”。所有 Agent 向外输出的信息都应该是加工过的结论而不是原始数据。这不只节省 Token更重要的是避免 Agent 之间的信息互相干扰。建议在所有 Agent 的 system prompt 中明确写一句你向其他 Agent 传递信息时必须使用结构化摘要附带上文背景禁止直接粘贴原始日志或网页正文。6.4 成本优化缓存、批处理、延迟非紧急搜索最后聊钱。1M 上下文项目跑一天账单增长速度可能超出预期。我统计过自己一周的使用情况发现约一半的开销集中在反复读取同一批大文档上。开通服务商提供的缓存能力之后这类重复读取的成本大幅下降。此外把非紧急任务集中批处理也是有效的省钱手段。比如夜间让系统一口气跑五份报告而不是白天每来一个请求就热启动一套 1M 上下文流水线。搜索任务同样可以做策略优化一次会话内如果已经搜过同主题就直接复用上一轮结果不再重复触发搜索。根据我个人的实际体验这套“1M 上下文 Codex 联网搜索 多 Agents”的配置真正的门槛不在于代码实现而在于你是否愿意把时间花在角色设计和上下文梳理上。工具调用、沙箱执行、消息协议都是可以替换的模块唯独“让每个 Agent 恰好看到它该看的内容”这件事是决定系统聪明还是愚笨的分水岭。如果你现在正准备搭一套类似的系统我建议从最小链路开始先不加 Agent只把联网搜索和代码执行串联跑通再逐步增加角色观察每一步对输出质量的影响而不是第一次就直接上全配置。