模型负责聪明,工程负责让聪明可靠

写在前面

Hi,好久不见,距离上次写文又过去了半年啦。这半年又有一些实践和想法,想整理一下,和大家交流~

上一篇总结还是去年底写的,那时候关于智能化相关的实践更多在「探索可使用阶段」。把多智能体、知识库、上下文工程这些能力搭起来,让业务流程跑通。能出结果。

但是,这半年做的事情是"爬楼梯"式的探索最佳实践。不再是「让它能跑」,而是想尝试着回答一个很实际的问题:一套依赖大模型的系统,怎么才能让业务团队敢放心用?

上半年做了哪些事呢?落地了一些或许对于目前我遇到的业务场景可能是最佳实践的技术方案:DAG 编排引擎、Harness、ReAct、协调者---多智能体、令牌桶限流、两级产出校验、统一事件流协议......。

所以这篇文章,主要想聊一聊上半年做的这些能力项:用了什么技术、为什么这么设计、踩过什么坑、最后怎么解的。

主要的价值大概汇总成三点:

  • 让 AI 真正懂业务------提示词工程、知识工程、记忆管理、规划能力,把业务领域知识、任务意图、历史上下文精准喂到模型面前;
  • 让 AI 真正会干活------编排骨架、智能体循环、ReAct、思维链、DAG、多智能体、技能抽象、协议接入、函数调用、工具使用,把一个复杂任务从头做到尾;
  • 让 AI 真正靠得住------事件流协议、反思自省、安全护栏、可观测、评估体系,让每一步说得清、拦得住。

OK,那接下来,就开始正文了~

先说清楚:做的到底是什么

目前做的平台一直是for业务同学的,就是研发和测试。整体的产品核心是:把业务同学「理解需求 → 测试分析 → 编写用例 → 自动化执行 → 集成发版」这条又累又重复的链路,交给 AI 来做。

这一整个的背后是一个编排与执行引擎,提供 n 个专业化能力(技能):从接口 / App / Web 用例的自动生成,到需求预处理、领域分析、测试范围划定、用例评审、文档与图片解析、需求/代码变更影响分析(产品功能 / 后端 / 前端 / 资金安全等)、新用例推荐、物料、环境、n个内部工具推荐。

然后,整套系统是双引擎结构:一侧是确定性的编排引擎(DAG 编排 + 技能管理 + Harness),负责「按步骤把活干完」;另一侧是探索性的推理引擎(ReAct 循环 + 意图理解 + 知识检索),负责「搞清楚用户到底想干嘛,动态决定下一步」。概括来说:确定性任务走 DAG 编排,探索性任务走 ReAct 推理,两者正交互补。

然后整个系统的难点是:大模型本质是个概率生成器,会超时、会限流、会空返回、会幻觉、会「说自己成功了但文件根本没落盘」。那怎么在这种不确定性之上,搭出一套稳定、说得清、还能持续扩展的生产系统,这就是上半年投入真正在解的题。还有,就是token的成本控制!

让 AI 真正「懂业务」

一个通用大模型,对我们的业务规范、内部术语、私有系统一无所知。想让它变成业务专家?核心就一件事:在有限的上下文窗口里,把领域知识、任务意图、历史状态,按对的顺序、对的时机,精准喂给它。 这一域覆盖四项能力:提示词工程、知识工程、记忆管理、规划能力。

提示词工程:Prompt / Spec 双文件 + 渐进式上下文

同一句「帮我分析这个需求」,换个措辞,模型输出质量可能天差地别。对一个要交付的产品来说,这种波动是致命的。这里做的第一件事,就是将散落在工程代码不同角落的提示词,整理成一套工程化的资产

两个设计:

