# 智能体测试系统架构: 多智能体协作与模型可替换设计 ```{contents} ``` 前几篇文章解决的是"怎么用 AI 做测试"([云服务测试的 AI 转型](./cloud-service-testing.md))和"怎么手写一个 Agent"([从0开始搭建一个 Agent](./agent.md))。这篇站高一层,回答一个架构问题:**如果要把这些 AI 环节固化成一个测试系统(有网站、有流水线、有多个智能体协作),架构上怎么设计,才能在外部 AI 日新月异——新模型、新架构范式、新交互协议层出不穷——的时候,做到快速切换而不是每次推倒重来?** 文章给出:一张总架构图、智能体之间如何交互、多个模型/架构下如何对接、从"只换模型"到"整体重构"的三档方案、以及记忆/RAG/存储/扩展/MCP 部署六个横向关切;再往外走一圈:内网已有系统(测试代码仓、执行机、历史记录、设计系统)怎么接入、知识怎么共享、系统怎么自我迭代、用户怎么开发插件,最后收拢为一份"永不变更"的不变量清单。 ## 总架构图 ```{mermaid} flowchart TB USER[用户 / 测试工程师] --> WEB[Web 界面 / CI 流水线] subgraph EXT[外部系统: 内网已有资产] DESIGN[设计系统
需求描述] CODE[测试代码仓] EXECREPO[执行机代码仓] HIST[历史测试设计/执行记录] end DESIGN -->|需求同步: 需求契约| ORCH HIST -->|一次性导入+增量同步| KM WEB --> ORCH[阶段编排层
七阶段 DAG, 契约流转] subgraph AGENTS[Agent 运行时: 角色能力接口的多种实现] R1[用例生成] R2[用例评审] R3[脚本生成] R4[失败分诊] end ORCH --> AGENTS AGENTS --> GW[模型网关
路由/限流/降级/灰度] GW --> M1[厂商模型 A] GW --> M2[厂商模型 B] GW --> M3[本地模型兜底] AGENTS <-->|检索知识 / 沉淀结论| KM[知识管理
git 文档库=事实源
RAG 索引=可重建
记忆库=复盘结论] AGENTS --> MCP[MCP 工具层
领域工具=HTTP 独立部署
环境工具=stdio 跟随] MCP --> EXEC[执行机 / 测试代码仓] MCP --> CASES[用例库 / 报告服务] AGENTS --> LOG[(会话日志 Trajectory
模型可见即可重建)] LOG --> EVAL[评测平台
golden 集回归 / 质量看板] EVAL -.质量反馈, 影子模式.-> ORCH EVAL -.定稿回流.-> KM ``` 这张图里每个箭头都对应后文一节:编排层与契约(一)、Agent 交互(二)、模型网关(三/7.5)、知识管理(7.1/7.2/九)、MCP 与执行机(7.6)、外部系统接入(八)、会话日志与评测平台(五/十)。 ## 结论先放在前面 1. **解耦的本质是"契约化"**:测试系统拆成需求理解 → 用例生成 → 评审 → 脚本生成 → 执行 → 分诊 → 报告七个阶段,阶段之间只传**结构化契约(JSON schema)**,不传对话历史、不传模型私有对象。契约稳定,内部实现随便换; 2. **智能体交互用三种拓扑就够**:流水线/DAG(流程已知)、编排者-工作者(任务需拆解)、生成-评审对抗(质量闭环)。不要发明第四种; 3. **对接多模型的关键是"能力接口 + 适配器"而不是"统一 API"**:OpenAI 兼容接口只统一了传输格式,模型之间的 context 长度、tool calling 能力、JSON 稳定性差异巨大,调度层必须按**能力声明**选模型; 4. **三档方案不是三选一,是演进而非跃迁**:先做方案一(配置级换模型,一周内),同时按方案二的接口边界写代码;方案三(平台级重构)等业务规模逼到眼前再做; 5. **测试系统有一个别的系统没有的优势:它自己就是测试专家**。给每个 AI 阶段建 golden 评测集,任何模型/架构替换后先跑评测再上线——用测试的方法测 AI,这是本文所有方案的共同底座; 6. **接入已有系统用"只读适配器,写回走评审"**:内网的测试代码仓、执行机、设计系统一律不改,系统以只读方式消费它们;AI 要改动它们时,产出 diff/MR 交人审,执行权限不外放; 7. **自我迭代必须"AI 提案、评测裁判、人盖章"**:AI 可以生成 prompt 修订建议、扩充 golden 集候选、清理知识库,但任何变更只有过评测门禁 + 人工合入才生效——防止系统自我强化式退化; 8. **可扩展的护城河是不变量**(十一):契约 schema、golden 集、知识事实源、审计日志、角色接口,这些永远不动;模型、框架、前端、部署形态随意换。 ## 一、先拆阶段: 解耦的对象是什么 解耦不是抽象口号,第一步是把"AI 参与测试"这件事拆成边界清晰的阶段。每个阶段满足一个约束:**结构化输入 → 结构化输出,像纯函数一样可被替换**。 ``` 需求文档/OpenAPI ──> ┌────────────┐ ┌────────────┐ ┌────────────┐ │ 1 需求理解 │──> │ 2 用例生成 │──> │ 3 用例评审 │ └────────────┘ └────────────┘ └────────────┘ 需求点清单 用例(编号化) 评审意见(分级) │ ┌────────────┐ ┌────────────┐ ┌────v───────┐ │ 7 报告生成 │<── │ 6 失败分诊 │<── │ 4 脚本生成 │ └────────────┘ └────────────┘ └────────────┘ 测试报告 分类+嫌疑 可执行脚本 │ ┌─────────v──┐ │ 5 用例执行 │ (传统测试框架, 非 AI) └────────────┘ ``` 两个关键设计决策: **第一,阶段间只传契约,不传过程。** 阶段 2 的输出是一组带编号、带优先级、预期结果有文档出处的用例 JSON,而不是"模型说过的话"。下游阶段永远面对确定性的结构化数据,上游换成任何模型、任何框架,下游无感。这就是 [DAG 那篇](./dag.md)说的"边 = 数据依赖"在系统级的推广——DAG 管内,阶段契约管外。 **第二,每个阶段的 prompt 模板与代码分离。** 模板进 git 仓库、评审合入(见[云服务测试的 AI 转型](./cloud-service-testing.md)的模板层),代码里只有"读模板 + 填槽 + 调模型"。换模型时大概率要调 prompt,调 prompt 不该动代码、不该发版。 ## 二、智能体之间如何交互 多智能体(multiple agents)不是目的,是单 agent 装不下时的自然结果——上下文有上限、工具集太杂会稀释注意力、生成与评审必须隔离。三种拓扑覆盖所有场景: ### 拓扑一: 流水线/DAG —— 流程已知的任务 七个阶段按依赖关系连成图,每个节点是一次 LLM 调用或普通函数,按拓扑序执行。这是测试系统的主骨架。 ```{mermaid} flowchart LR A[需求理解] --> B[用例生成] --> C[用例评审] C -->|通过| D[脚本生成] C -->|不通过| B D --> E[执行] --> F[失败分诊] --> G[报告] ``` 三个要点(完整论证见 [DAG 那篇](./dag.md)): - **节点即缓存单元**:换模型或调 prompt 只影响受影响节点,其余全部命中缓存,迭代成本从"全量重跑"变成"单点重跑"; - **回边显式化**:评审不通过回到生成,这条边画在图里,比藏在某段 if-else 里好审计得多; - **DAG 的边界要清楚**:流程未知的开放式探索(如"帮我查这个诡异的 flaky")套不进 DAG,该走下面的拓扑三。 ### 拓扑二: 编排者-工作者 —— 任务需拆解的场景 大模块的用例生成,单 agent 上下文装不下整个模块的 OpenAPI,拆成"编排者分派 + 多个工作者并行"([Agent 那篇](./agent.md)末尾提到的模式): ``` ┌─────────────┐ │ 编排者 Agent │ 读模块全景, 拆成子任务 └──┬───┬───┬──┘ 分派 │ │ │ 只传: 子任务描述 + 该子任务的输入契约 ┌────────v┐ ┌─v───────┐ ┌─────────┐ │ 工作者1 │ │ 工作者2 │ │ 工作者3 │ 各自只带自己需要的工具/文档 └────────┘ └─────────┘ └─────────┘ 结果回传(结构化), 编排者汇总校验 ``` 编排者与工作者之间的消息**走契约而非自由对话**:编排者下发 `{子任务, 输入JSON}`,工作者返回 `{产物JSON, 自检结论}`。这带来一个红利——工作者可以换模型甚至换框架(比如某个子任务特别难,从单次调用升级为带工具循环的完整 agent),只要返回的契约不变,编排者无感。 ### 拓扑三: 生成-评审对抗 —— 质量闭环 [多模型辩论](./multi-model-debate.md)和[结对编程](./pair-coding.md)已经论证过:生成与评审必须用不同模型/不同会话,否则"自己认可自己"。在测试系统里固化为: | 阶段 | 生成方 | 评审方 | 评审关注点 | |------|--------|--------|-----------| | 用例 | 通用强模型 | 另一厂商模型 | 遗漏、编造(预期结果是否有文档出处) | | 脚本 | 快/便宜模型 | 强模型 | 断言正确性、框架规范 | | 分诊 | 快模型 | 人 + 抽样强模型复核 | 分类准确性 | 评审方的输出也是契约: `{意见列表, 每条带证据引用 + 阻断/建议分级}`。生成方只处理契约内的意见,形成一个收敛循环(见[多模型辩论](./multi-model-debate.md)的"修订方不能照单全收")。 ```{note} 三种拓扑的共同点:**智能体之间不说"悄悄话",只说"公文"**。所有跨 agent 通信都是 schema 化的、可落盘的、可人读的。这既是可审计性的要求,也是后面一切"可替换性"的前提。 ``` ## 三、多个模型/架构下如何对接 ### 传输层: OpenAI 兼容 API 是事实标准 [本地 AI 服务那篇](./local-ai-service.md)已经建立的事实:llama.cpp / Ollama / vLLM 以及各云厂商 API 都实现了 OpenAI 兼容接口,`base_url + api_key + model` 三个参数就能切换后端。传输层用 OpenAI SDK 直连即可,不需要额外代理。 但**只统一传输格式远远不够**,这是最容易踩的坑:两个都"兼容 OpenAI 接口"的模型,能力可能天差地别。 ### 差异层: 能力声明,而不是模型名单 模型之间的真实差异(决定它能不能承担某个角色): | 能力维度 | 差异示例 | 影响哪个阶段 | |---------|---------|-------------| | context 长度 | 32K vs 1M | 需求理解阶段能否整本读文档 | | tool calling 稳定性 | 7B 小模型 JSON 经常输出畸形 | 能否跑 ReAct 循环(见 [Agent 常见失败表](./agent.md)) | | JSON mode / 结构化输出 | 有的只支持 prompt 约束 | 契约输出的解析失败率 | | 指令遵循 vs 创造力 | instruct 模型 vs 通用模型 | 评审要听话,头脑风暴要发散 | | 成本/速度档位 | flash 便宜快,pro 贵慢 | 成本分工(见[多模型辩论](./multi-model-debate.md)) | 所以对接层的设计是:**每个模型注册时声明自己的能力画像,调度层按"角色需要什么能力"选模型,而不是按"模型叫什么名字"硬编码**。 ```python # 模型注册表: 模型是数据, 不是代码 PROVIDERS = { "kimi": {"base_url": "https://api.moonshot.cn/v1", "key_env": "KIMI_API_KEY"}, "deepseek":{"base_url": "https://api.deepseek.com/v1", "key_env": "DEEPSEEK_API_KEY"}, "local": {"base_url": "http://localhost:8000/v1", "key_env": None}, # 见 local-ai-service.md } # 角色 → 能力要求 → 具体模型(配置化, 可热改) ROLES = { "case-generator": {"provider": "kimi", "model": "kimi-k2", "needs": {"json_mode": True, "min_context": 128000}}, "case-reviewer": {"provider": "deepseek", "model": "deepseek-v4-pro", "needs": {"reasoning": "high"}}, # 跨厂商评审, 盲区不重叠 "log-triage": {"provider": "deepseek", "model": "deepseek-v4-flash", "needs": {"cost": "low", "speed": "high"}}, } ``` ```python def call_role(role: str, prompt: str, **kwargs) -> str: """所有 AI 调用唯一入口。换模型 = 改配置; 代码永远只认角色名。""" cfg = ROLES[role] client = OpenAI(base_url=PROVIDERS[cfg["provider"]]["base_url"], api_key=os.environ[PROVIDERS[cfg["provider"]]["key_env"]]) return client.chat.completions.create( model=cfg["model"], messages=[{"role": "user", "content": prompt}], **({"response_format": {"type": "json_object"}} if cfg["needs"].get("json_mode") else {}), **kwargs).choices[0].message.content ``` ### 架构层: 能力接口,让"换架构"也成为配置 比换模型更深一层的是换**架构范式**:今天用"单次调用 + prompt",明天某个阶段可能需要"工具循环 agent",后天可能变成"多 agent 辩论"。如果调用方代码写死了"一次 chat.completions 调用",换范式就要改所有调用点。 解法是定义**角色能力接口**,每种范式是一个实现: ```python class CaseGenerator(Protocol): """用例生成角色的能力契约: 输入需求契约, 输出用例契约。 调用方只依赖这个接口, 不关心背后是单次调用、ReAct 循环还是多 agent。""" def generate(self, requirement: RequirementDoc) -> CaseSet: ... class PromptCaseGenerator(CaseGenerator): """实现A: 一条强 prompt 单次生成(现在的做法)""" class AgenticCaseGenerator(CaseGenerator): """实现B: 带工具循环的 agent——模型自己查 OpenAPI、翻历史用例、 不确定处标'需澄清'(机制见 agent.md 的 ReAct 循环)""" ``` 加上一个 factory 按配置装配,**换架构就从"重构"降级为"改配置 + 写一个实现类"**。这就是方案二的核心,后面详述。 ### 工具层: MCP 兜底 系统内的工具(查用例库、查错误码表、触发执行)按 [MCP](./mcp.md) 暴露,Agent 侧通过标准协议发现与调用。这样工具的实现与 Agent 框架彻底解耦——未来换任何支持 MCP 的 agent 运行时,工具零改动。 ## 四、三档方案: 从只换模型到整体重构 ### 方案一: 配置级 —— 只换模型 **做法**:所有 AI 调用走统一入口(上面的 `call_role`),模型寻址全部配置化;prompt 模板外置到 git 仓库;OpenAI 兼容接口直连各 provider。 **换一次模型的工作量**:改配置文件 + 针对性调该角色的 prompt 模板 + 跑该角色的评测集回归。以天计。 ``` ┌─────────────────────────────────────────────┐ │ 测试系统(网站/流水线/阶段代码) ←—— 不动 │ ├─────────────────────────────────────────────┤ │ ROLES 配置 + prompt 模板库 ←—— 只改这里 │ ├─────────────────────────────────────────────┤ │ OpenAI 兼容 API (各厂商/本地) ←—— 随便换 │ └─────────────────────────────────────────────┘ ``` **利**: - 成本极低,一周内落地,立刻获得"新模型出来当天切换"的能力; - 配合 golden 评测集(见下一节),换模型质量可量化、可回滚。 **弊**: - **只能换"能力等价或更高"的模型**。新模型 tool calling 方式不同、上下文窗口不同,该角色背后的架构假设(prompt 是一条还是多条、有没有工具循环)仍然是写死的; - prompt 模板与角色隐式耦合:模板里可能塞了"你是评审员"这类角色设定,换模型时模板往往要跟着调,配置切换并非完全无痛; - 架构范式被冻结:今天所有阶段都是"单次调用",想给某个阶段升级成多 agent 辩论,还是要动代码。 **适用**:团队初期、AI 环节以"单次调用类任务"为主(用例生成、分诊、报告)。 ### 方案二: 接口级 —— 换模型同时换架构 **做法**:在方案一之上,把每个 AI 角色的**能力接口**显式定义出来(输入契约 → 输出契约 → 质量基线),每种架构范式(单次调用 / ReAct agent / 编排者-工作者 / 辩论循环)作为接口的可插拔实现;智能体间通信全部契约化;阶段编排(DAG)与阶段实现分离。 ``` ┌─────────────────────────────────────────────┐ │ 阶段编排层 (DAG 定义、依赖、缓存) ←—— 不动 │ ├─────────────────────────────────────────────┤ │ 角色能力接口 (generate/review/triage...) │ │ ├─ 实现: PromptXxx (单次调用) │ │ ├─ 实现: AgenticXxx (ReAct 循环) ← 新增 │ │ └─ 实现: DebateXxx (多agent辩论) ← 新增 │ ├─────────────────────────────────────────────┤ │ 模型适配层 (能力声明 + 配置寻址) ←—— 不动 │ └─────────────────────────────────────────────┘ ``` **换一次架构的工作量**:给某角色新写一个实现类 + 实现内部随便用什么范式 + 跑该角色评测集。以周计,且不影响其他角色。 **利**: - **模型和架构两个维度都解锁**:新模型接入 = 注册 provider;新范式落地 = 新实现类。两者互不干扰; - 灰度友好:同一角色的两个实现可以 A/B 并存,按模块/按流量切比例,评测集数据说话; - 抽象层有明确的量化验收手段(评测集),"抽象泄漏"能第一时间被发现而不是攒着。 **弊**: - **前置设计成本真实存在**:能力接口要想清楚输入输出契约,设计错了后面全是补丁。建议接口先服务当前最简单的实现,等第二个实现出现时再泛化(YAGNI); - 接口层是"最不坏"的抽象,不是免费的:多一层间接,调试时栈变深,新人理解成本上升; - 对团队工程能力有要求——如果团队还没有把方案一跑稳,上接口层是过早优化。 **适用**:AI 环节已跑稳半年以上、开始频繁出现"这个阶段该升级成 agent 了"诉求的团队。 ### 方案三: 平台级 —— 整体重构(含网站) **做法**:把"测试业务"与"AI 能力"拆成两个独立系统。AI 能力沉淀为内部 **AI 中台**(统一模型网关、agent 运行时、评测平台、模板库),以 API/事件形式对外服务;测试系统(网站、流水线)退化为中台的**一个消费方**,与其他潜在消费方(开发环境插件、告警 bot)平级。 ``` ┌────────────┐ ┌────────────┐ ┌────────────┐ │ 测试网站 │ │ IDE 插件 │ │ 告警 bot │ 消费方层: 谁都能接 └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ └───────────────┼───────────────┘ v ┌─────────────────────────────────────────────┐ │ AI 能力中台 │ │ ├─ 模型网关(路由/限流/审计/成本) │ │ ├─ Agent 运行时(编排/DAG 执行/工具-MCP) │ │ ├─ 评测平台(golden 集管理/回归对比/质量看板) │ │ └─ 模板与知识库(git 化/RAG) │ └─────────────────────────────────────────────┘ ^ ┌─────────────────────┴───────────────────────┐ │ 模型层: 各厂商 API / 本地推理(随时替换) │ └─────────────────────────────────────────────┘ ``` 网站全体重构之所以"不再疼",是因为**测试领域资产(用例库、报告、执行记录)从来就不该和 AI 代码住在一个仓库里**——它们是纯领域数据,通过契约与中台交互。重构网站只是换一个消费方的壳,数据和 AI 能力都不动。 **利**: - 根本性解耦:网站怎么重构、换什么前端框架、要不要拆微服务,都与 AI 演进无关;反过来模型/架构随便换,消费方只受契约影响; - AI 投入开始跨团队复用,成本分摊;评测平台独立后,质量治理有专门的看板和负责人; - 安全合规收口一处(密钥、审计、数据分级,见[云服务测试](./cloud-service-testing.md)的数据安全一节)。 **弊**: - **贵且慢**:中台本身是个需要长期运营的产品,不是一次性项目。网关、运行时、评测平台每一块都要人维护; - **过度设计的经典陷阱**:如果 AI 消费方只有测试系统一个,中台就是在为一个客户做通用产品,复杂度没有买家; - 多一层网络调用与组织边界,排障链路变长,迭代速度反而可能下降。 **适用**:AI 能力已有三个以上消费方、或合规/成本治理已经成痛点的组织。否则保持方案二,把中台的心留给将来。 ### 三档对比总表 | 维度 | 方案一: 配置级 | 方案二: 接口级 | 方案三: 平台级 | |------|--------------|--------------|--------------| | 能换什么 | 模型 | 模型 + 某角色的架构范式 | 模型 + 架构 + 消费方外壳全换 | | 切换成本 | 天 | 周(单角色) | 消费方随便换,中台不动 | | 前置投入 | 一周 | 1-2 月(含契约设计) | 季度级 | | 主要风险 | 架构被冻结,升级仍要改代码 | 抽象设计失误、过早优化 | 过度设计、中台无人运营 | | 质量保障 | 角色级评测集回归 | 评测集 + 实现级 A/B 灰度 | 评测平台 + 全局质量看板 | | 适用时机 | 现在就该做 | 跑稳半年后 | 消费方 ≥3 或治理成痛点 | ## 五、共同底座: Golden 评测集 —— 用测试的方法测 AI 三个方案里反复出现"跑评测集回归",这里把它说透,因为它是测试系统做 AI 架构独有的、别的领域羡慕不来的优势: **每个 AI 阶段维护一份 golden 数据集**:输入是真实脱敏过的需求文档/日志,期望输出是当年人工评审定稿的用例/分诊结论。每次换模型、换架构、调 prompt,先离线跑 golden 集,自动对比: | 指标 | 怎么算 | 换模型时的决策 | |------|--------|--------------| | 契约合规率 | 输出能否通过 schema 校验 | 低于阈值直接拒绝该模型 | | 与基线 diff 率 | 结构化字段级 diff(如预期结果文本的相似度) | diff 大到人看不完 = 有风险,抽审 | | 评审拦截率 | 评审方对生成方产出的阻断意见数 | 拦截率翻倍说明生成质量退化 | | 成本/延迟 | token 消耗与耗时 | 同质量选便宜的(成本分工见[多模型辩论](./multi-model-debate.md)) | ```python def evaluate(role: str, impl) -> EvalReport: """任何角色实现的唯一准入门槛: golden 集回归。""" report = EvalReport() for case in load_golden(role): output = impl.run(case.input) report.schema_ok += passes_schema(output, CONTRACTS[role]) report.diff_ratio += field_diff(output, case.expect) report.cost += impl.last_call_cost return report ``` golden 集本身也是团队资产:每次人工评审定稿的产出物,抽一部分回流进 golden 集,集子越用越准。这和[云服务测试](./cloud-service-testing.md)里的"飞轮"是同一个机制——只不过这次飞轮转动的对象,是 AI 系统自己。 ## 六、落地案例: 接入 DeepSeek Harness 的评估 外部 AI 框架层出不穷,这一节用一个真实案例走一遍评估流程:**DeepSeek Harness(dsh)**——DeepSeek 2026 年 8 月开源的 agent 运行框架,一周内 GitHub 16 万+ star,被认为是 Claude Code 基础设施的开源对标。评估它能不能嵌进上面的架构、嵌在哪一层。 ### 它是什么: 特点和原理 官方给出的公式:**Agent = Model + Harness**。模型负责推理,Harness 负责把推理接到真实环境——上下文管理、工具调用、权限审批、会话持久化、多智能体编排。它不是一个新模型,也不是开箱即用的产品,而是组装 agent 的"工厂"。 四个核心设计([官方 README](https://github.com/deepseek-ai/deepseek-harness)与[架构文档](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/architecture.md)): **1. 一切皆插件。** 基于 Cordis 插件元框架:模型适配器、工具注册表、会话日志、agent 循环本身都是插件,没有特权内核。运行中的 dsh = 启动时按序叠加的一层 patch 组合成的插件树——"产品由一棵插件树组成,每一部分都可以从配置替换"。替换一个 provider 就换掉整个产品的对应能力。 **2. Seam(接缝)设计。** 每个可替换能力有三个角色:声明接口的 Service Definition、实现它的 Service Provider、使用它的 Consumer。例如文件系统和子进程共享一个执行世界,把 provider 指向远程沙箱,Bash/PTY/LSP 就整体跟着迁走,无需分叉代码。 **3. 仅追加会话日志(Trajectory)。** 模型看到的一切——系统提示词、思维链、工具调用与结果、子 agent 调度、每次上下文注入——都写入 append-only 的 `SessionEvent` 日志,模型可见即日志可重建是运行时不变量。恢复、分叉、检索、回放共享同一份事件流。 **4. 四种运行模式。** 标准(完整工具组合)、PTC(Programmatic Tool Calling,模型生成一段代码组合多轮工具调用)、极简(仅 shell + 文件编辑,用于模型基准测试)、创造(检查运行时、在内存中试验插件并组合新模式)。另有 `web / headless / sdk / sdk-minimal / acp` 五种 profile,其中 headless 和 SDK 形态适合被外部系统嵌入调用。 ### 映射到本文架构: 它是方案二的"活标本" 把 dsh 和第三、四节的抽象逐一对照,会发现它不是外来物,而是把方案二的每个抽象都做到了极致的参考实现: | 本文的抽象 | dsh 中的对应物 | 吻合度 | |-----------|--------------|--------| | 模型适配层(能力声明) | `ctx.llm` 适配器 seam,换模型 = 注册插件 | 高 | | 角色能力接口(架构可插拔) | `core/agent` 的 Agent 接口 + `core/agent-loop` 默认驱动,循环本身可替换 | 高 | | 工具标准化 | `ctx.tools` 作用域化工具注册表 + 带审批的执行流水线(可与 MCP 互通) | 高 | | 阶段契约与可审计 | 仅追加会话日志,模型可见即日志可重建 | 高于我们目前的设计 | | 编排者-工作者拓扑 | 子 agent / 实验性的 Agent Teams(名册 + 任务板 + 邮箱) | 中,偏 coding 场景 | ### 嵌入评估: 嵌在哪、怎么用 **结论:能嵌入,且正好是方案二"角色能力接口"的一个实现;但不适合当系统骨架。** ```{mermaid} flowchart TB subgraph SYS[我们的测试系统] ORCH[阶段编排层 DAG] -->|契约 JSON| GEN[脚本生成角色] ORCH --> TRIAGE[失败分诊角色] end subgraph DSH[dsh --profile headless/sdk] LOOP[agent 循环 + 工具] LOG[(Trajectory 会话日志)] LOOP --- LOG end GEN -->|作为该角色的一种实现| LOOP TRIAGE -->|作为该角色的一种实现| LOOP LOG -. 审计/回放/评测数据来源 .-> ORCH ``` **适用方面(按收益排序)**: 1. **脚本生成与修复(收益最大)**。这是 agentic coding 框架的主场:让 agent 带着"读 OpenAPI、翻历史用例、写 pytest、跑测试、看报错迭代修复"的工具循环干活(对应拓扑二),正好落地"用例 → 可执行脚本"这个当前最耗人力的阶段; 2. **失败分诊的深查模式**。普通失败走单次调用(便宜),`confidence` 低或 `is_flaky` 的案件升级给 dsh 跑的 agent——自己翻日志、查提交历史、跑复现命令,产出带证据链的分诊报告; 3. **用例生成的 Agentic 实现**。对应 `AgenticCaseGenerator`:模型自主查需求文档、对不确定处标"需澄清",而不是一条 prompt 塞到底; 4. **编排者-工作者的工作者运行时**。大模块拆解后,每个工作者可以是一个 dsh 子 agent,Trajectory 日志直接作为工作者产出的审计附件; 5. **评测数据来源**。它的 append-only 日志天然回答"这次输出模型到底看了什么"——golden 集回归失败时,回放日志定位是模型问题还是上下文注入问题,比我们自己埋点省事。 **不适用/风险**: - **单次调用类阶段不要用**。用例评审、报告生成这类"一条 prompt 进出"的阶段,引入一个 agent 运行时是纯负担——进程开销、成本、复杂度全无收益。记住原则:**harness 嵌在角色内部,编排层永远只面对契约**; - **v0.1 开发者预览,官方明言将有破坏性变更**。必须关在角色实现类后面,并纳入 golden 集回归;绝不允许它的 API 泄漏到阶段契约和编排层。它一旦被换(或升级 breaking),代价 = 重写一个实现类,而不是重构系统; - **Node/TypeScript 技术栈**(有 Python SDK,本质是拉起 dsh 进程走 JSON-RPC),嵌入形态是进程间调用而非库调用,部署多一个运行时依赖; - **它的会话/轮次模型很"重"**(turn/step/request series 概念体系),与 DAG 阶段的"纯函数"心智不同——边界要划清:dsh 负责角色内部的"怎么做",DAG 负责阶段间的"做什么"。 **落地建议**:按方案二的装配方式,先给"脚本生成"这一个角色写 `DshCaseGenerator` 实现,headless 形态接入,跑 golden 集与现有 `PromptCaseGenerator` A/B 对比;数据说话,再决定是否推广到分诊深查等场景。 ## 七、横向关切: 记忆、知识、存储与扩展 前面六节解决"AI 怎么换"。系统真跑起来之后还有六个横向关切,每个都按"够用 → 标准 → 重型"给多档方案。**共同原则不变:这些机制都是角色的私有缓存或系统底座,绝不进入阶段契约。** ### 7.1 Agent 记忆 先分清三种记忆,混为一谈是设计错误: | 记忆层 | 内容 | 生命周期 | 存放位置 | |--------|------|---------|---------| | 工作记忆 | 当前任务上下文 | 一次会话 | 会话日志(append-only,阶段内部) | | 项目记忆 | 团队约定、环境信息、模块约定 | 长期稳定 | 知识库(git 化文档) | | 长期记忆 | 历史决策、踩坑记录、用户偏好 | 持续增长 | 本节方案的主角 | **方案A: 记忆即文件(起步)**。`memory/` 目录放 markdown,git 管理,启动时注入 system prompt。 | 利 | 弊 | |----|----| | 零依赖;可评审、可 diff,和模板库同一套治理纪律 | 容量极小(上下文装不下几百条);检索=全量注入,记忆越多越稀释注意力;模型不会主动维护 | **方案B: 记忆即工具(推荐)**。把记忆做成 agent 的两个工具:`save_memory(事实, 标签)` / `recall(查询)`,存 PostgreSQL,检索用关键词+轻量向量。模型自己决定记什么、何时查——这正好复用 [Agent 那篇](./agent.md)的工具循环机制,不用发明新概念。 | 利 | 弊 | |----|----| | 容量不限;按需检索不占上下文;记忆的增删对模型透明 | 记忆质量依赖模型自觉,可能记入垃圾;需要定期人工清理(和知识库腐化同一类问题);并发写需要简单去重 | **方案C: 记忆服务(重型)**。独立记忆服务,分层(情景/语义)、衰减策略、冲突合并,多系统共享。 | 利 | 弊 | |----|----| | 多消费方共享一份记忆;有正式的遗忘与冲突解决机制 | 又是一个要长期运营的系统;对测试场景的收益有限——测试系统的"记忆"大多是团队知识,本该走知识库而非个人化记忆 | **选型建议**:测试系统选 B,且把纪律写死:**长期记忆只记"这次 AI 协作复盘出的结论"**(对应[云服务测试](./cloud-service-testing.md)的沉淀触发器),团队知识一律进知识库不进记忆。个人化记忆在测试场景价值低,警惕过度设计。 ### 7.2 知识与 RAG 原理见 [RAG 那篇](./rag.md):检索是"考试时发参考资料",不是事实源。先定这条纪律,再选档: **方案A: 无向量(起步, 强烈推荐先用它)**。git 文档库 + 目录约定 + `AGENTS.md` 写明"回答必须引用哪些文件" + ripgrep 全文检索。 | 利 | 弊 | |----|----| | 零新增组件;单一事实源,文档即索引,绝无"索引过期"问题;命中结果可精确引用行号 | 无语义检索,"报错码 429 怎么处理"搜不到"限流排空"这种换词表述;文档上十万字后命中率下降 | **方案B: 嵌入式向量库(增长期)**。pgvector / sqlite-vec 与业务库同库,分块→向量化→入库→检索五步管线(见 [RAG 那篇](./rag.md)的最小实现)。 | 利 | 弊 | |----|----| | 运维零新增;向量和业务数据同事务,一致性简单 | 检索负载和业务库抢资源;数据量大了想换专用引擎,迁移成本随时间放大 | **方案C: 独立检索服务(规模期)**。OpenSearch + 专用向量库(Milvus/Qdrant),RAG 成为独立服务,测试系统只是消费方。 | 利 | 弊 | |----|----| | 独立扩容;召回质量可调(混合检索、重排);与方案三平台级架构对接 | 一个完整的新系统要运维;文档→索引的同步管道是新的故障点,管道挂了 AI 悄悄退化 | **三档共同的防腐化纪律**:事实源永远是 git 文档库,索引永远可重建;在 golden 集里加"引用时效性"用例——问一个文档已更新的旧说法,期望 AI 答新版,答错说明索引/知识腐化。 ### 7.3 数据冗余与高可用 先按 RPO/RTO 给数据分类,不同数据冗余档位完全不同: | 数据 | 性质 | 可容忍丢失 | 冗余方案 | |------|------|-----------|---------| | 用例库、golden 集、模板库 | 版本化资产 | 几乎不可丢 | **git 化本身就是冗余**(多副本克隆+MR 历史),异地再加一个镜像 remote 即完成 | | 会话日志/Trajectory | 审计资产 | 可丢近期 | append-only 文件 + 定期归档对象存储 | | 任务状态、队列消息 | 运行时数据 | 完全可丢 | 无需专门冗余,从上游契约重放即可(这也要求任务可重入) | | 记忆库、向量索引 | 可再生缓存 | 可丢 | 定期快照;真丢了按知识库重建 | 业务库(报告、任务记录)本身: **方案A: 单机 + 每日备份**。恢复点 24 小时,恢复时间小时级。 | 利 | 弊 | |----|----| | 零运维成本;测试系统的业务库大多数时间可以丢 | 崩一天丢一天;golden 集若也放库里就不可接受——所以 golden 集必须 git 化,和业务库分离 | **方案B: 主从 + 自动故障转移(Patroni/哨兵)**。RPO 秒级,RTO 分钟级。 | 利 | 弊 | |----|----| | 对调用方透明;成本可控(多一台机器) | 脑裂需要仲裁;切换瞬间在途任务要可重入兜底 | **方案C: 异地多活**。对测试系统几乎永远过度。 | 利 | 弊 | |----|----| | 机房级容灾 | 成本与复杂度数倍;测试系统停半天的人工预案通常比多活便宜得多 | ### 7.4 高性能横向扩展 先纠正一个直觉:AI 测试系统的瓶颈**不在 web 层**。页面 QPS 很小,重活是 AI 调用——而 AI 调用的吞吐上限在 provider 的速率限制或自托管 GPU,不在你的代码。所以扩展策略是"轻的一层随便扩,重的一层受控排队": **方案A: 单体 + 垂直扩容(起步)**。一个应用,AI 调用同步发起,调外部 API。 | 利 | 弊 | |----|----| | 最简单;外部 API 时代几乎永远够用 | 并发上限=进程数×每请求耗时;长任务(整模块用例生成)会占住连接;无法削峰 | **方案B: 无状态化 + 任务队列(推荐)**。web 层做成无状态,AI 调用全部异步入队,worker 池消费,按角色分队列(贵模型队列单独限流);DAG 节点缓存天然吸收重复计算: ``` 用户请求 ──> 无状态 Web 层 ──> 任务队列(按角色分队列+限流) │ ┌─────────────┼─────────────┐ v v v worker worker worker (水平扩这一层) │ 消费时先查 DAG 节点缓存, 命中即返回 v 模型网关(7.5)──> 各 provider / 本地推理 ``` | 利 | 弊 | |----|----| | web 层和 worker 层独立水平扩;provider 限流时排队而非报错;任务可重试、可审计 | 引入队列组件(学习成本参考本仓库 celery/ 目录的示例);任务状态要额外管理;调试链路多一跳 | **方案C: 事件驱动(平台级)**。和方案三平台级架构配套,此处不重复展开。 自托管模型的扩展单独说一句:多实例 vLLM + 网关负载均衡(机制见[生产部署那篇](./production-deployment.md));外部 API 场景下"横向扩展"的正确姿势是**多 provider 密钥池轮换**,不是加自己的机器。 ### 7.5 模型自由切换(运维面) 第四节管的是"代码可换"(适配层),这里管的是"运行时怎么切": **方案A: 配置 + 重启**。改 ROLES 配置,滚动重启。 | 利 | 弊 | |----|----| | 实现成本零 | 切换有停机;无法灰度——新模型质量如何只能上线后看 | **方案B: 模型网关(推荐)**。LiteLLM/one-api 类网关做统一入口:模型 = 一个字符串,网关负责路由、限流、重试、密钥池、成本统计。在此之上做三件事: - **灰度**:按角色切(分诊先切新模型观察一周),再按流量比例切; - **降级**:provider 故障/超时自动切备用 provider,本地模型兜底(见[本地 AI 服务](./local-ai-service.md)); - **门禁**:切换动作和 golden 集回归联动——回归不过,路由配置不允许合入。 | 利 | 弊 | |----|----| | 切换从"发版"变"改路由配置";降级自动化;全系统 token 成本一处可见 | 多一个组件;网关本身成了单点(需双实例);调试时多一跳,请求 id 要全链路透传 | **方案C: 网关 + 评测联动(治理成熟期)**。在 B 之上加"模型-角色-质量"看板:每个角色各模型的 golden 集得分、成本、延迟持续对比,选模型从"拍脑袋"变"看数据",也直接服务[多模型辩论](./multi-model-debate.md)的成本分工。 | 利 | 弊 | |----|----| | 质量、成本、延迟三维权衡可见;新模型接入决策有量化依据 | 看板本身需要维护;样本量小的角色数据噪声大,别过度解读 | ### 7.6 工具/MCP 的部署形态: 跟着 agent 走, 还是独立部署 [MCP](./mcp.md) 协议本身支持两种传输:**stdio**(MCP server 作为子进程,由 agent 宿主拉起,只跟本机一个 agent 通信)和 **Streamable HTTP**(独立部署的服务,谁都能连)。这不是非此即彼的架构抉择——同一份 server 实现通常两种 transport 都暴露,真正的决策是**每个工具放哪种形态**。判断标准只有一条:**这个工具操作的东西在哪、归谁用**。 | 维度 | stdio(跟着 agent) | HTTP(独立部署) | |------|------------------|----------------| | 适用工具 | 操作**本地资源**的: shell、文件、读本地日志、本地脚本 | 操作**共享服务**的: 查用例库、触发执行平台、错误码服务、知识库检索 | | 消费方 | 单个 agent 独占 | 多个 agent/系统复用(web、CI bot、其他团队) | | 密钥与权限 | 散在每台 agent 机器上,各自配置 | 收敛在服务侧,一处鉴权、审计、限流 | | 运维成本 | 零(随 agent 起停) | 多一个长驻服务,要版本管理 | | 性能 | 无网络开销 | 多一次本地 RPC,可忽略 | | 治理 | 权限分散,审计要埋在每个 agent 里 | 集中治理,天然符合[云服务测试](./cloud-service-testing.md)的执行层纪律 | 对测试系统的结论: - **领域工具(查用例库、触发用例执行、写报告)独立部署 HTTP**——它们是多消费方的(web 界面、分诊 bot、未来 IDE 插件都要用),且涉及执行权限,必须集中鉴权审计,不能跟着某个 agent 进程走; - **环境工具(shell、文件操作、翻日志)stdio 跟着 agent**——操作的是 agent 所在机器的资源,独立部署反而要处理"远程执行"这个本不存在的问题; - **第三种形态: 进程内挂载**。如果你自己拥有 agent 运行时(自研循环或像 dsh 那样的框架),工具可以不经过 MCP 协议,直接注册进运行时的工具表(如 dsh 的 `ctx.tools`)。省掉协议开销和进程管理,代价是失去"写一次处处可用"——只有当你确定短期没有第二个消费方时才划算。 两个坑: - **把本地工具包成 HTTP 是负收益**。stdio 的 shell 工具一旦暴露成 HTTP 服务,"谁能调"立刻变成认证难题——等于把 agent 的机器权限开放给内网(危险工具的边界见 [Agent 那篇](./agent.md)的权限一节); - **HTTP 形态忘了鉴权**。MCP server 默认不带认证,独立部署时必须在前面加网关或内置 token,否则内网任何机器都能调你的执行平台。 ## 八、外部系统接入: 内网已有资产怎么进来 真实的公司环境不是一个绿色field。总架构图左上角的四类已有资产,接入方式各不相同,但共用两条铁律:**不改已有系统**(适配器模式,我们读它们)、**写回走评审**(AI 产出 diff/MR,人审后合入,执行权限不外放)。 | 已有资产 | 性质 | 接入方式 | 进入哪个阶段 | |---------|------|---------|-------------| | 设计系统(需求描述) | 需求源头,持续更新 | API/webhook 订阅变更,转成**需求契约**(结构化需求点清单),增量触发"需求理解"阶段重跑 | 阶段 1 的输入 | | 测试代码仓 | 执行资产,人在维护 | git 只读克隆 + 作为 agent 的文件工具工作区;AI 改脚本**只产出 MR**,评审由测试工程师在原有 code review 流程里完成 | 阶段 4 的产物落点、阶段 5 的输入 | | 执行机代码仓 | 执行环境,独立演进 | 不直接碰。由执行平台暴露 API,MCP 工具封装后给 agent 调用(见 7.6);执行机代码的变更由执行机团队自己的流程管 | 阶段 5 | | 历史测试设计/执行记录 | 沉睡的知识原料 | 一次性清洗导入知识库 + 定期增量同步;向量化后供用例生成/分诊检索——历史用例是生成质量最强的上下文(见[云服务测试](./cloud-service-testing.md)的上下文工程) | 阶段 2/6 的检索语料 | 三个容易忽视的要点: - **需求契约是跨系统的第一块基石**。设计系统的需求描述格式各家公司不同,必须先转成统一的"需求点清单" schema(需求点、验收标准、出处链接),此后下游七个阶段都对设计系统无感——设计系统换工具,只改这一个适配器; - **历史记录导入时带着出处**。每条历史用例入库时保留"来自哪个系统、哪个版本"的元数据,AI 生成时引用有据可查,也便于源系统数据修正后的重新同步; - **同步管道要可重放**。所有"外部系统 → 知识库/契约"的同步都记录游标(cursor),管道挂了从断点续传,而不是全量重来(7.2 节索引可重建的纪律在这里同样适用)。 ## 九、知识的生产、共享与治理 知识管理的三个存储(总架构图中部)职责不同,共享方式也不同: | 存储 | 内容 | 事实源? | 共享方式 | |------|------|--------|---------| | git 文档库 | 需求契约、用例库、排障手册、历史记录导入 | **是** | MR 评审制,全团队共享;跨团队共享 = 加一个 git remote | | RAG 索引 | 文档库的分块向量 | 否,可重建 | 导出索引快照给其他部署环境(内网隔离场景),重建永远以文档库为准 | | 记忆库 | AI 协作的复盘结论 | 否 | 不跨系统共享——个人记忆无共享价值,团队结论沉淀时应升格为文档库条目 | Agent 之间"共享知识"的真相:**不存在 agent 间的知识传递,只有大家读同一个事实源**。两个 agent 要共享上下文,正确做法是都把结论写进文档库/契约,而不是 A 把对话历史塞给 B——这与第二节"智能体之间只说公文"是同一条纪律。 生产与消费的飞轮(与[云服务测试](./cloud-service-testing.md)的飞轮同源,此处落到存储层):**AI 产出 → 人评审定稿 → 定稿回流文档库(带出处)→ 索引重建 → 下一次检索起点更高**。定稿回流是写入知识库的唯一合法途径——AI 运行时的中间产物(记忆)永远不直接进事实源。 ## 十、系统的自我迭代升级 "AI 自我迭代"听着玄,拆开就是四个可迭代对象和一条铁律。 **铁律:AI 提案、评测裁判、人盖章。** AI 可以生成任何改进建议,但只有评测门禁 + 人工合入两个闸门都打开,变更才生效。没有这道闸,系统会自我强化——用当前的错误模式去"改进"自己,越迭代越歪。 **可迭代的四类对象**: | 对象 | AI 怎么提案 | 怎么裁判 | 生效方式 | |------|-----------|---------|---------| | Prompt 模板 | 分析评审拦截记录/解析失败日志,生成修订 diff | golden 集回归对比 | MR 合入模板库 | | 角色实现 | 新模型接入、新框架接入(如 dsh)、范式升级(单次→agent) | golden 集 + 与现实现 A/B | 路由配置灰度,流量从小到大 | | 评测集自身 | 从人工定稿的产出物中抽取新 golden 用例 | 抽样人工确认标注无误 | MR 合入 golden 库 | | 知识库 | 发现文档过期/矛盾时标记并给出修订建议 | 领域负责人确认 | MR 合入文档库 | **升级流程(以"新模型接入"为例)**,这就是系统级的 CI/CD: ``` 1. 注册 新模型写入网关配置,只路由到影子流量(旁路执行,结果只记录不生效) 2. 评测 全角色跑 golden 集,产出 质量/成本/延迟 三维对比报告 3. 对比 与现模型逐角色对比:契约合规率、字段 diff 率、评审拦截率 4. 灰度 无分歧的角色先切 10% 流量,观察一至两周 5. 全量 逐步放大;任意阶段指标回退,一键路由回旧模型 ``` **影子模式(shadow)是自我迭代的基础设施**:任何"提案"都先旁路跑一段时间积累真实数据,再谈生效。这和测试领域的"金丝雀发布"是同一个思想,只是被测对象从代码变成了 AI 配置。 ## 十一、插件体系: 用户怎么开发自己的扩展 参考成熟测试系统的插件架构元素(pytest 的 conftest/插件发现机制、Jenkins 的插件市场、dsh 的"一切皆插件 + profile 组合"),设计三级插件,门槛从低到高: **一级: 工具插件(MCP server)**。写一个 MCP server,注册进工具目录,agent 即可调用。这是绝大多数用户的扩展点——接一个内部系统、加一个查询能力,都在这一级。流程:本地开发 → 用 dsh/Claude Desktop 自测 → 提交工具目录登记(声明名称、schema、权限 scope)→ 评审合入。 **二级: 角色实现插件**。实现某个角色的能力接口(如自定义的 `CaseGenerator`),打包注册后可被路由配置选中。用于"我的场景和默认实现差异很大,要换做法"的团队。必须随插件提交该角色的 golden 集测试结果。 **三级: 编排插件**。定义新的 DAG 节点模板(输入契约、输出契约、依赖位置),扩展七阶段流水线本身。门槛最高,因为契约一变影响全局,评审要架构负责人参与。 统一的发布流程(三级共用): ``` 开发(脚手架模板生成) → 本地 golden 自测(不过不能提交) → MR 到插件/模板库 → 双人评审(质量 + 安全scope) → 灰度(指定模块/流量) → 全量 → 质量看板持续观察 ``` 治理四件套,缺一不可: - **权限 scope 声明**:插件注册时必须声明要什么权限(读哪些仓、能否触发执行),超 scope 调用直接被拒——和 7.6 节 MCP 鉴权同一套; - **版本与签名**:插件带版本号,编排配置锁定版本,升级要显式动作; - **禁用开关**:任一插件可一键停用(灰度出问题时不用回滚部署); - **不许绕过评测**:插件产物同样要过 golden 集门禁——插件是"换实现"的正规军,不是绕过质量的侧门。 ## 十二、不变量清单: 什么东西永远不改 把全文收拢成一张表。左列是每次重构、每次外部 AI 变迁都不允许动的;右列是鼓励经常换的。判断标准只有一个:**换它的代价是不是线性的**——换右列任何一项,代价是一个适配器/一个实现类/一次配置;换左列任何一项,代价是迁移历史数据和重建信任。 | 不变(迁移成本非线性) | 可变(切换成本线性) | |----------------------|---------------------| | 七阶段的**契约 schema**(及需求契约 schema) | 模型(网关路由) | | **golden 评测集**(含评测门禁流程) | prompt 模板 | | **知识事实源**(git 文档库及其 MR 治理) | 角色实现(单次调用/dsh/自研循环) | | **审计日志**(会话 Trajectory,"模型可见即可重建") | RAG 引擎与索引(可重建) | | **角色能力接口**(方案二的抽象边界) | 前端网站与技术栈 | | **权限模型**(scope 声明、执行权不外包) | 部署形态(单机/队列/中台) | | | 插件的具体实现 | 这张表也是架构评审的checklist:任何新设计提案,先问它动没动左列;动了,就回到"契约是否必须演化"这个问题上做显式决策,而不是在代码里悄悄改。 ## 常见坑 | 坑 | 现象 | 处理 | |----|------|------| | 直接把对话历史传给下游阶段 | 下游耦合上游模型的输出习惯,换模型全崩 | 阶段间只传契约 JSON,对话历史留在阶段内部 | | 用模型名当配置键 | `"kimi-k2": {...}` 散在代码各处,换模型全局搜改 | 配置键用**角色名**,模型名只是值 | | OpenAI 兼容 = 能力兼容的错觉 | 换了个"兼容"模型,JSON 输出天天解析失败 | 注册时能力声明 + golden 集契约合规率门槛 | | 接口层一次设计完美 | 三个月没写出第二个实现,抽象全是猜测 | 第二个实现出现前,不为"将来可能"做泛化 | | 评审方和生成方同模型同会话 | AI 自己认可自己,错误一致化 | 跨厂商/跨会话隔离(见[结对编程](./pair-coding.md)) | | 换模型不测就上线 | 用例库悄悄混入新模型的编造断言 | 评测集回归是 CI 里的强制关卡,不是可选项 | | 一步到位上中台 | 为一个消费方养一个平台团队 | 消费方 <3 时坚守方案二,把契约边界守好 | | 框架 API 泄漏出角色层 | 框架升级 breaking,全系统跟着改 | 框架关在角色实现类后面,golden 集回归兜底(见上节 dsh 评估) | | 向量库当事实源 | 文档改了 AI 引用旧说法,无人察觉 | git 文档库是唯一事实源,索引可重建;golden 集加引用时效性用例(见 7.2) | | 记忆与知识混存 | 团队知识躺在个人记忆里,人走即失 | 团队知识进知识库;记忆只放复盘结论(见 7.1) | | 队列任务不可重入 | worker 重跑产生重复用例/重复报告 | 任务以契约输入做幂等键;消费先查 DAG 节点缓存(见 7.4) | ## 总结 - **交互**:智能体之间只说"公文"不说"悄悄话"——流水线/DAG 管流程,编排者-工作者管拆解,生成-评审对抗管质量,三种拓扑覆盖全部场景; - **对接**:OpenAI 兼容 API 统一传输,能力声明统一差异,角色能力接口统一架构范式,MCP 统一工具; - **方案**:配置级(方案一)现在就做;接口级(方案二)边跑边埋边界,第二个实现出现时泛化;平台级(方案三)等消费方数量逼出来再上; - **底座**:golden 评测集让每个"换"都可量化、可灰度、可回滚——测试系统做 AI 架构,最大的优势就是能用测试的手段治理 AI 本身; - **横向**:记忆、RAG、冗余、扩展、运行时切换各有"够用→标准→重型"三档(第七节),与三档主方案正交,按实际规模逐档升级,不要跳档; - **接入**:已有系统只读适配、写回走 MR(八),知识只有一条共享路径——大家读同一事实源(九); - **迭代**:AI 提案、评测裁判、人盖章,影子模式先行(十);扩展走三级插件 + 统一发布流程(十一); - **底线**:契约、golden 集、事实源、审计日志、角色接口、权限模型是不变量(十二)——它们不动,其他随便换,这就是"外部 AI 日新月异也能快速切换"的全部含义。 ## 参考资料 - [云服务测试的 AI 转型: 六个方向、五项能力、四类工具](./cloud-service-testing.md)——阶段拆分与模板层/知识层的来源 - [从0开始搭建一个 Agent](./agent.md)——ReAct 循环、工具调用协议、多 Agent 模式 - [AI 工作流里的 DAG](./dag.md)——阶段编排、缓存与可审计性的机制细节 - [只有一个 Claude Code: 让多个模型讨论方案和 review 代码](./multi-model-debate.md)——生成-评审对抗与成本分工 - [Kimi Code + Claude Code 结对编程](./pair-coding.md)——跨厂商盲区互补分析 - [MCP: AI 应用的 "USB-C" 接口](./mcp.md)——工具标准化,一处实现处处可用 - [RAG: 检索增强生成](./rag.md)——7.2 节分档方案的原理与最小实现 - [从0开始搭建本地 AI 服务](./local-ai-service.md)——OpenAI 兼容接口与本地模型兜底 - [从学习到生产](./production-deployment.md)——模型服务化部署、网关与治理 - [DeepSeek Harness 官方仓库](https://github.com/deepseek-ai/deepseek-harness)与[架构文档](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/architecture.md)——第六节评估对象的一手资料