☰
Manus上下文工程深度拆解:AI Agent的护城河,从配置到验证一篇就够
2026/9/28 4:31:11 网站建设 项目流程

1. 为什么你的 Agent 总是“又慢又笨”:从 Manus 的上下文工程说起

如果你正在做 AI Agent 开发,大概率遇到过这种场景:任务跑到第 30 轮工具调用时,模型开始重复之前的动作,回答质量断崖式下跌,Token 账单却一路飙升。你以为是模型不行,换了个更强的模型,结果只是把“腐烂”的阈值往后推了一点,问题依旧。Manus 联合创始人兼首席科学家 Peak 在跟 LangChain 创始人交流时提到过一个关键判断:Agent 应用层的护城河不是模型微调,而是上下文工程。他们上一个产品因为死磕模型训练,一个“训练-评估”周期要 1 到 2 周,产品迭代速度被活活拖死;而这一代产品把赌注压在上下文工程上,几个月内重构了 5 次,反而活了下来。

这个判断对做 Agent 的开发者来说非常实用。上下文工程要解决的核心矛盾是 LangChain 创始人提到的“上下文悖论”:Agent 要完成复杂任务,必须大量调用工具来获取上下文,典型任务大约 50 次工具调用;但上下文越长,模型性能越差,成本呈指数上升。即使你用的是 100 万 Token 窗口的模型,处理到 128K 到 200K 附近时,性能就开始“腐烂”,出现重复、缓慢、质量下降。所以问题不在于窗口够不够大,而在于你有没有一套机制,在上下文腐烂之前主动给它“瘦身”。

这篇文章面向 AI Agent 开发者和架构师,我会把 Manus 那套上下文工程的思路拆成可复制的配置骨架,给你 settings.json 和 config.toml 两份示例,再带你一步步验证压缩、摘要、卸载、隔离这几个动作到底怎么落地。你不需要微调模型,也不需要自己训一个,只要把上下文调度做对,Agent 的稳定性和成本就能明显改善。下面先从 TaoToken 的接入准备讲起,因为后面的验证请求需要一个稳定的模型调用入口。

2. TaoToken 前置准备:拿到模型调用入口

上下文工程的验证离不开模型调用,我这边用的是 TaoToken 作为统一入口。它的作用是让你在一个地方管理模型调用和 API Key,不用在多个厂商之间来回切换配置。对于做 Agent 上下文实验来说,这点很重要,因为你可能要频繁对比不同模型在同样上下文策略下的表现,统一入口能省掉大量重复配置的时间。

你需要先拿到 API Key。打开 TaoToken 控制台,进入 API Keys 页面创建一个新的 Key,建议按项目命名,比如agent-context-lab,方便后面做用量区分。创建后把 Key 复制出来,放到环境变量里,不要硬编码进配置文件。

export TAOTOKEN_API_KEY="sk-你的key"

TaoToken 的 API 地址是https://taotoken.net/api,兼容 OpenAI 风格的调用方式,所以后面配置文件里我会直接用它作为 base_url。如果你还没注册,可以先到官网了解一下:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。注册后在控制台里能看到完整的接入文档和模型列表,建议先跑通一个最简单的对话请求,确认 Key 和网络都没问题,再进入上下文配置环节。

这一步不要跳过。我见过不少人直接上复杂配置,结果报错时分不清是 Key 问题、网络问题还是上下文逻辑问题,排查成本翻倍。先用最小请求验证通路,后面出问题就能快速定位。

3. 可复制的 Agent 上下文配置骨架

这一节是全文的核心。我把 Manus 那套上下文工程思路落成两份配置文件:一份settings.json负责运行时参数,一份config.toml负责策略定义。你可以直接复制到项目里改。

3.1 settings.json:运行时参数骨架

{ "model": { "base_url": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY", "name": "claude-sonnet-4-20250514", "max_output_tokens": 4096 }, "context": { "rot_threshold_tokens": 128000, "compact_ratio": 0.5, "keep_recent_tool_calls": 3, "offload_dir": "./agent_workspace/offload", "enable_compaction": true, "enable_summarization": true, "summarize_from_raw": true }, "isolation": { "enable_sub_agents": true, "max_sub_agents": 4, "sub_agent_context_limit": 32000 }, "cache": { "enable_kv_cache": true, "cache_ttl_seconds": 3600 } }

几个参数值得展开说。rot_threshold_tokens设成 128000,这是上下文腐烂的起点,到了这个值就触发瘦身。compact_ratio是 0.5,意思是压缩时只动最老的 50% 历史,保留最新 50% 的完整信息,这样模型还有新鲜样例可以模仿,不会行为错乱。keep_recent_tool_calls设成 3,保证最后几个工具调用的全量信息不被动,防止模型忘记自己刚刚在干什么。summarize_from_raw设为 true,摘要时用原始未压缩数据来总结,保证信息保真度。

3.2 config.toml:策略定义骨架

[context.offloading] enabled = true strategy = "file_reference" # 大输出只保留文件路径,内容落到 offload_dir max_inline_chars = 2000 [context.reducing] enabled = true order = ["compaction", "summarization"] # 先压缩,压缩收益变小才摘要 [context.retrieving] enabled = true method = "hybrid" # 语义检索 + 文件系统 grep 兜底 vector_store = "./agent_workspace/vectors" grep_tool = true [context.isolation] enabled = true mode = "sub_agent" # 复杂任务拆给子 Agent,各自独立窗口 [context.caching] enabled = true scope = "prefix" # 对稳定前缀做 KV 缓存,降低长上下文成本

这份配置的逻辑顺序是:先卸载,再精简,需要时检索,复杂任务隔离,全程缓存。Manus 的实践里特别强调“先压缩后摘要”,因为压缩是可逆的,信息只是被外置,零丢失;摘要是不可逆的,会彻底丢弃原文。只有在压缩收益也变小时,才万不得已触发摘要。这个顺序在order字段里体现出来了。

3.3 压缩与摘要的实现差异

压缩针对的是那些可以从外部重建的信息。比如一个工具调用返回{path: "file.txt", content: "..."},压缩后只保留{path: "file.txt"},内容留在文件系统里,Agent 需要时自己去读。摘要则是对历史信息做总结,彻底丢弃原文,释放空间最大但不可逆。

def reduce_context(messages, config): if count_tokens(messages) < config["rot_threshold_tokens"]: return messages # 第一步:压缩最老的 50% old, recent = split_history(messages, config["compact_ratio"]) compacted = [compact_tool_call(m) for m in old] # 第二步:压缩收益不足时才摘要 if count_tokens(compacted + recent) >= config["rot_threshold_tokens"]: summary = summarize(raw_history=old, keep_recent=config["keep_recent_tool_calls"]) return [summary] + recent return compacted + recent

这段代码是骨架,实际项目里你要根据自己的消息结构改。关键是那个判断顺序:先压缩,压缩后如果还是超阈值,才摘要。很多人反过来做,一上来就摘要,结果信息丢太多,Agent 后面任务直接跑偏。

4. 验证请求与成功结果

配置写好了,得验证它真的生效。我分三步走:先验证基础调用通路,再验证压缩触发,最后验证隔离。

4.1 基础调用验证

curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "回复 OK 两个字母"}], "max_tokens": 16 }'