Prompt / Spec 双文件分离。 每个能力拆成一对文件:.prompt.md 管「怎么想」(角色设定、分析流程、领域规范引用),.spec.md 管「输出长什么样」(结构化的格式规格)。为什么要拆?因为这两者的变更频率和变更人完全不同。产品同学想调输出格式,不该被迫去理解推理逻辑;更关键的是,.spec.md 后续还要被产出校验环节复用(下游拿它反向校验模型输出合不合规),格式约束混在 prompt 里,校验逻辑就没法独立引用了。合在一起,改格式必然误伤逻辑。

渐进式上下文注入。 所有材料不能一股脑塞满 context,得严格分层:第一层 SKILL.md 核心指令(最关键,第一个注入)、第二层预加载参考文档(规范 / 领域知识,减少运行时的 Read 调用)、第三层本轮必需的输入(需求文档、接口列表)、第四层共享上下文补充。为什么分层?一次性塞满会稀释关键指令、浪费 token、让模型抓不住重点;分层之后,协调者只读 1-2 层、不碰大文件,把大文件的消化留给子专家。像 App 页面分析,分别给 UI、状态机、决策表、工作流、交叉覆盖五个维度各写了独立的分析视角提示词,用模板渲染注入运行时变量(项目名、需求内容、接口列表)。

沉淀规矩:提示词禁止内联进代码。散落的字符串无法 diff、无法 review、改一处漏一处。这是最不值得踩的坑。

知识建模 → 注入 → 验证的闭环,多维向量融合检索

模型它自己是不懂「什么是资金安全变更」「接口断言该怎么写」,也不能指望它凭空长出这些判断力。先澄清一个常见误解:知识工程 ≠ RAG。 RAG 只是「从知识库检索片段注入 Prompt」这一个环节,完整的闭环应该是:知识建模 (怎么组织)→ 知识注入 (何时喂入)→ 知识验证(输出是否合规)。

知识分成四层建模:domain-knowledge/(业务概念、交互模式、术语表)、specs/(Markdown / PyTest / TestNG 等输出格式规范)、rules.md(命名规则、优先级标注、禁止事项等行为边界)、examples/(Few-shot 标准样例)。为什么要分四层?为了按需组合注入。有些任务要领域知识但不要 PyTest 规范,分层后就能精确供给,不浪费 token。

检索侧做了两个升级:一是把关键词检索换成了 BGE 向量语义检索 。用户搜「下单流程」,关键词命中不了「购物车结算」,但语义向量可以实现领域术语的同义表达(「退款」=「退货还款」)召回率显著提升;二是多维向量融合 。Word2Vec 抓词级术语精确匹配、Sentence-BERT 抓句级语义相似、Doc2Vec 抓文档级主题匹配,单一向量覆盖不全的场景,融合后按场景选维度或综合打分。Few-shot 这里强调一条原则:必须用真实可执行的标准样例。因为 LLM 会忠实复刻例子里的一切细节,你给的例子有瑕疵(断言不全、格式不对),它会连瑕疵一起学。

最终效果呈现:断言、格式规范、术语都更匹配业务了。

记忆管理:工作记忆 / 共享黑板 / 会话状态隔离

一个复杂任务跨多轮、多角色协作,记不住上文、或者不同任务的上下文互相污染,产出就会前言不搭后语、时好时坏。所以会话状态做了三层处理:

工作记忆 单次推理循环期间的短时状态,用一个结构化的 AgentMemory(明确的 dataclass 而非大字典,字段清清楚楚,后续维护者不会读到脏数据)承载 user_query、analysis_results、loop_history、remaining_tasks 等,让循环里的「思考---行动---观察」能连贯传递。每一轮还落一个 LoopState 快照(第几轮、思考、动作、观察、反思、状态),反思模块靠它回看历史、避免重复动作,调试时也能回溯是哪一轮开始跑偏。

共享黑板 多个协作节点之间的跨节点状态,用的是 BlackBoard 黑板模式:每个节点执行完,outputs 自动 merge 到共享上下文,下游节点直接 ctx.get(key) 读,零拷贝。节点间靠内存引用共享,不需要把大对象反复序列化 / 反序列化。就像教室里的一块黑板,做完写上去,后面的人直接读,不用互相传递信息。

