1. Agent 系统技术迭代的底层逻辑与核心命题
1.1 从“能跑”到“跑得稳”:2026 上半年 Agent 系统的分水岭
2026 年上半年的 Agent 系统迭代,跟过去两年那种“堆功能、拼 Demo”的玩法已经完全不是一回事了。我自己的感受是,从今年年初开始,圈子里讨论的重点明显从“你的 Agent 能做什么”转向了“你的 Agent 在连续跑 200 步之后还能不能保持一致性”。这个转向背后其实是一个很朴素的事实:Agent 的能力上限,不再由模型本身决定,而是由 harness 工程决定的。
所谓 harness,你可以把它理解成 Agent 的“骨架 + 神经系统”。模型是大脑,但大脑再聪明,如果没有一套稳定的骨架去承接它的输出、管理它的上下文、约束它的工具调用,那这个 Agent 就是个只会说漂亮话的摆设。2026 上半年最显著的变化就是,harness 从“胶水层”升级成了“核心工程层”。以前大家写 Agent,harness 部分可能就是几十行 while 循环加几个 if-else;现在一个生产级 Agent 的 harness 代码量动辄上千行,里面涉及上下文压缩策略、记忆分层、工具循环的异常恢复、并发控制、安全边界等等。
为什么会有这个变化?因为大家踩的坑够多了。早期做 Agent 的人都有过这种经历:Demo 里跑得好好的,一上生产环境,用户多问几轮就开始胡言乱语,工具调用失败一次整个链路就崩了,上下文一长模型就开始“失忆”。这些问题的根源都不在模型,而在 harness 没有做好状态管理和错误恢复。所以 2026 上半年的迭代,本质上是一次“工程补课”——把过去欠下的工程债还上。
1.2 上下文管理:Agent 系统的“呼吸系统”
上下文管理这个词,在 2026 上半年被讨论的频率极高,但很多人对它的理解还停留在“截断”和“摘要”这两个动作上。实际上,一个成熟的上下文管理系统更像人的呼吸系统——它需要持续地吸入新信息、呼出无用信息,同时保持内部环境的稳定。
我自己的项目里,上下文管理经历了三个阶段。第一阶段是“暴力截断”,就是超过 token 限制就把最早的消息删掉,简单粗暴但效果很差,因为早期消息里往往包含关键的任务定义和约束条件。第二阶段是“滑动窗口 + 摘要”,保留最近 N 轮对话,把更早的内容压缩成一段摘要。这个方案好一些,但摘要本身会丢失细节,而且摘要的质量高度依赖模型能力。第三阶段,也就是 2026 上半年主流方案,是分层上下文管理:把上下文分成“系统层”“任务层”“会话层”“临时层”四个层级,每个层级有不同的生命周期和压缩策略。
系统层是 Agent 的身份定义、能力边界、安全规则,这部分永远不压缩,永远放在最前面。任务层是当前任务的描述、目标、约束,任务切换时才更新。会话层是用户和 Agent 的交互历史,按轮次做滑动窗口,超出部分做结构化摘要。临时层是工具调用的中间结果、检索到的文档片段,这部分生命周期最短,用完即弃。这种分层的好处是,每一层可以独立管理,不会因为临时信息的膨胀而挤占核心指令的空间。
实操心得:分层上下文管理的关键不是分层本身,而是层与层之间的“晋升”和“降级”规则。比如一个临时层的工具结果,如果被多次引用,就应该晋升到会话层;一个会话层的约束,如果被反复违反,就应该晋升到系统层。这套规则需要根据具体业务场景调参,没有万能公式。
1.3 记忆系统:从“单次会话”到“跨会话连续性”
记忆和上下文是两回事,但很多人会混淆。上下文是单次会话内的信息管理,记忆是跨会话的信息持久化。2026 上半年,记忆系统的迭代方向非常明确:从“向量检索”走向“双网络记忆模型”。
早期的 Agent 记忆就是往向量数据库里塞对话记录,需要的时候做相似度检索。这个方案的问题在于,它只能做“联想式回忆”,没法做“精确回忆”。比如用户问“我上次说的那个项目截止日期是哪天”,向量检索可能返回一堆相关但不精确的片段,而用户要的是一个确切日期。所以 2026 上半年出现了“双网络记忆模型”的实践:一个网络是向量网络,负责语义联想和模糊回忆;另一个网络是结构化网络,负责精确事实的存储和查询。两个网络之间通过实体链接和事件索引做关联。
这个思路其实借鉴了认知科学里关于人类记忆的研究——人的记忆也分语义记忆和情景记忆。语义记忆是概念和事实,情景记忆是具体事件和经历。Agent 的双网络记忆模型,本质上就是在模拟这两种记忆的协同工作。我实测下来,这种方案在需要长期陪伴的场景(比如个人助理、教育辅导)里效果提升非常明显,用户会感觉 Agent “真的记得我”。
1.4 工具循环:Agent 的“手脚”如何不抽筋
工具循环是 Agent 执行任务的核心机制:模型输出工具调用请求,harness 执行工具,把结果返回给模型,模型继续推理或调用下一个工具。这个循环看起来简单,但实际工程里坑非常多。
2026 上半年工具循环迭代的重点是异常恢复和幂等性。早期 Agent 最怕的就是工具调用失败——网络超时、API 限流、参数错误,任何一种失败都可能导致整个任务链路崩溃。现在的做法是,harness 层对每个工具调用做“事务化”封装:记录调用前的状态、调用参数、调用结果,失败时根据错误类型决定是重试、降级还是回滚。同时,对于有副作用的工具(比如写文件、发请求),要求实现幂等接口,避免重试导致重复操作。
另一个重要迭代是工具循环的并发控制。当 Agent 需要同时调用多个工具时,怎么管理并发、怎么处理部分成功部分失败的情况,这些都是 2026 上半年工程实践里反复打磨的点。我自己的项目里用了一个简单的策略:把工具调用分成“可并行”和“必须串行”两类,可并行的用并发池执行,必须串行的按依赖顺序执行,任何一步失败都触发整个事务的回滚或补偿。
2. Harness 工程的核心细节与实操要点
2.1 Harness 和 Agent 的区别:别再混为一谈了
这个问题在 2026 上半年被问得特别多,因为很多新手一上来就搞混。我用一个类比来解释:Agent 是一辆车的整体,包括发动机、方向盘、座椅、音响;Harness 是这辆车的底盘和传动系统。你开车的时候感受到的是方向盘和油门,但真正决定这辆车能不能稳定跑高速的,是底盘和传动系统。
具体到技术层面,Agent 包含模型、提示词、工具集、harness 四个部分。模型是推理引擎,提示词是行为指南,工具集是能力扩展,harness 是运行时框架。Harness 负责的事情包括:上下文管理、记忆读写、工具调用的调度和执行、错误处理、状态持久化、并发控制、安全边界检查。你可以把 harness 理解成 Agent 的“操作系统”——模型是 CPU,工具是外设,harness 是内核。
为什么这个区分重要?因为很多团队在优化 Agent 的时候,把精力全花在换模型和调提示词上,忽略了 harness 工程。结果就是模型换了更贵的,提示词改了无数版,效果提升却非常有限。而真正做过生产级 Agent 的人都知道,harness 工程的质量,决定了 Agent 能力的下限;模型能力,决定了 Agent 能力的上限。下限不牢,上限再高也没用。
2.2 上下文压缩的三种策略与选择依据
上下文压缩是 harness 工程里最核心也最棘手的部分。2026 上半年主流的压缩策略有三种,我分别说一下适用场景和实操细节。
第一种是摘要压缩。把早期的对话内容用模型生成一段摘要,替换掉原始消息。这个策略的优点是压缩率高,能把几千 token 压到几百 token;缺点是摘要质量不稳定,而且摘要过程本身消耗模型调用。我的经验是,摘要压缩适合“会话层”的压缩,不适合“任务层”,因为任务层的约束条件一旦被摘要丢失,Agent 就会跑偏。
第二种是结构化提取。不是生成自然语言摘要,而是从早期对话里提取结构化信息——比如任务目标、关键实体、已完成的步骤、待办事项。这些结构化信息用 JSON 或表格形式存储,比自然语言摘要更精确,也更容易被模型理解。这个策略适合“任务层”的压缩,我自己的项目里任务层的压缩全部用结构化提取。
第三种是向量化归档。把早期对话做 embedding 后存入向量库,需要的时候通过检索召回。这个策略适合“临时层”的压缩,比如工具调用的中间结果、检索到的文档片段。这些内容不需要一直放在上下文里,但可能在后续步骤中被引用,所以归档到向量库,按需召回。
注意事项:上下文压缩的触发时机很关键。不要等到上下文快满了才压缩,那样会导致压缩过程本身没有足够的空间来生成摘要。我的做法是设置一个“水位线”,比如上下文使用率达到 70% 就触发压缩,留出 30% 的缓冲空间。
2.3 记忆写入的时机与去重逻辑
记忆系统的工程难点不在读取,而在写入。什么时候写、写什么、怎么写,这三个问题决定了记忆系统的质量。
写入时机方面,2026 上半年的实践共识是事件驱动写入,而不是定时写入或每轮写入。所谓事件驱动,就是当对话中出现“值得记住”的信息时才触发写入。什么算“值得记住”?我的判断标准是三条:第一,包含用户偏好或个人信息;第二,包含任务的关键决策或结论;第三,包含可复用的知识或经验。这三条满足任意一条,就触发记忆写入。
写入内容方面,不要存原始对话,要存结构化记忆单元。一个记忆单元包含:时间戳、主体、事件类型、内容摘要、关联实体、置信度。比如“用户说他下周三要去北京出差”这条记忆,结构化后就是:时间戳、主体=用户、事件类型=行程、内容=下周三去北京、关联实体=北京、置信度=高。这种结构化存储的好处是,检索时可以精确匹配,也可以做时间范围查询和实体关联查询。
去重逻辑方面,这是很多人忽略的点。如果不做去重,同一个信息会被反复写入,导致记忆库膨胀和检索噪声。我的做法是,写入前先做一次相似度检查,如果已有记忆单元与新单元相似度超过阈值(我一般设 0.85),就做合并更新而不是新增。合并时保留最新的时间戳和最高的置信度,内容做增量更新。
2.4 工具循环的异常分类与恢复策略
工具循环的异常处理,我把它分成四类,每类有不同的恢复策略。
第一类是瞬时异常,比如网络超时、API 限流。这类异常的特点是重试就能成功。策略是带退避的重试,第一次等 1 秒,第二次等 2 秒,第三次等 4 秒,最多重试 3 次。重试时要注意幂等性,对于有副作用的工具,重试前要检查上一次调用是否已经生效。
第二类是参数异常,比如模型生成的工具参数格式错误、缺少必填字段。这类异常重试没用,需要把错误信息返回给模型,让模型修正参数后重新调用。策略是“错误反馈循环”:把工具返回的错误信息作为观察结果加入上下文,模型看到错误后会调整参数。
第三类是逻辑异常,比如工具返回的结果与预期不符、任务目标无法达成。这类异常需要 harness 层做判断,决定是继续尝试、切换工具还是终止任务。策略是设置“最大尝试次数”和“备选工具链”,超过次数就降级到备选方案。
第四类是系统异常,比如 harness 自身崩溃、状态丢失。这类异常需要状态持久化和恢复机制。策略是每个工具调用前后都做状态快照,崩溃后从最近的快照恢复,重新执行未完成的步骤。
| 异常类型 | 典型场景 | 恢复策略 | 重试上限 |
|---|---|---|---|
| 瞬时异常 | 网络超时、限流 | 退避重试 | 3 次 |
| 参数异常 | 参数格式错误 | 错误反馈循环 | 2 次 |
| 逻辑异常 | 结果不符预期 | 备选工具链 | 1 次 |
| 系统异常 | harness 崩溃 | 状态快照恢复 | 1 次 |
3. 实操过程与核心环节实现
3.1 从零搭建一个带记忆的 Agent Harness
这一节我把自己搭建 Agent harness 的完整流程拆开讲,你可以直接参考这个结构去实现。
第一步是定义状态结构。Harness 的核心是状态管理,所以首先要定义清楚 Agent 的状态包含哪些字段。我的状态结构一般包含:会话 ID、用户 ID、当前任务描述、上下文分层数据、记忆引用、工具调用历史、错误记录、执行步骤计数。这个状态结构要能被序列化,方便持久化和恢复。
第二步是实现上下文管理器。上下文管理器负责维护四个层级的上下文数据,并提供“获取当前上下文”和“更新上下文”两个接口。获取上下文时,按系统层、任务层、会话层、临时层的顺序拼接,总 token 数超过阈值时触发压缩。更新上下文时,根据信息来源决定写入哪个层级。
第三步是实现记忆管理器。记忆管理器负责记忆的写入、检索和更新。写入时做结构化提取和去重检查,检索时支持向量检索和结构化查询两种模式,更新时做合并和置信度调整。记忆管理器需要和上下文管理器协作:检索到的记忆作为临时层内容注入上下文,上下文中的重要信息触发记忆写入。
第四步是实现工具调度器。工具调度器负责工具注册、参数校验、调用执行、结果处理和异常恢复。每个工具注册时要声明:工具名称、功能描述、参数 schema、是否有副作用、是否幂等、超时时间。调度器根据这些元数据决定调用策略和恢复策略。
第五步是实现主循环。主循环是 harness 的入口,流程是:加载状态 -> 构建上下文 -> 调用模型 -> 解析输出 -> 如果是工具调用则执行工具并更新状态 -> 如果是最终回答则返回结果 -> 循环直到任务完成或达到最大步数。
# 主循环的简化伪代码 def agent_loop(session_id, user_input): state = load_state(session_id) state.context.update("session", user_input) while state.step_count < MAX_STEPS: context = context_manager.build(state) output = model.generate(context) if output.type == "tool_call": result = tool_scheduler.execute(output.tool, output.params) state.context.update("temp", result) state.tool_history.append(output.tool) elif output.type == "final_answer": memory_manager.write(state) save_state(state) return output.content state.step_count += 1 return "任务超出最大步数限制"3.2 上下文压缩的参数计算与调优
上下文压缩的参数不是拍脑袋定的,需要根据模型窗口大小和业务特点来计算。我以 128K 窗口的模型为例,说一下我的参数设置逻辑。
首先留出 20% 的缓冲空间给模型输出,所以实际可用上下文是 128K * 0.8 = 102K token。然后四个层级的预算分配:系统层固定 2K,任务层固定 4K,会话层 40K,临时层 56K。会话层和临时层的比例是 40:56,接近 1:1.4,这个比例是根据我的业务特点调的——我的场景里工具调用结果比较多,所以临时层预算大一些。
压缩触发水位线设在 70%,也就是总使用量达到 71K token 时触发压缩。压缩时优先压缩临时层,临时层压缩到 50% 以下还不够就压缩会话层。压缩策略:临时层用向量化归档,会话层用结构化提取,任务层不压缩只更新。
调优的时候我建议关注两个指标:压缩频率和信息丢失率。压缩频率太高说明预算分配不合理,信息丢失率太高说明压缩策略太激进。信息丢失率的测量方法是,压缩后让模型回答一些依赖早期信息的问题,看准确率下降多少。我的经验是,信息丢失率控制在 5% 以内是可以接受的。
3.3 双网络记忆模型的落地实现
双网络记忆模型的落地,核心是解决两个网络之间的同步和关联问题。我的实现方案是这样的。
向量网络用轻量级向量库,存储记忆单元的 embedding 和元数据。结构化网络用关系型数据库,存储记忆单元的结构化字段。两个网络通过记忆单元 ID 做关联。写入时,先做结构化提取,生成记忆单元,然后同时写入两个网络。检索时,如果查询是模糊的(比如“我之前说过什么关于项目的事”),走向量网络;如果查询是精确的(比如“项目截止日期是哪天”),走结构化网络;如果查询是混合的,两个网络都查,然后做结果融合。
结果融合的策略是:结构化网络的精确匹配结果优先级最高,向量网络的语义匹配结果作为补充。融合时做去重和排序,排序依据是匹配度和时间新鲜度。我实测下来,这种双网络方案在长期陪伴场景里的记忆准确率比单向量方案提升了 30% 以上。
实操心得:双网络记忆模型的一个坑是“记忆冲突”。比如用户先说“我喜欢咖啡”,后来说“我戒咖啡了”,两条记忆都存进去了,检索时可能返回矛盾的结果。我的解决方法是给记忆单元加“时效性”字段,新记忆写入时检查是否有冲突的旧记忆,有的话把旧记忆标记为“已过期”,检索时默认不返回过期记忆。
3.4 工具循环的并发控制与事务化封装
工具循环的并发控制,我的方案是“依赖图 + 并发池”。先把所有待执行的工具调用构建成依赖图,没有依赖关系的工具可以并行执行,有依赖关系的按拓扑顺序执行。并发池的大小根据工具类型设置:IO 密集型工具并发数可以高一些(比如 10),CPU 密集型工具并发数低一些(比如 4),有副作用的工具并发数设为 1(必须串行)。
事务化封装的实现是:每个工具调用包装成一个事务对象,包含调用前状态、调用参数、调用结果、调用后状态。执行时先记录调用前状态,执行工具,记录调用结果和调用后状态。如果执行失败,根据错误类型决定回滚或补偿。回滚是把状态恢复到调用前,补偿是执行一个反向操作来抵消副作用。
class ToolTransaction: def __init__(self, tool, params, state): self.tool = tool self.params = params self.before_state = state.snapshot() self.result = None self.after_state = None def execute(self): try: self.result = self.tool.run(self.params) self.after_state = self.before_state.apply(self.result) return self.result except TransientError: return self.retry() except LogicError: return self.fallback() except SystemError: return self.rollback()4. 常见问题与排查技巧实录
4.1 Agent 记忆丢失的排查路径
记忆丢失是最高频的问题,我整理了一套排查路径,按顺序检查。
第一,检查记忆是否真的写入了。很多情况下是写入环节就失败了,比如结构化提取报错、去重逻辑误判、数据库连接失败。排查方法是看写入日志,确认每条记忆的写入状态。
第二,检查记忆是否被检索到了。写入成功但检索不到,通常是检索策略问题。比如查询走了结构化网络但记忆只存在向量网络,或者相似度阈值设得太高导致召回不足。排查方法是手动执行检索查询,看返回结果。
第三,检查检索到的记忆是否被注入了上下文。检索成功但模型没用上,可能是上下文注入位置不对,或者被后续的压缩操作挤掉了。排查方法是看模型调用时的完整上下文,确认记忆内容在不在里面。
第四,检查模型是否忽略了记忆。记忆在上下文里但模型没采纳,可能是提示词没有引导模型使用记忆,或者记忆的呈现格式模型不敏感。排查方法是调整提示词,明确要求模型参考记忆内容。
| 排查环节 | 检查点 | 常见原因 | 解决方法 |
|---|---|---|---|
| 写入 | 写入日志 | 提取失败、去重误判 | 修复提取逻辑、调整阈值 |
| 检索 | 检索结果 | 策略不匹配、阈值过高 | 调整检索策略、降低阈值 |
| 注入 | 完整上下文 | 位置不对、被压缩 | 调整注入位置、保护记忆 |
| 采纳 | 模型输出 | 提示词不引导 | 优化提示词、调整格式 |
4.2 工具调用死循环的终止策略
工具调用死循环是另一个高频问题:模型反复调用同一个工具,或者在不同工具之间来回切换,始终无法推进任务。我的终止策略是三层防护。
第一层是步数限制。设置最大执行步数,比如 50 步,超过就强制终止并返回当前结果。这个是最粗暴但最有效的兜底。
第二层是重复检测。检测最近 N 步内是否有重复的工具调用模式,如果有就触发警告。警告的方式是在上下文里插入一条系统消息:“检测到重复调用模式,请尝试不同的方法或终止任务。”很多时候模型看到这条消息就会调整策略。
第三层是进展评估。每执行几步就评估一次任务进展,如果连续多次评估都没有实质性进展,就触发终止。进展评估可以用模型来做,也可以用规则来做。我的做法是用规则:检查任务目标是否被推进、是否有新的信息产生、是否接近完成条件。
注意事项:终止策略的阈值设置要平衡。太松了死循环浪费资源,太紧了正常的多步任务被误杀。我的经验是,步数限制设为正常任务平均步数的 3 倍,重复检测窗口设为 5 步,进展评估间隔设为 10 步。
4.3 上下文膨胀的紧急处理方案
上下文膨胀是生产环境里的突发问题:某个请求导致上下文急剧膨胀,token 消耗飙升,响应变慢甚至超时。我的紧急处理方案是“三级熔断”。
第一级是软熔断:当上下文使用率超过 85% 时,触发强制压缩,把所有可压缩的层级压到最低。同时记录告警,事后分析原因。
第二级是硬熔断:当上下文使用率超过 95% 时,拒绝新的工具调用,只允许模型输出最终回答。如果模型无法输出最终回答,就返回当前已收集的信息并终止任务。
第三级是会话熔断:当同一个会话在短时间内多次触发硬熔断时,暂停该会话,要求用户重新开始或联系支持。这个是为了防止恶意请求或异常循环。
紧急处理之后要做根因分析:是某个工具返回了超大结果?是模型陷入了重复调用?是压缩策略失效了?找到根因后针对性修复,避免再次发生。
4.4 跨设备记忆同步的实操方案
跨设备记忆同步是 2026 上半年被问得很多的问题,尤其是“在一台电脑上的记忆配置怎么用到另一台电脑上”。我的方案是“中心化存储 + 本地缓存”。
中心化存储是把记忆库放在服务端,所有设备通过 API 读写。这样天然同步,但依赖网络。本地缓存是在每台设备上存一份记忆的副本,读写时先走本地缓存,异步同步到中心存储。这样离线也能用,但需要处理冲突。
冲突处理策略是“时间戳优先 + 手动合并”。两条记忆冲突时,时间戳新的优先。如果时间戳相同或无法判断,就标记为冲突,提示用户手动选择。我实测下来,大部分冲突都是可以自动解决的,只有少数需要人工介入。
实操心得:跨设备同步的一个隐藏坑是“记忆格式版本不一致”。不同设备的 harness 版本可能不同,记忆的存储格式可能有差异。我的做法是给记忆单元加版本号,同步时做格式转换,确保兼容性。
5. Agent 安全与并发扛压的工程实践
5.1 Agent 安全的三道防线
Agent 安全在 2026 上半年被提到了前所未有的高度,因为 Agent 开始有执行能力了——能写文件、能发请求、能操作数据库。一旦被恶意利用,后果比单纯的聊天机器人严重得多。我的安全方案是三道防线。
第一道是输入过滤。所有进入 Agent 的用户输入都要过一遍过滤,检测注入攻击、越权指令、敏感内容。过滤规则包括:关键词黑名单、正则模式匹配、模型分类器。模型分类器用来检测那些绕过关键词的变体攻击。
第二道是工具权限控制。每个工具都有权限等级,Agent 只能调用当前会话被授权的工具。权限控制基于最小权限原则:默认不给权限,需要时显式授权。授权可以基于用户身份、会话上下文、任务类型。
第三道是输出审查。Agent 的输出在返回给用户之前要过一遍审查,检测是否泄露了敏感信息、是否包含不当内容、是否符合安全策略。审查不通过的输出会被拦截或脱敏。
5.2 高并发场景下的 Agent 架构
Agent 怎么扛并发,这个问题的核心是“状态隔离”和“资源池化”。我的架构方案是这样的。
状态隔离方面,每个会话有独立的状态空间,会话之间不共享可变状态。共享的是只读资源,比如工具定义、提示词模板、记忆库的只读副本。这样会话之间不会互相干扰,并发安全性有保障。
资源池化方面,模型调用、工具执行、数据库连接都走连接池。连接池的大小根据资源类型设置:模型调用池大小等于并发会话数,工具执行池根据工具类型分别设置,数据库连接池按常规配置。池化的好处是资源复用,避免频繁创建销毁的开销。
限流和降级方面,每个用户有请求频率限制,超过限制就排队或拒绝。系统整体有负载监控,负载过高时触发降级:关闭非核心功能、降低模型调用频率、缩短上下文窗口。降级的目的是保证核心功能可用,牺牲非核心功能。
5.3 从单机到分布式的演进路径
Agent 系统从单机到分布式,我的演进路径分三步。
第一步是单机多进程。Harness 和模型调用分离,harness 跑在主进程,模型调用和工具执行跑在子进程。这样模型调用阻塞不会影响 harness 的响应。这个阶段适合日活几百的场景。
第二步是多机水平扩展。Harness 无状态化,状态存到共享存储(比如 Redis)。多台机器跑 harness 实例,前面加负载均衡。这个阶段适合日活几千到几万的场景。
第三步是微服务化。把上下文管理、记忆管理、工具调度拆成独立服务,各自独立扩展。服务之间通过消息队列通信,异步处理。这个阶段适合日活几十万以上的场景。
每一步演进都要解决一致性问题。单机多进程用进程间锁,多机水平扩展用分布式锁,微服务化用最终一致性。一致性方案的选择取决于业务对一致性的要求,强一致场景用分布式事务,弱一致场景用补偿事务。
5.4 性能监控与瓶颈定位
Agent 系统的性能监控,我关注四个核心指标:响应延迟、token 消耗、工具调用成功率、任务完成率。
响应延迟分两段:模型调用延迟和 harness 处理延迟。模型调用延迟取决于模型服务,harness 处理延迟取决于上下文管理和工具调度。定位瓶颈时先看是哪段延迟高,再深入排查。
Token 消耗分输入和输出。输入 token 高说明上下文管理有问题,输出 token 高说明模型输出控制有问题。我的经验是,输入 token 应该控制在窗口的 60% 以内,输出 token 应该控制在 2K 以内。
工具调用成功率低于 95% 就要排查,通常是工具本身的问题或参数生成的问题。任务完成率低于 80% 就要排查,通常是 harness 逻辑或提示词的问题。
实操心得:性能监控的一个关键是“基线”。没有基线就没法判断当前性能是好是坏。我的做法是系统上线后跑一周,收集正常情况下的指标分布,取 P50 和 P95 作为基线。后续监控时,P95 超过基线 20% 就告警。
6. 框架选型与工具链的取舍逻辑
6.1 Agent 框架选型的五个维度
2026 上半年 Agent 框架层出不穷,选型的时候我关注五个维度:上下文管理能力、记忆系统支持、工具生态、可观测性、扩展性。
上下文管理能力看框架是否支持分层管理和自定义压缩策略。记忆系统支持看框架是否内置记忆模块,还是需要自己集成。工具生态看框架是否有丰富的预置工具和工具注册机制。可观测性看框架是否提供日志、追踪、指标。扩展性看框架是否允许自定义组件和替换核心模块。
我的选型原则是:核心模块必须可替换,非核心模块可以用预置的。上下文管理和记忆系统是核心,必须能自定义;工具生态和可观测性是非核心,可以用框架自带的。这样既保证了核心能力的可控性,又降低了开发成本。
6.2 自研 Harness 还是用现成框架
这个问题没有标准答案,取决于团队情况和业务需求。我的判断标准是三条。
第一,业务是否有特殊需求。如果业务对上下文管理、记忆系统、安全控制有特殊要求,现成框架满足不了,那就自研。如果业务是通用场景,现成框架够用,那就用框架。
第二,团队是否有工程能力。自研 harness 需要较强的工程能力,包括状态管理、并发控制、错误处理、性能优化。团队如果没有这方面的经验,自研的坑会很多。
第三,长期维护成本。自研 harness 意味着长期维护,框架升级、bug 修复、功能扩展都要自己来。用现成框架则依赖社区维护,但可能受限于框架的设计。
我的经验是,早期用框架快速验证,验证通过后逐步替换核心模块。这样既享受了框架的开发效率,又保证了核心能力的可控性。
6.3 工具链的集成与适配
工具链集成是 Agent 落地的重要环节。我的集成方案是“适配器模式”:每个外部工具都写一个适配器,把工具的接口转换成 harness 统一的工具接口。适配器负责参数转换、结果转换、错误转换。
适配器的好处是解耦:harness 不关心工具的具体实现,只关心统一接口。工具升级或替换时,只需要改适配器,不影响 harness。适配器还可以做增强:比如给不支持幂等的工具加幂等包装,给没有超时控制的工具加超时控制。
工具链适配的一个常见坑是“参数 schema 不一致”。不同工具的参数格式可能不同,有的用 JSON,有的用表单,有的用命令行参数。适配器要统一转换成 JSON schema,方便模型理解和生成。
6.4 从 DeepSeek Harness 到通用 Harness 的迁移经验
DeepSeek Harness 在 2026 上半年被广泛使用,很多团队从它起步。我的迁移经验是:先并行运行,再逐步切换。
并行运行阶段,同一套业务逻辑同时跑在 DeepSeek Harness 和自研 Harness 上,对比两者的输出和性能。这个阶段主要是验证自研 Harness 的正确性和稳定性。
逐步切换阶段,按业务模块切换,先切非核心模块,再切核心模块。每个模块切换后观察一段时间,确认没问题再切下一个。切换过程中保留回滚能力,出问题能快速切回。
迁移过程中要注意的是“行为差异”。不同 Harness 对同一输入的处理可能有差异,比如上下文压缩策略不同、工具调用顺序不同。这些差异可能导致输出不一致。我的做法是定义一套“行为契约”,明确 Harness 应该满足的行为规范,迁移时验证新 Harness 是否符合契约。
7. 迭代方向与个人实践体会
7.1 2026 下半年的技术趋势预判
从上半年的迭代节奏看,下半年有几个方向值得关注。
第一是记忆系统的标准化。目前记忆系统各做各的,没有统一标准。下半年可能会出现记忆系统的接口标准,方便不同系统之间的记忆迁移和共享。
第二是Harness 的可观测性增强。目前 Harness 的调试主要靠日志,效率不高。下半年可能会出现专门的 Harness 调试工具,支持断点、单步、状态查看。
第三是安全控制的精细化。目前安全控制主要是粗粒度的权限控制,下半年可能会细化到“每个工具调用的每个参数”级别的控制。
第四是多 Agent 协作的工程化。目前多 Agent 协作还比较原始,下半年可能会出现成熟的协作框架,支持 Agent 之间的任务分配、结果汇总、冲突解决。
7.2 我踩过的三个大坑
第一个坑是上下文压缩过度。早期为了省 token,把压缩阈值设得很低,结果模型经常丢失关键信息,任务完成率很低。后来把阈值调高,留足缓冲空间,效果明显改善。教训是:省 token 不能以牺牲任务完成率为代价。
第二个坑是记忆写入太频繁。早期每轮对话都写记忆,导致记忆库膨胀,检索噪声大。后来改成事件驱动写入,只在关键信息出现时写,记忆质量大幅提升。教训是:记忆不是越多越好,而是越精越好。
第三个坑是工具循环没有超时控制。早期有个工具调用卡住了,整个 Agent 就挂在那里,直到人工干预。后来给每个工具调用加了超时,超时后自动终止并返回错误。教训是:任何外部调用都必须有超时控制。
7.3 给后来者的实操建议
如果你刚开始做 Agent 系统,我的建议是:先把 harness 做扎实,再考虑模型和工具。
Harness 做扎实的标准是:上下文管理稳定、记忆系统可靠、工具循环健壮、错误处理完善。这四个做到了,Agent 的基本盘就稳了。模型和工具是锦上添花,harness 是雪中送炭。
具体做法上,我建议从最小可用 harness 开始:一个主循环、一个上下文管理器、一个工具调度器。先跑通单轮对话和单工具调用,再逐步加记忆、加并发、加安全。不要一上来就搞大而全的架构,那样容易陷入过度设计。
最后分享一个我常用的调试技巧:把 harness 的每一步状态都打日志。上下文变化、记忆读写、工具调用、错误处理,全部记下来。出问题的时候,翻日志就能定位到具体哪一步出了什么问题。这个习惯帮我省了大量排查时间。