返回里能看到choices[0].message.content是OK,说明 Key 和地址都对。这一步通了,后面才有意义。

4.2 压缩触发验证

构造一个超过阈值的对话历史,观察压缩是否被调用。你可以在代码里打日志:

messages = build_long_history(tokens=140000) result = reduce_context(messages, config) print("压缩前 token:", count_tokens(messages)) print("压缩后 token:", count_tokens(result)) print("是否触发摘要:", any(is_summary(m) for m in result))

预期结果是压缩后 token 明显下降,且如果压缩后仍超阈值,会看到摘要消息。如果压缩后没降多少,检查compact_ratio是不是设得太小,或者工具调用内容本身就不含可外置的大块信息。

4.3 隔离验证

给一个复杂任务,看是否拆给了子 Agent:

task = "分析这份 5 万行日志,找出所有超时请求并按接口分组统计" result = run_with_isolation(task, config) print("子 Agent 数量:", result.sub_agent_count) print("主 Agent 上下文峰值:", result.main_context_peak)

成功的话,子 Agent 数量大于 1,主 Agent 上下文峰值远低于单 Agent 跑同样任务的峰值。这说明隔离生效了,每个子 Agent 只处理自己的小窗口,互不干扰。

5. 本篇常见错排查

5.1 压缩后模型行为错乱

现象是 Agent 开始重复动作或者答非所问。大概率是keep_recent_tool_calls设得太小,模型没有新鲜样例可模仿。把它调到 3 到 5 之间再试。另一个可能是压缩时把最新 50% 也动了,检查compact_ratio是不是设成了 1.0。

5.2 摘要后信息丢失严重

如果摘要后 Agent 完全忘了任务目标,检查summarize_from_raw是不是 false。用压缩后的数据去摘要,保真度会差很多。另外摘要 prompt 里要明确保留任务目标、当前进度、待办事项这三类信息。

5.3 卸载后检索不到

文件路径保留了,但 Agent 去读的时候找不到。检查offload_dir是不是相对路径导致工作目录变化后失效,建议用绝对路径。另外确认检索工具(grep 或语义搜索)真的被注册进了工具列表,不然 Agent 不知道怎么取回。

5.4 隔离导致子 Agent 结果对不上

子 Agent 各自独立窗口,如果任务拆分边界不清晰,结果会互相矛盾。拆分时保证每个子任务有明确的输入和输出契约,主 Agent 只做汇总不做二次推理。max_sub_agents不要设太大,4 个左右比较稳,太多反而增加协调成本。

5.5 缓存没生效成本没降

KV 缓存对前缀稳定性要求高。如果你的 system prompt 或工具定义每次都在变,缓存命中率会很低。把稳定不变的部分放前面,变动部分放后面。TaoToken 的接入文档里有关于缓存前缀的说明,可以对照检查。

6. 把上下文工程变成你的 Agent 护城河

回到开头那个判断:应用层的护城河是使用模型的能力,也就是上下文工程。Manus 重构 5 次,最大的飞跃不是加了更花哨的技巧,而是简化和移除不必要的层。这套配置骨架你可以在本地跑起来,先验证压缩和摘要的顺序,再验证隔离和缓存,逐步把 Agent 的上下文调度做稳。

如果你在接入或排障过程中遇到问题,建议先到 TaoToken 的 API Keys 页面确认 Key 状态,再对照接入文档检查 base_url 和请求格式:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。想直接对比不同模型在同样上下文策略下的表现,可以用模型对话页面快速试:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 。如果你打算长期做编码类 Agent 或者多 Agent 编排,Coding Plan 会更适合,能省掉不少调用管理上的琐事:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。

最后留一个我自己的经验:上下文工程的目标不是让系统更复杂,而是让模型的工作变得更简单。你删掉的每一段冗余上下文,可能比加进去的任何技巧都更值钱。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询