会话隔离 不同用户、不同任务之间用独立 session 隔开互不串扰。历史上下文则按 token 预算裁剪,只带最近约 6 条(约三轮对话):足够理解近期语境,又不会撑爆窗口挤占关键指令的空间。如果需要知道全局,历史会话的上下文压缩,Compact 做好处理即可。

规划能力:粗规划 + 细执行的分层,意图驱动的 Pipeline 选择

用户一句模糊的话进来,系统得先判断「他到底想干嘛」,再决定走哪条链路。判断错了,后面全错。这里需要一个原则:粗规划 + 细执行分层,绝不一上来就规划到最细粒度。

粗规划层,由 UnderstandingEngine 意图理解引擎在 Pipeline 执行前工作。用思维链推理理解用户真实意图,从 n 条 Pipeline 里选中正确的那条,并抽取出需求 ID 等参数(比如判断该走 App 还是 接口)。细执行层,则是 ReAct 循环每一轮 Think 重新评估当前状态,由反思模块动态决定下一步。

为什么要分层?因为一开始就把计划做到最细,那么中途任何一个变量一变,整个计划全盘作废、得重来。所以,粗粒度定方向,细粒度定步骤。

这样的话,用户可以不用懂系统内部有多少条链路,说人话即可,系统自己选对路、排好序。

让 AI 真正「会干活」

懂业务只是门票,真正拉开差距的是干活。一个测分任务,往往要读需求、拆维度、并行分析、调用内部系统、生成用例、再合并去重。这是一整套复杂的「干活」流程。这一域是整套系统最厚的部分,设计了多个能力:编排骨架、智能体循环、推理行动、思维链、有向无环图编排、多智能体、技能抽象、模型上下文协议、函数调用、工具使用

编排骨架:Harness 与 DAG

早期做法是让一个 Agent 从头到尾把任务干完。它容易迷路、超时、上下文越滚越长,出了问题去捞日志简直是灾难。所以第一件事:在模型之外搭一层 Harness(执行骨架),把「谁来干、干什么、按什么顺序、拿什么输入、产出谁校验、失败怎么退避、限流怎么控」这些编排关注点,从模型手里收回到工程侧统一管理。

关键在于 Harness 与 DAG 是正交的两层:DAG 只回答「节点之间的依赖与顺序」,Harness 横切在每个节点执行的前后,负责重试、限流、会话隔离、上下文注入、产出校验。不管节点内部跑的是分析、生成还是评审,这些事都由 Harness 统一兜底。这么切分的好处就是:模型只负责「想」,连自己该按什么顺序想都不用操心;骨架负责「组织」,组织逻辑对所有节点复用。这层 Harness 是后面所有协作能力的基础。

智能体循环:ReAct + 双层循环 + CoT 推理

模型一旦开始「思考」就是个黑盒,你不知道它想到哪一步、会不会停不下来。所以把 Agent 的工作过程显式建模为 ReAct 循环:Think(想下一步该干什么)→ Act(执行一个动作)→ Observe(观察结果)→ Reflect(反思要不要继续) ,每个阶段都是可观测、可干预的节点。并且 maxTurns 根据不同阶段和场景动态控制轮次,防止无限循环、浪费 token。

这里有几个设计权衡:

Think 分首轮和后续:首轮做一次完整的思维链推理,把任务拆透;后续轮次基于已有记忆做简短思考,不必每轮都从零重新推理,省 token 也省时间。

决策交给模型、护栏兜底 :每一轮 Think 让模型输出结构化 JSON {action, params, reasoning}。action 必须落在 Action 的白名单内(树操作、三类分析、生成、评审、扩充),越界或非法就由安全护栏强制纠正。简单说:让模型可以自主判断,但不让它自由发挥。

双层循环:外层是 Harness 的调度循环,内层是 ReAct 的推理循环,两层各自计数、各有上限。CoT 本质就是 ReAct 里 Think 阶段的展开,把它流式吐出来,用户实时看到「它在分析哪个接口、为什么这么判断」。黑盒变成了透明的、每一步分析执行的过程都是可视的。

有向无环图编排:执行模式 + 拓扑排序 + 并发控制

一个 App 用例任务要从多个维度分析,串着做太慢;每一类变更分析各自独立,串着做更浪费;而且只要中间一个环节挂了,串行流程就全盘皆输。所以把每个任务的执行流程声明成一张有向无环图 ,显式声明节点依赖,引擎自动做拓扑排序决定执行顺序,没有依赖关系的节点自动并行。还有一点:区分「调度节点」(只做编排、不调 LLM)和「执行节点」(真正调模型),省下大量不必要的模型调用。

执行模式有三种:serial(串行)、parallel(全并行、一败俱败)、parallelSettled(并行且失败隔离)。parallelSettledPromise.allSettled 收集所有结果,再按 majority 阈值判定(比如 4 个维度成功 3 个就算通过),单个维度挂了不拖垮整体。这是「宁可缺一角也要出东西」的产品取舍。

重点说说并发控制 。这里吃了很大的跟头。最初并行用最朴素的 Promise.all 一次性全发,结果五六个 Agent 在同一瞬间打满模型并发配额,直接触发 ConcurrentLimitError。后来上了三层叠加:1. maxConcurrency(默认 5)限制同时在跑的节点数;2. dispatchIntervalMs(默认 1000ms)在派发之间插错峰间隔,请求被平滑地一个个放出去,而不是瞬间并发;3. 用 AsyncLocalStorage 给每条并行链路做上下文隔离,避免并发时状态丢失和错乱。节点之间的数据用 BlackBoard 黑板模式零拷贝传递,不必层层透传。

多智能体:Coordinator-Worker + Map-Reduce

让一个 Agent 又懂 UI 又懂状态机又懂资金安全,结果就是谁都懂一点、谁都不精,还容易角色混淆、上下文互相污染。换个思路:Coordinator-Worker(协调者---工人)模式 :Coordinator 只负责调度和最后的结果合并、冲突消解,它只读前置生成的摘要、绝不亲自读大文件,保证自己轻装、不被撑爆。每个 Worker 是职责单一的子专家(UI 分析、状态机分析、决策表分析、工作流分析、交叉覆盖分析),各自拥有独立的 200K context 和独立 session(互不 resume 对方历史),在自己的大上下文里专注干一件事,物理隔离、互不污染。

多维度并行分析,本质上就是一次 Map-Reduce。Map 阶段是多路子专家并行产出,Reduce 阶段 Coordinator 把多路结果归并去重、消解冲突。落到数据上,多维并行不仅让分析更高效,而且每个子专家的产出质量因为「上下文纯净」反而更高。

技能抽象:Tool 、Skill + 注册-物化-执行

在实际业务中,如果多个能力各写各的,无法复用、无法发现、无法组合,加一个新场景就要从头拼一遍编排。所以把每个能力抽象成标准化的 Skill :这里简单的说明一下skill的概念,主要是为了让不了解的同学或者了解不多的同学能简单的理解这个概念。就比如说单个 Tool 是一把锤子,那 Skill 就是一整套「装修技能包」(锤子、钉子、图纸、施工规范都齐了)。这个技能包就是一个完全可插拔随时可用的一个可独立交付、可复用的能力单元。目录结构统一(index.js 入口 + nodes/ 节点 + resources/ 资源分离),提示词与代码分离,.prompt.md 管「怎么想」、.spec.md 管「输出长什么样」,后者还会被产出校验环节复用。

再往上建了一套云端技能市场,走注册 → 物化 → 执行 三段:技能先注册元数据、版本化管理;用到时按需物化 到执行环境(这一步用分布式锁 + Double-check 拿到锁后再查一遍是否已物化,保证并发下不重复拉取、不互相踩踏);最后执行。前端只需选一个技能名称,后端自动组装出完整执行流程。

协议 + 函数调用 + MCP 、Function Calling 、最小权限工具箱

干活嘛,AI 得能访问各种接口、平台、文档系统、代码仓库,能读写文件、能调起子专家。

接入侧用 MCP(模型上下文协议) 把内部服务标准化地接进来,支持 stdio / SSE / HTTP / SDK 四种传输方式。新工具只需在市场注册,无需改动 Agent 代码;配置按 mcpOverrides > request.mcps > manifest.mcpRefs 合并、自动加载。

但「能动手」又意味着风险:调错、滥用、乱来。

给 AI 一套受控规则:内置的读、写、执行、调子专家等基础工具,加按场景扩展的自定义工具;每个工具入参都带严格的 schema 约束 ;再用工具白名单/黑名单按最小权限 原则,只给每个角色它这次真正需要的工具。这里踩过一个坑:管理工具(TodoWrite)在一次任务里无效调用高达 55 次、白白浪费 120-200 秒和大量 token。发现这个之后,直接上了 disallowedTools 黑名单,无效调用从 55 次降到 0 。这也验证了一个原则:给 AI 的自由度不是越大越好,最小权限、按场景分层授权,产出反而更稳、也更省 Token。

让 AI 真正「靠得住」

懂业务、会干活了,但能不能让人放心?这才是最后一块拼图 可靠。一套要给业务团队天天用的系统,用户大多容忍不了「有时候行、有时不行」。

这里覆盖四个能力:反思自省、安全护栏、可观测性、评估体系。它们不增加模型的聪明,但决定了这份聪明能不能稳定、便宜、说得清地落到用户手上。

反思自省:ReAct 的 Reflect,让 AI 知道「什么时候该收手」

AI 不知道任务什么时候算完成,要么早早停手漏掉覆盖,要么反复自我确认停不下来白白烧掉Token,还容易越干越偏离最初目标。

反思本质是 ReAct 循环里的 Reflect 阶段 。这里设计了两级:先跑快速完成检查 ,用轻量规则判断产出是否明显完整。约 70% 的任务在这一级就能被判定完成、免掉一次 LLM 调用;只有拿不准的才进深度反思 ,让模型对照「用户最初的目标」做结构化自省,输出 {完成度, 是否需用户补充, 该继续还是收手}。反思时同步做产出校验,识别「明显被截断的半成品」。

关键在于对照的是用户最初的目标,不是当前这一轮的局部产出 这样才防得住「越干越偏」。落地后产出缺失率从 30% 降到约 5% ,无效 token 浪费减少约 40%

安全护栏:给能力极强但没分寸的 AI 立好边界

这里可以把 AI 当成一个能力极强、但没有分寸感的实习生。它会跳过分析直接下结论、会滥用工具、会在缺材料时硬编。这样在系统设计中肯定是不太能接受的一件事,所以得给它明确的边界。也就是需要 护栏 来设防:

maxTurns 循环轮次上限 防无限打转

disallowedTools 工具黑名单 比如禁掉 TodoWrite------它曾经一次任务白烧 55 次调用、120~200 秒,禁掉后归零

PrerequisiteCheckNode 前置检查 ,拦住「材料没齐就往下干」,而且缺材料时 不硬编、区分材料类型分别引导用户去补齐;挡住半成品

允许 Say No 干不了就明说,不糊弄。

重试也讲分寸:错误可以分成「瞬态」和「确定性」两类。超时、限流这种再试一次可能就好,用 指数退避 2s→4s→8s 重试;而模型内部报出的 确定性错误 ,再试三次还是同样失败,就立即短路、不必浪费时间。

这里分享一个越做越坚定的信念:给 AI 划边界,不是在「限制」它,而是在「成就」它。自由不等于智能,利用好合适的分寸。

可观测性:把黑盒,一点点变成白盒

AI 系统天然是黑盒,出了事只能靠猜。这放在生产环境是不可接受的。

全链路埋点 事件贯穿始终,每一步都能靠 seq 追溯到序号。关键指标被 Metrics 量化采集 比如某个建模能力被量化出「一次任务读了 35 次文件、浪费了几百 KB 上下文」这种以前完全看不见的浪费。日志分级、可按序回放;断线还能续传不丢事件。把非确定性的黑盒,变成一条可追溯的白盒链路。

价值很直接:出问题能精确定位到环节;以前「说不清哪里贵、哪里慢」,现在每一处浪费都有数字;用户断线重连也不丢中间产物。一句话:看不见的东西没法优化,量化是优化的前提。

评估体系:让「好不好」能被量化,不靠感觉

AI 产出质量如果只能靠人肉抽查感觉,就没法规模化、也没法持续改进。

两级校验,产出即校验 。为什么要两级?因为只看第一级,模型自己报告的状态「成功」 会被假成功 骗过:遇到过模型返回状态成功、期望的文件却根本没落盘,或者只写了个空文件。所以第二级是真去磁盘上确认文件在不在、是不是空的,空文件、空目录一律按缺失处理,把错误摁死在当场,不让它延迟到下游翻倍返工。

思考 & 体会

智能化的难,不在「智能」,在「工程」。

去年那篇总结里有说「工程能力才是核心竞争力」,当时还偏理论。这半年实打实验证了一点:一个本该执行却被静默跳过的环节、一处传输层的默认行为差异、一个从没被显式声明的身份。这些和「智能」毫无关系的细节,才是真正决定成败的东西。说到底,这半年最大的技术挑战:怎么在一个天生不可靠的大模型之上,搭出一套生产可用的系统。 模型可能超时、限流、空返回、幻觉、产出不落盘。它给的是「可能性」,工程决定这份可能性能不能稳定、便宜、可控地落到用户手上。模型负责聪明,工程负责让聪明可靠。

话说回来,如果让我重来一遍,有几件事我会更早做:编排骨架应该一开始就按可靠性设计,而不是被生产事故推着一块块补;工具调用的真实数据诊断应该更早做。「某个工具被滥用 55 次」是靠一次次的翻日志才发现的,凭直觉根本猜不到;产出校验更应该是第一优先级「假成功」这个坑。

用户不在乎你底层怎么改,只在乎好不好用。

整个上半年做的技术很多,但对用户来说,能感知到的就几件事:每次都出得来了、快了、AI 更懂测试也更专业了。至于底层的编排怎么重排、旋钮怎么拧、轮次怎么从数十压到个位数。用户一无所知,也不需要知道。技术指标是给自己看的,用户体验才是给用户的。做智能化,最终还是要回到「做一个好用的产品」这个原点。

最后

下半年重心会在 AI Native 方向~ 有更多实践心得了,年底再开一篇和大家聊聊吧~

一起往前走~

相关推荐
CoovallyAIHub2 小时前
Claude Code 被曝安全后门:Coco 给出了 AI 协作的另一种答案
agent
新知图书3 小时前
记忆能力的定义与内涵
人工智能·agent·ai agent·智能体
昵称好难啊4 小时前
1. Loop Engineering详解
llm·agent
饼干哥哥4 小时前
一夜之间,全世界的 Agent 能力提高了一个档次
设计模式·agent·代码规范
不一样的少年_5 小时前
不用框架,手搓 AI Agent:(一) 先让它跑起来
前端·后端·agent
程序员柒叔5 小时前
OpenCode 一周动态-2026-W28
人工智能·github·agent·opencode·hermes
亦暖筑序5 小时前
AgentScope-Java 入门:用 SSE 展示评审任务进度
java·agent·ai编程
leeyi5 小时前
Token 账单怎么看:给 Agent 加用量统计(第51篇-E37)
aigc·agent·ai编程
TrisighT6 小时前
Agent 流式响应你只拼 delta 就完事了?三个暗坑修完,白烧的 token 少了 68%
aigc·agent·ai编程