普通视图

发现新文章,点击刷新页面。
昨天以前掘金专栏-得物技术

Claude Code Harness 工程:数仓侧落地方案|得物技术

作者 得物技术
2026年5月21日 10:21

一、AI Coding 现状与痛点:为什么需要 Harness

当前使用情况

得物离线数仓各小组已基本完成 AI Coding 工具的覆盖,主力工具为 Claude Code,辅以数据平台的 IDE 插件,应对重复性工作时效率提升明显。

核心痛点

尽管整体提效已显现,但团队在实际使用中暴露出三类结构性痛点。

痛点一:AI 不记得上下文约束,开发过程中反复"失忆"。会话开始时告知了"金额字段单位是千元",对话进行到一半后 AI 忘了,生成的 SQL 把千元当元用,导致数据差了 1000 倍。这不是偶发问题,而是 Claude Code 的 context compact 机制(上下文压缩)的系统性限制:当对话 token 接近上限(约 95%)时,历史内容被自动压缩为摘要,临时口头说的约束全部丢失。

痛点二:规范执行不稳定,靠记忆兜底的部分最容易出问题。OneData 命名规范、注释三段式、INSERT 必须带 PARTITION 子句......这些规范大家都知道。在项目工期紧张时,人工规范遵守率降至 60%~70%,AI 靠 prompt 记忆的规范遵守率也只有 70%~80%。真正需要的是:把规范从"LLM 记忆中的指导性内容"变成"每次执行时强制检查的护栏"。

痛点三:大型需求开发中,context 很快被撑满,越到后期 AI 越不可靠。复杂需求(大型宽表、大量下游血缘)的典型开发过程:

血缘查询结果(500~3000 tokens) 自测 23 条 SQL 执行结果(5000~15000 tokens) SKILL 规范文件内容(~10000 tokens) 数据比对两表样本(大量行)= context 迅速膨胀 → compact 触发 → 关键约束遗忘 → AI 开始犯低级错误

核心矛盾:越是复杂的需求,越依赖 AI;但越复杂的需求,context 越容易撑满,AI 越容易"失忆"。

从"随手问 AI"到"把能力封装起来"

针对上述痛点,我们沿用了一条反复验证的结论:规范执行是人的短板、AI 的长板;业务判断是 AI 的短板、人的长板。Harness 工程的目标,就是把"执行层"的不稳定因素系统性地消掉:把规范写进 hooks,不再靠 AI 记忆,每次写 SQL 文件后自动触发检查;把迭代约束写进持久化文件,compact 后自动重新注入,不再靠临时口头说;把高 token 操作隔离到 subagent,主 context 只接收摘要,不被过程数据撑满。

二、先搞清楚"Harness"是什么

在 Claude Code 的 update-config skill 描述中有一句话:"Automated behaviors require hooks configured in settings.json --- the harness executes these, not Claude"。

Harness = Claude Code 的宿主运行框架,即 Claude Code 客户端本身这个"工具链容器"。它:管理 context window 生命周期;在 LLM 推理循环之外确定性地执行 hooks;协调 subagents 的生命周期;不依赖模型判断,直接执行配置的自动化行为。区别总结:

三、核心问题:compact 到底丢掉什么?

每次数仓开发 context 接近满时,auto-compact 触发(默认 95% 时触发),会把整个对话历史替换为一份摘要,token 缩减到原来的约 12%。哪些内容 compact 后丢失:

数仓场景最痛的点:对话中说的"这次用 OVERWRITE 模式"、"先忽略 field_a 字段" → compact 后全忘;SKILL 文件读了一半,compact 后前几个 step 的内容没了 → Claude 重复询问;自测跑出来 50 行结果,加上血缘查询的几十行表结构 → context 很快膨胀到 compact 阈值。

四、五层防御体系(从简单到复杂)

第一层:写死进 CLAUDE.md(立即可用)

机制:项目根目录 .claude/CLAUDE.md 每次 compact 后从磁盘重新注入,是最可靠的持久化位置。将当前迭代的关键信息写入,格式建议:

# 当前迭代状态(每次迭代手动更新)## 正在开发- 表:db_a.dws_table_a
 版本:V1.0
 node_id:1000000001
 状态:ETL开发阶段(Step 3/8)

## 本次迭代约束- 禁止修改:dwd_table_b(已上线,只读)
 分区字段:partition_dt(格式 yyyyMMdd,不是 dt)
 amount 字段单位:千元(不是元)

## 数仓全局规范
 建表:分区字段必须是 partition_dt string
 禁止:SELECT *UPDATE/DELETEWHERE
 金额字段用 DECIMAL(20,4),不用 DOUBLE
 INSERT 必须带 PARTITION 子句

操作规则:进入新迭代时,更新"正在开发"和"本次迭代约束"两节;上线后清空"本次迭代约束";全局规范长期保留,控制在 100 行以内。

第二层:Auto Memory 自动积累(已在运行)

机制:Claude 自动将跨会话发现写入 ~/.claude/projects//memory/MEMORY.md,每次 compact 后重新注入。数仓场景下主动触发 Claude 写记忆的时机:"这张表的 amount 字段单位是千元,请记住";"field_a 在特定场景下会为空,请记住这个踩坑";"本次 V1.0 的关键变更是 field_b 逻辑调整,请记住"。Claude 会自动写入 MEMORY.md,下次会话或 compact 后自动恢复。

第三层:hooks 自动验证(核心防御,解决"忘了检查"的问题)

这是解决"每次写完 SQL 自动检查"的关键机制。

配置文件位置

数仓项目根目录/
└── .claude/
    ├── settings.json          ← hooks 在这里配置
    ├── CLAUDE.md              ← 数仓规范上下文
    └── hooks/
        ├── validate_sql.sh          ← SQL 规范自动检查
        ├── block_dangerous_ddl.sh   ← 危险 DDL 拦截
        └── inject_context.sh        ← compact 后重注入上下文

settings.json 完整配置

{"hooks": {"PostToolUse": [{"matcher": "Write|Edit","hooks": [{"type": "command","command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/validate_sql.sh","timeout": 60,"statusMessage": "检查 SQL 规范..."}]}],"PreToolUse": [{"matcher": "Bash","hooks": [{"type": "command","command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block_dangerous_ddl.sh"}]}],"SessionStart": [{"matcher": "compact","hooks": [{"type": "command","command": "cat \"$CLAUDE_PROJECT_DIR\"/.claude/context/dw_conventions.md","statusMessage": "重注入数仓规范..."}]}],"Stop": [{"hooks": [{"type": "prompt","prompt": "检查用户要求的所有任务是否都已完成。如果还有未完成项,返回提示但不要重新开始。检查 stop_hook_active 是否为 true,如是则直接 exit。","model": "claude-haiku-4-5-20251001"}]}]}}

SQL 规范自动检查脚本

.claude/hooks/validate_sql.sh:

#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo"$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('file_path',''))" 2>/dev/null)

# 只处理 .sql 文件
[[ "$FILE_PATH" != *.sql ]] && exit 0
[[ -z "$FILE_PATH" ]] && exit 0

SQL=$(cat "$FILE_PATH" 2>/dev/null)
[[ -z "$SQL" ]] && exit 0

ERRORS=()

# 规范1:禁止 SELECT *echo "$SQL" | grep -iqE 'SELECT\s+\*' && ERRORS+=("CRITICAL: 发现 SELECT *,必须明确列名")

# 规范2:INSERT 必须带 PARTITIONif echo "$SQL" | grep -iqE 'INSERT\s+(INTO|OVERWRITE)'; thenecho "$SQL" | grep -iqE 'PARTITION\s*\(' || ERRORS+=("CRITICAL: INSERT 缺少 PARTITION 子句")
fi# 规范3:DOUBLE 类型金额echo "$SQL" | grep -iqE '\bDOUBLE\b' && ERRORS+=("WARNING: 金额字段建议用 DECIMAL(20,4),不用 DOUBLE")

# 规范4:UPDATE/DELETE 必须有 WHEREif echo "$SQL" | grep -iqE '\b(UPDATE|DELETE)\b'; thenecho "$SQL" | grep -iqE '\bWHERE\b' || ERRORS+=("CRITICAL: UPDATE/DELETE 缺少 WHERE 条件")
fiif [ ${#ERRORS[@]} -gt 0 ]; thenecho "=== SQL 规范检查失败:$FILE_PATH ===" >&2
  for err in"${ERRORS[@]}"; doecho "  $err" >&2
  doneexit 2
fiecho "SQL 规范检查通过: $(basename $FILE_PATH)" >&2
exit 0

危险 DDL 拦截脚本

.claude/hooks/block_dangerous_ddl.sh:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo"$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('command',''))" 2>/dev/null)

# 拦截生产表 DROP/TRUNCATE(放行 _dev/_test/_stg 后缀)if echo "$CMD" | grep -iqE '\b(DROP\s+TABLE|TRUNCATE\s+TABLE)\b'; thenif ! echo "$CMD" | grep -qiE '(_dev|_test|_stg)\b'; thenecho "BLOCKED: 检测到生产表 DROP/TRUNCATE 操作,请确认表名是否正确" >&2
    exit 2
  fifiexit 0

hook 通信协议关键规则

关键陷阱:阻断必须用 exit 2,用 exit 1 不会阻止 Claude 继续执行。

第四层:subagents 做上下文隔离(防 context 膨胀)

核心原则:把"高 token 消耗但结果只需要摘要"的操作放到 subagent 的独立 context 中执行。

数仓场景适合下放 subagent 的操作

创建 subagent 文件

.claude/agents/sql-validator.md(SQL 语法验证):

---
name: sql-validator
description: ODPS/MaxCompute SQL 语法验证与规范检查专用 agent。当用户生成或修改 SQL 文件后需要验证时调用。在独立 context 运行,防止大量验证日志污染主对话。
tools: Read, Bash, Grep, Glob
model: haiku
permissionMode: dontAsk
---

你是数仓 SQL 规范专家,只做验证,不修改文件。

验证项(按优先级):
1. SELECT * 禁止
2. INSERT 必须带 PARTITION
3. 字段用 snake_case 命名
4. 金额字段用 DECIMAL 不用 DOUBLE
5. 多表 JOIN 必须有 ON 条件
6. 笛卡尔积风险检测

输出格式:
- 状态:PASS / FAIL
- 问题列表(CRITICAL / WARNING / INFO)
- 修改建议(具体到行号)

不超过 50 行,只返回结构化报告。

.claude/agents/dw-explorer.md(防止血缘查询撑爆主 context):

---
name: dw-explorer
description: 数仓结构探索 agent。当需要大量读取表结构、DDL、字段信息、血缘关系时自动调用,避免大量文件内容污染主 context。只读,不修改任何文件。
tools: Read, Glob, Grep, Bash
model: haiku
permissionMode: dontAsk
---

你是数仓探索专家,只读操作。

当被调用时:
1. 读取指定表的 DDL、字段信息、分区策略
2. 分析上下游血缘(一层)
3. 识别关键字段口径(金额、日期、状态类字段)

输出:不超过 80 行的结构化摘要,包含:
- 表基本信息(层级、粒度、分区策略)
- 核心字段定义(含口径说明)
- 上下游血缘(只列表名,不展开内容)
- 发现的特殊口径或踩坑点

使用方式

在主对话中自然触发:

用 dw-explorer 分析 db_a.dwd_table_a 的结构

对刚生成的 insert_dws_table_a.sql 用 sql-validator 验证

或强制指定(避免 Claude 自行判断):

@"sql-validator (agent)" 验证 path/to/insert.sql

第五层:SKILL 文件改造(减少 context 消耗)

当前的问题:每次调用 SKILL 文件(01~08.md),内容全部加载进主 context,加速 compact 触发。改造方向:把 SKILL 文件的"执行步骤"提炼成 subagent 指令,subagent 内部读完整 SKILL 文件,主 context 只接收结果摘要;用 path-scoped rules 替代 SKILL 文件中的规范章节,按需加载:

---
# .claude/rules/etl-rules.md
paths:
  - "**/*insert*.sql"
  - "**/*_di.sql"
  - "**/*_df.sql"
---

# ETL 开发规范(按文件路径自动加载)
- 必须有 partition_dt 分区
- INSERT OVERWRITE 前检查分区是否已存在
- 不允许跨库 JOIN

SKILL 文件保持现状,但改变调用方式:不要在主对话中直接触发,而是启动一个 subagent 来读 SKILL 文件执行 ETL,主对话只接收最终产出的 SQL 文件路径。

五、可行落地方案:数仓 Harness 架构

先让我们看一下整体的架构设计(整体架构图):

这张架构图的核心逻辑是职责分层:不同类型的工作交给最合适的机制去做,而不是全部压在 Claude 的推理循环里。

持久化层解决的是"失忆"问题,任何临时口头说的约束,compact 后都会消失;但写进 .claude/CLAUDE.md 的内容,每次会话启动和 compact 后都会从磁盘重新注入------这是整套方案里最简单也最可靠的一层。

Harness 层(Hooks) 解决的是"规范靠记忆"的问题,PostToolUse hook 在每次写 .sql 文件后确定性触发,不依赖 Claude 有没有记住规范要求;违规时 exit 2 强制阻断,Claude 必须修正后才能继续,规范遵守率从 70%80% 提升到 95%+。

Subagent 层解决的是"context 被撑满"的问题,血缘查询、23 项自测、数据比对这类操作会产生大量 token,放到独立 context 的 subagent 里执行,主会话只接收一份摘要,compact 触发频率预计降低 50%70%。

三层机制分工明确,互不干扰:Hooks 处理"写动作触发的规范检查",subagent 处理"读操作的 context 隔离",CLAUDE.md 处理"跨会话状态持久化"。为了配合这套架构落地,数仓的研发流程可以拆解为 8 个大的步骤,流程图如下:

从 Harness 架构的视角来看,8 个步骤可以按"对 context 的影响"分成两类:一类是直接在主会话处理 (内容量有限,context 压力低):需求分析(读 PRD)、技术设计(写规范说明)、SR 导入(生成配置)、SLA/DQC(生成规则)。另一类必须通过 Harness 机制处理(否则会加速 compact 或规范失控):ETL 开发每次写 .sql 文件,PostToolUse hook 自动触发规范检查,不依赖人工提醒;自测时 23 条 SQL 的执行结果体量大,交给 data-quality-checker subagent 隔离,主会话只收 PASS/FAIL 摘要;数据比对时两表样本数据量大,交给 data-comparator subagent 隔离;性能优化时血缘 + 多层 DDL 每次 500~3000 tokens,交给 dw-explorer subagent 隔离。这种分工不是把步骤拆开独立执行,而是在同一个工作流里,让每个步骤以最合适的方式运行------context 压力小的步骤留在主会话保持流畅,context 压力大的步骤通过 subagent 隔离保持干净,规范检查通过 hook 自动执行不需要人工干预。

六、基于 SKILL 规范的数仓工作流设计

数仓 8 步 SKILL 规范(需求分析→技术设计→ETL→自测→数据比对→SR 导入→性能优化→SLA/DQC)天然对应 Harness 的三层机制。核心思路是:SKILL 文件不变,改变调用方式------主对话只读规范结论,实际执行由 subagent 或 hook 完成。

各步骤推荐提示词与工作流

Step 1:需求分析

推荐提示词:

用 dw-explorer subagent 先读取上游表结构(只返回摘要),
然后按需求分析规范生成:
1. 需求摘要(≤5行)
2. 表字段口径草稿
3. 待确认问题清单(按优先级排序)
需求文档 URL:[粘贴PRD链接]

Hook 配合:SessionStart 注入当前迭代约束(版本号/表名/禁止修改的表)。

Step 2:技术设计

推荐提示词:

基于上一步确认的需求,按 OneData 规范完成技术设计:
 表名:[按 层级_域_主题_粒度_周期 格式命名]
 粒度:[描述]
 分区:partition_dt string(格式 yyyyMMdd)
 禁止:任何与上游不一致的字段命名
输出 OneData 建模说明,不超过 60

CLAUDE.md 写入(设计完成后手动更新):

## 当前迭代技术设计决策- 表名:db_a.dws_table_a
- 主键:order_no + partition_dt
- 特殊约束:amount 字段继承上游千元单位,不做转换

Step 3:ETL 开发

这是 Harness 工程价值最高的步骤,PostToolUse hook 在每次 SQL 文件保存时自动触发。

推荐提示词:

按 ETL 开发规范生成建表 DDL + Insert SQL- 建表文件:ddl_[表名].sql
- 插入文件:insert_[表名].sql
- 要求:INSERT 用 OVERWRITE 模式,PARTITION 子句必须包含 partition_dt
- 金额字段:DECIMAL(20,4),单位继承上游(千元)
生成完毕后,用 sql-validator subagent 验证两个文件

Hook 自动执行(无需手动触发):每次写入 .sql 文件 → PostToolUse hook 自动运行规范检查。若发现 SELECT * 或缺少 PARTITION → 返回 exit 2,Claude 收到错误自动修正。

Step 4:自测

推荐提示词(防止自测结果撑爆主 context):

用 data-quality-checker subagent 对 [表名] 执行 23 项标准自测,
bizdate = [日期]
补充口径约束:[如"is_perform=1 只取履约订单"]
只返回:PASS/FAIL 汇总 + FAIL 项详情(≤50行),不返回原始 SQL 执行结果

效果:23 条 SQL 的执行结果全在 subagent context 里,主对话只收到一份摘要报告。

Step 5:数据比对

推荐提示词:

用 data-comparator subagent 对比:
 新表:[新表名] partition_dt = [日期]
 参考表:[旧表名/线上表]
 比对字段:[核心金额字段列表]
 容差:≤ 0.01%(金额类)
只返回:差异超过容差的字段列表 + 差值,不返回全量对比数据

Step 6:SR数据库导入

推荐提示词(自动生成最优数据库建表参数):

用 dw-sr SKILL生成建表任务, 先查以下表的 DDL 和一层上下游血缘(只返回摘要):
- 源表:[ODPS表名]
- 目标表:[SR表名]

然后基于 DDL 摘要,分析当前 SR 同步任务的配置风险:
1. 字段类型是否有精度丢失风险(DECIMAL/DOUBLE → DECIMAL(38,18))
2. Key 字段选择是否合理(重复率是否过高导致 DUPLICATE KEY 膨胀)
3. 分区数量是否合理(partition_live_number 与下游查询窗口是否匹配)
4. DISTRIBUTED BY HASH 的 bucket 数与数据量是否匹配
5. 是否有 DATETIME 字段在 SR 侧用了 VARCHAR 存储(会导致时间过滤走全表扫描)

输出同步任务配置建议(按风险高低排序),不超过 20 行。
每条格式:[风险等级 高/中/低] 问题描述 → 建议修改方式

Step 7:性能优化

推荐提示词(防止血缘查询撑爆主 context):

用 dw-explorer subagent 先查 [表名] 的一层上下游血缘和 DDL(只返回摘要),
然后分析当前 Insert SQL 的性能瓶颈:
1. 是否有全表扫描
2. 是否有笛卡尔积风险
3. 是否可以用 MAP JOIN 替代 HASH JOIN
输出优化建议(按收益排序),不超过 30

Step 8:SLA/DQC

推荐提示词:

按 SLA/DQC 规范为 [表名] 生成 9 类 DQC 规则:
 完整性:主键非空、分区数据量
 准确性:核心金额字段与上游比对(容差 0.01%)
 一致性:is_perform 与 perform_flag 联动逻辑
 时效性:产出时间 SLA ≤ 次日 8:00
输出 DQC 配置 JSON,可直接使用

SKILL 调用方式改造(减少主 context 消耗)

当前问题:触发 SKILL 时,SKILL 文件全文(约 10KB)加载进主 context,加速 compact。改造方向:

核心原则:主对话只接收决策级信息(PASS/FAIL、差异字段、优化方案),不接收过程数据(SQL 执行结果、原始血缘列表、完整 DDL 内容)。

精准对话流设计:控制AI思考的艺术

文章中多次提到 /dw-etl、/dw-自测 等命令,这是数仓研发全流程 SKILL 套件的核心触发词,每个命令对应一个封装了规范、产出格式和工具调用的标准化执行单元。核心理念:把每次都要重复讲的要求写进 SKILL,把每次都怕忘的检查点写进 SKILL,把每次都需要的结构化输出也写进 SKILL------这样谁来做需求都行,底座是一致的。

8 个 SKILL 命令一览

以 /dw-etl 为例:一条命令封装了什么?ETL 开发(Step 3)是 Harness 工程价值最高的步骤,SKILL 文件内封装了:① 规范内容(写死,不靠记忆):建表规范:分区字段必须是 partition_dt STRING(格式 YYYYMMDD);金额字段:DECIMAL(26,4),不用 DOUBLE;INSERT 模式:必须使用 INSERT OVERWRITE,必须带 PARTITION 子句;禁止:SELECT *、跨库 JOIN(非血缘关系)。② 产出格式(结构化,不走样):

输出文件:
├── ddl_[表名].sql      ← ODPS 建表语句(含注释三段式、生命周期配置)
├── insert_[表名].sql   ← ODPS Insert SQL(含分区裁剪、JOIN 规范)
└── ddl_sr_[表名].sql   ← SR 建表语句(Key 列顺序、DECIMAL 精度)

③ 自动护栏(Hook 配合):每次 .sql 文件写入后,PostToolUse hook 自动执行 validate_sql.sh;发现 SELECT * 或缺少 PARTITION → exit 2 阻断,Claude 强制修正。④ subagent 卸载(防 context 膨胀):"生成完毕后,用 sql-validator subagent 验证两个文件";验证结果全在 subagent context 里,主对话只收到"PASS/FAIL + 问题列表"。综合效益数据:

七、落地步骤

步骤一:项目级上下文持久化。在数仓项目目录下创建 .claude/CLAUDE.md,写入当前迭代状态。每次新迭代开始时更新"正在开发"和"本次迭代约束"两节,上线后清空约束节。全局规范永久保留,控制在 100 行以内。

步骤二:配置 hooks 自动验证。创建 .claude/settings.json + hooks/ 目录,配置 PostToolUse hook(每次写 .sql 后自动规范检查)和 PreToolUse hook(拦截危险 DDL)。效果:不需要每次手动说"帮我检查 SQL 规范",hook 在 Harness 层自动触发,不占用 Claude 推理资源。

步骤三:创建 subagents 隔离高 token 操作。创建三个核心 subagent 文件:sql-validator.md、dw-explorer.md、data-quality-checker.md。将 Step 4/5/7 的执行全部下放,预计主 context compact 频率降低 50%~70%。

八、Harness 工程能解决的核心问题

这一节是整个方案的出发点,也是对"为什么要这么做"的直接回答。

数仓 AI 开发当前的本质瓶颈:语义理解

在实际数仓 AI 开发中,技术能力不是瓶颈,语义理解才是。需求理解偏差占总返工的 40%~60%,大约 40%~50% 的工作时间花在理解需求和与业务核对口径上。精准血缘探查:准确率提升显著,远超传统方式。这两个观察揭示了同一个问题:AI 在数仓场景的不准确,根本原因不是"不会写 SQL",而是"不理解业务语义"------不知道这张表的 amount 单位是千元还是元,不知道 is_perform=1 在这个版本里意味着什么,不知道某字段在特定场景下会为空。

语义 × 数据 = 准确率

数仓 AI 开发的准确率,可以用一个公式来理解:

准确率 = 语义理解深度 × 数据规范覆盖度

结论:Harness 工程的本质,是把"语义"和"规范"从不可靠的 LLM 记忆中,迁移到确定性的 hooks + 持久化文件里,从而让 语义 × 规范 = 准确率 这个等式两边的变量都变得稳定。

具体能解决的四类问题

问题一:字段口径遗忘导致的计算错误

现状:对话开始时告知了"amount 字段单位是千元",compact 后 Claude 忘了,生成的 SQL 把千元当元用,导致数据差 1000 倍。Harness 解法:字段口径写进 .claude/CLAUDE.md(compact 后重新注入);踩坑经验写进 Auto Memory(跨会话持久化);结果:这类错误从"时常发生"降到"基本不出现"。

问题二:需求理解偏差导致的返工

现状:需求文档描述的是"用户视角的 GMV",但 AI 生成了"交易视角的 GMV",两者口径不同,数据对不上,需要返工。Harness 解法:需求分析的产出(口径草稿 + 待确认问题清单)写进 CLAUDE.md 的迭代约束节;Stop hook 检查任务完整性,确认待确认问题清单已全部明确后才放行;结果:需求一次交付通过率从约 50% 提升到 90%。

问题三:SQL 规范执行不一致

现状:规范文档写了"INSERT 必须带 PARTITION",但 Claude 有时会忘,或在 compact 后规范内容被清除后生成不合规的 SQL。Harness 解法:PostToolUse hook 在每次写 .sql 文件后自动执行规范检查,不依赖 Claude 记忆;违规时 exit 2 返回错误,Claude 强制修正后才能继续;结果:规范执行率从"依赖 LLM 记忆的 70%~80%"提升到"hook 强制的 95%+"。

问题四:大型需求开发中的 context 耗尽

现状:复杂需求(大型宽表、大量下游血缘)开发过程中,血缘查询 + 自测结果 + SKILL 文件内容堆满 context,compact 触发后丢失关键约束,Claude 开始犯低级错误。Harness 解法:血缘查询 → dw-explorer subagent(独立 context,只返回摘要);23 项自测 → data-quality-checker subagent(独立 context,只返回 PASS/FAIL 报告);SKILL 文件内容 → subagent 内部读取,主 context 只接收产出的 SQL 文件路径;结果:主 context compact 频率预计降低 50%~70%。

与传统数仓 AI 开发方式的对比

从"AI 帮我写代码"到"AI 嵌入研发流水线"

Harness 工程的最终目标,不是让 Claude 更聪明,而是让整个研发流水线更可靠。Claude(LLM)负责:理解需求、设计方案、生成代码------这些需要语义理解的事;Harness(hooks)负责:规范检查、危险拦截、任务完整性验证------这些需要确定性执行的事;Subagents 负责:大量文件读取、血缘查询、自测执行------这些会消耗大量 context 的事;CLAUDE.md + Memory 负责:字段口径、迭代约束、踩坑经验------这些需要跨会话持久化的事。这四层分工,让数仓 AI 开发从"对话驱动的一次性辅助"升级为"规则嵌入的流水线自动化"。

往期回顾

1.[BP Claw 破解 AI 编码输入难题 ------FlinkSpec 需求智能化实践|得物技术](# 一、AI Coding 现状与痛点:为什么需要 Harness

当前使用情况

得物离线数仓各小组已基本完成 AI Coding 工具的覆盖,主力工具为 Claude Code,辅以数据平台的 IDE 插件,应对重复性工作时效率提升明显。

核心痛点

尽管整体提效已显现,但团队在实际使用中暴露出三类结构性痛点。

痛点一:AI 不记得上下文约束,开发过程中反复"失忆"。会话开始时告知了"金额字段单位是千元",对话进行到一半后 AI 忘了,生成的 SQL 把千元当元用,导致数据差了 1000 倍。这不是偶发问题,而是 Claude Code 的 context compact 机制(上下文压缩)的系统性限制:当对话 token 接近上限(约 95%)时,历史内容被自动压缩为摘要,临时口头说的约束全部丢失。

痛点二:规范执行不稳定,靠记忆兜底的部分最容易出问题。OneData 命名规范、注释三段式、INSERT 必须带 PARTITION 子句......这些规范大家都知道。在项目工期紧张时,人工规范遵守率降至 60%~70%,AI 靠 prompt 记忆的规范遵守率也只有 70%~80%。真正需要的是:把规范从"LLM 记忆中的指导性内容"变成"每次执行时强制检查的护栏"。

痛点三:大型需求开发中,context 很快被撑满,越到后期 AI 越不可靠。复杂需求(大型宽表、大量下游血缘)的典型开发过程:

血缘查询结果(500~3000 tokens) 自测 23 条 SQL 执行结果(5000~15000 tokens) SKILL 规范文件内容(~10000 tokens) 数据比对两表样本(大量行)= context 迅速膨胀 → compact 触发 → 关键约束遗忘 → AI 开始犯低级错误

核心矛盾:越是复杂的需求,越依赖 AI;但越复杂的需求,context 越容易撑满,AI 越容易"失忆"。

从"随手问 AI"到"把能力封装起来"

针对上述痛点,我们沿用了一条反复验证的结论:规范执行是人的短板、AI 的长板;业务判断是 AI 的短板、人的长板。Harness 工程的目标,就是把"执行层"的不稳定因素系统性地消掉:把规范写进 hooks,不再靠 AI 记忆,每次写 SQL 文件后自动触发检查;把迭代约束写进持久化文件,compact 后自动重新注入,不再靠临时口头说;把高 token 操作隔离到 subagent,主 context 只接收摘要,不被过程数据撑满。

二、先搞清楚"Harness"是什么

在 Claude Code 的 update-config skill 描述中有一句话:"Automated behaviors require hooks configured in settings.json --- the harness executes these, not Claude"。

Harness = Claude Code 的宿主运行框架,即 Claude Code 客户端本身这个"工具链容器"。它:管理 context window 生命周期;在 LLM 推理循环之外确定性地执行 hooks;协调 subagents 的生命周期;不依赖模型判断,直接执行配置的自动化行为。区别总结:

三、核心问题:compact 到底丢掉什么?

每次数仓开发 context 接近满时,auto-compact 触发(默认 95% 时触发),会把整个对话历史替换为一份摘要,token 缩减到原来的约 12%。哪些内容 compact 后丢失:

数仓场景最痛的点:对话中说的"这次用 OVERWRITE 模式"、"先忽略 field_a 字段" → compact 后全忘;SKILL 文件读了一半,compact 后前几个 step 的内容没了 → Claude 重复询问;自测跑出来 50 行结果,加上血缘查询的几十行表结构 → context 很快膨胀到 compact 阈值。

四、五层防御体系(从简单到复杂)

第一层:写死进 CLAUDE.md(立即可用)

机制:项目根目录 .claude/CLAUDE.md 每次 compact 后从磁盘重新注入,是最可靠的持久化位置。将当前迭代的关键信息写入,格式建议:

# 当前迭代状态(每次迭代手动更新)## 正在开发- 表:db_a.dws_table_a
 版本:V1.0
 node_id:1000000001
 状态:ETL开发阶段(Step 3/8)

## 本次迭代约束- 禁止修改:dwd_table_b(已上线,只读)
 分区字段:partition_dt(格式 yyyyMMdd,不是 dt)
 amount 字段单位:千元(不是元)

## 数仓全局规范
 建表:分区字段必须是 partition_dt string
 禁止:SELECT *UPDATE/DELETEWHERE
 金额字段用 DECIMAL(20,4),不用 DOUBLE
 INSERT 必须带 PARTITION 子句

操作规则:进入新迭代时,更新"正在开发"和"本次迭代约束"两节;上线后清空"本次迭代约束";全局规范长期保留,控制在 100 行以内。

第二层:Auto Memory 自动积累(已在运行)

机制:Claude 自动将跨会话发现写入 ~/.claude/projects//memory/MEMORY.md,每次 compact 后重新注入。数仓场景下主动触发 Claude 写记忆的时机:"这张表的 amount 字段单位是千元,请记住";"field_a 在特定场景下会为空,请记住这个踩坑";"本次 V1.0 的关键变更是 field_b 逻辑调整,请记住"。Claude 会自动写入 MEMORY.md,下次会话或 compact 后自动恢复。

第三层:hooks 自动验证(核心防御,解决"忘了检查"的问题)

这是解决"每次写完 SQL 自动检查"的关键机制。

配置文件位置

数仓项目根目录/
└── .claude/
    ├── settings.json          ← hooks 在这里配置
    ├── CLAUDE.md              ← 数仓规范上下文
    └── hooks/
        ├── validate_sql.sh          ← SQL 规范自动检查
        ├── block_dangerous_ddl.sh   ← 危险 DDL 拦截
        └── inject_context.sh        ← compact 后重注入上下文

settings.json 完整配置

{"hooks": {"PostToolUse": [{"matcher": "Write|Edit","hooks": [{"type": "command","command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/validate_sql.sh","timeout": 60,"statusMessage": "检查 SQL 规范..."}]}],"PreToolUse": [{"matcher": "Bash","hooks": [{"type": "command","command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block_dangerous_ddl.sh"}]}],"SessionStart": [{"matcher": "compact","hooks": [{"type": "command","command": "cat \"$CLAUDE_PROJECT_DIR\"/.claude/context/dw_conventions.md","statusMessage": "重注入数仓规范..."}]}],"Stop": [{"hooks": [{"type": "prompt","prompt": "检查用户要求的所有任务是否都已完成。如果还有未完成项,返回提示但不要重新开始。检查 stop_hook_active 是否为 true,如是则直接 exit。","model": "claude-haiku-4-5-20251001"}]}]}}

SQL 规范自动检查脚本

.claude/hooks/validate_sql.sh:

#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo"$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('file_path',''))" 2>/dev/null)

# 只处理 .sql 文件
[[ "$FILE_PATH" != *.sql ]] && exit 0
[[ -z "$FILE_PATH" ]] && exit 0

SQL=$(cat "$FILE_PATH" 2>/dev/null)
[[ -z "$SQL" ]] && exit 0

ERRORS=()

# 规范1:禁止 SELECT *echo "$SQL" | grep -iqE 'SELECT\s+\*' && ERRORS+=("CRITICAL: 发现 SELECT *,必须明确列名")

# 规范2:INSERT 必须带 PARTITIONif echo "$SQL" | grep -iqE 'INSERT\s+(INTO|OVERWRITE)'; thenecho "$SQL" | grep -iqE 'PARTITION\s*\(' || ERRORS+=("CRITICAL: INSERT 缺少 PARTITION 子句")
fi# 规范3:DOUBLE 类型金额echo "$SQL" | grep -iqE '\bDOUBLE\b' && ERRORS+=("WARNING: 金额字段建议用 DECIMAL(20,4),不用 DOUBLE")

# 规范4:UPDATE/DELETE 必须有 WHEREif echo "$SQL" | grep -iqE '\b(UPDATE|DELETE)\b'; thenecho "$SQL" | grep -iqE '\bWHERE\b' || ERRORS+=("CRITICAL: UPDATE/DELETE 缺少 WHERE 条件")
fiif [ ${#ERRORS[@]} -gt 0 ]; thenecho "=== SQL 规范检查失败:$FILE_PATH ===" >&2
  for err in"${ERRORS[@]}"; doecho "  $err" >&2
  doneexit 2
fiecho "SQL 规范检查通过: $(basename $FILE_PATH)" >&2
exit 0

危险 DDL 拦截脚本

.claude/hooks/block_dangerous_ddl.sh:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo"$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('command',''))" 2>/dev/null)

# 拦截生产表 DROP/TRUNCATE(放行 _dev/_test/_stg 后缀)if echo "$CMD" | grep -iqE '\b(DROP\s+TABLE|TRUNCATE\s+TABLE)\b'; thenif ! echo "$CMD" | grep -qiE '(_dev|_test|_stg)\b'; thenecho "BLOCKED: 检测到生产表 DROP/TRUNCATE 操作,请确认表名是否正确" >&2
    exit 2
  fifiexit 0

hook 通信协议关键规则

关键陷阱:阻断必须用 exit 2,用 exit 1 不会阻止 Claude 继续执行。

第四层:subagents 做上下文隔离(防 context 膨胀)

核心原则:把"高 token 消耗但结果只需要摘要"的操作放到 subagent 的独立 context 中执行。

数仓场景适合下放 subagent 的操作

创建 subagent 文件

.claude/agents/sql-validator.md(SQL 语法验证):

---
name: sql-validator
description: ODPS/MaxCompute SQL 语法验证与规范检查专用 agent。当用户生成或修改 SQL 文件后需要验证时调用。在独立 context 运行,防止大量验证日志污染主对话。
tools: Read, Bash, Grep, Glob
model: haiku
permissionMode: dontAsk
---

你是数仓 SQL 规范专家,只做验证,不修改文件。

验证项(按优先级):
1. SELECT * 禁止
2. INSERT 必须带 PARTITION
3. 字段用 snake_case 命名
4. 金额字段用 DECIMAL 不用 DOUBLE
5. 多表 JOIN 必须有 ON 条件
6. 笛卡尔积风险检测

输出格式:
- 状态:PASS / FAIL
- 问题列表(CRITICAL / WARNING / INFO)
- 修改建议(具体到行号)

不超过 50 行,只返回结构化报告。

.claude/agents/dw-explorer.md(防止血缘查询撑爆主 context):

---
name: dw-explorer
description: 数仓结构探索 agent。当需要大量读取表结构、DDL、字段信息、血缘关系时自动调用,避免大量文件内容污染主 context。只读,不修改任何文件。
tools: Read, Glob, Grep, Bash
model: haiku
permissionMode: dontAsk
---

你是数仓探索专家,只读操作。

当被调用时:
1. 读取指定表的 DDL、字段信息、分区策略
2. 分析上下游血缘(一层)
3. 识别关键字段口径(金额、日期、状态类字段)

输出:不超过 80 行的结构化摘要,包含:
- 表基本信息(层级、粒度、分区策略)
- 核心字段定义(含口径说明)
- 上下游血缘(只列表名,不展开内容)
- 发现的特殊口径或踩坑点

使用方式

在主对话中自然触发:

用 dw-explorer 分析 db_a.dwd_table_a 的结构

对刚生成的 insert_dws_table_a.sql 用 sql-validator 验证

或强制指定(避免 Claude 自行判断):

@"sql-validator (agent)" 验证 path/to/insert.sql

第五层:SKILL 文件改造(减少 context 消耗)

当前的问题:每次调用 SKILL 文件(01~08.md),内容全部加载进主 context,加速 compact 触发。改造方向:把 SKILL 文件的"执行步骤"提炼成 subagent 指令,subagent 内部读完整 SKILL 文件,主 context 只接收结果摘要;用 path-scoped rules 替代 SKILL 文件中的规范章节,按需加载:

---
# .claude/rules/etl-rules.md
paths:
  - "**/*insert*.sql"
  - "**/*_di.sql"
  - "**/*_df.sql"
---

# ETL 开发规范(按文件路径自动加载)
- 必须有 partition_dt 分区
- INSERT OVERWRITE 前检查分区是否已存在
- 不允许跨库 JOIN

SKILL 文件保持现状,但改变调用方式:不要在主对话中直接触发,而是启动一个 subagent 来读 SKILL 文件执行 ETL,主对话只接收最终产出的 SQL 文件路径。

五、可行落地方案:数仓 Harness 架构

先让我们看一下整体的架构设计(整体架构图):

这张架构图的核心逻辑是职责分层:不同类型的工作交给最合适的机制去做,而不是全部压在 Claude 的推理循环里。

持久化层解决的是"失忆"问题,任何临时口头说的约束,compact 后都会消失;但写进 .claude/CLAUDE.md 的内容,每次会话启动和 compact 后都会从磁盘重新注入------这是整套方案里最简单也最可靠的一层。

Harness 层(Hooks) 解决的是"规范靠记忆"的问题,PostToolUse hook 在每次写 .sql 文件后确定性触发,不依赖 Claude 有没有记住规范要求;违规时 exit 2 强制阻断,Claude 必须修正后才能继续,规范遵守率从 70%80% 提升到 95%+。

Subagent 层解决的是"context 被撑满"的问题,血缘查询、23 项自测、数据比对这类操作会产生大量 token,放到独立 context 的 subagent 里执行,主会话只接收一份摘要,compact 触发频率预计降低 50%70%。

三层机制分工明确,互不干扰:Hooks 处理"写动作触发的规范检查",subagent 处理"读操作的 context 隔离",CLAUDE.md 处理"跨会话状态持久化"。为了配合这套架构落地,数仓的研发流程可以拆解为 8 个大的步骤,流程图如下:

从 Harness 架构的视角来看,8 个步骤可以按"对 context 的影响"分成两类:一类是直接在主会话处理 (内容量有限,context 压力低):需求分析(读 PRD)、技术设计(写规范说明)、SR 导入(生成配置)、SLA/DQC(生成规则)。另一类必须通过 Harness 机制处理(否则会加速 compact 或规范失控):ETL 开发每次写 .sql 文件,PostToolUse hook 自动触发规范检查,不依赖人工提醒;自测时 23 条 SQL 的执行结果体量大,交给 data-quality-checker subagent 隔离,主会话只收 PASS/FAIL 摘要;数据比对时两表样本数据量大,交给 data-comparator subagent 隔离;性能优化时血缘 + 多层 DDL 每次 500~3000 tokens,交给 dw-explorer subagent 隔离。这种分工不是把步骤拆开独立执行,而是在同一个工作流里,让每个步骤以最合适的方式运行------context 压力小的步骤留在主会话保持流畅,context 压力大的步骤通过 subagent 隔离保持干净,规范检查通过 hook 自动执行不需要人工干预。

六、基于 SKILL 规范的数仓工作流设计

数仓 8 步 SKILL 规范(需求分析→技术设计→ETL→自测→数据比对→SR 导入→性能优化→SLA/DQC)天然对应 Harness 的三层机制。核心思路是:SKILL 文件不变,改变调用方式------主对话只读规范结论,实际执行由 subagent 或 hook 完成。

各步骤推荐提示词与工作流

Step 1:需求分析

推荐提示词:

用 dw-explorer subagent 先读取上游表结构(只返回摘要),
然后按需求分析规范生成:
1. 需求摘要(≤5行)
2. 表字段口径草稿
3. 待确认问题清单(按优先级排序)
需求文档 URL:[粘贴PRD链接]

Hook 配合:SessionStart 注入当前迭代约束(版本号/表名/禁止修改的表)。

Step 2:技术设计

推荐提示词:

基于上一步确认的需求,按 OneData 规范完成技术设计:
 表名:[按 层级_域_主题_粒度_周期 格式命名]
 粒度:[描述]
 分区:partition_dt string(格式 yyyyMMdd)
 禁止:任何与上游不一致的字段命名
输出 OneData 建模说明,不超过 60

CLAUDE.md 写入(设计完成后手动更新):

## 当前迭代技术设计决策- 表名:db_a.dws_table_a
- 主键:order_no + partition_dt
- 特殊约束:amount 字段继承上游千元单位,不做转换

Step 3:ETL 开发

这是 Harness 工程价值最高的步骤,PostToolUse hook 在每次 SQL 文件保存时自动触发。

推荐提示词:

按 ETL 开发规范生成建表 DDL + Insert SQL- 建表文件:ddl_[表名].sql
- 插入文件:insert_[表名].sql
- 要求:INSERT 用 OVERWRITE 模式,PARTITION 子句必须包含 partition_dt
- 金额字段:DECIMAL(20,4),单位继承上游(千元)
生成完毕后,用 sql-validator subagent 验证两个文件

Hook 自动执行(无需手动触发):每次写入 .sql 文件 → PostToolUse hook 自动运行规范检查。若发现 SELECT * 或缺少 PARTITION → 返回 exit 2,Claude 收到错误自动修正。

Step 4:自测

推荐提示词(防止自测结果撑爆主 context):

用 data-quality-checker subagent 对 [表名] 执行 23 项标准自测,
bizdate = [日期]
补充口径约束:[如"is_perform=1 只取履约订单"]
只返回:PASS/FAIL 汇总 + FAIL 项详情(≤50行),不返回原始 SQL 执行结果

效果:23 条 SQL 的执行结果全在 subagent context 里,主对话只收到一份摘要报告。

Step 5:数据比对

推荐提示词:

用 data-comparator subagent 对比:
 新表:[新表名] partition_dt = [日期]
 参考表:[旧表名/线上表]
 比对字段:[核心金额字段列表]
 容差:≤ 0.01%(金额类)
只返回:差异超过容差的字段列表 + 差值,不返回全量对比数据

Step 6:SR数据库导入

推荐提示词(自动生成最优数据库建表参数):

用 dw-sr SKILL生成建表任务, 先查以下表的 DDL 和一层上下游血缘(只返回摘要):
- 源表:[ODPS表名]
- 目标表:[SR表名]

然后基于 DDL 摘要,分析当前 SR 同步任务的配置风险:
1. 字段类型是否有精度丢失风险(DECIMAL/DOUBLE → DECIMAL(38,18))
2. Key 字段选择是否合理(重复率是否过高导致 DUPLICATE KEY 膨胀)
3. 分区数量是否合理(partition_live_number 与下游查询窗口是否匹配)
4. DISTRIBUTED BY HASH 的 bucket 数与数据量是否匹配
5. 是否有 DATETIME 字段在 SR 侧用了 VARCHAR 存储(会导致时间过滤走全表扫描)

输出同步任务配置建议(按风险高低排序),不超过 20 行。
每条格式:[风险等级 高/中/低] 问题描述 → 建议修改方式

Step 7:性能优化

推荐提示词(防止血缘查询撑爆主 context):

用 dw-explorer subagent 先查 [表名] 的一层上下游血缘和 DDL(只返回摘要),
然后分析当前 Insert SQL 的性能瓶颈:
1. 是否有全表扫描
2. 是否有笛卡尔积风险
3. 是否可以用 MAP JOIN 替代 HASH JOIN
输出优化建议(按收益排序),不超过 30

Step 8:SLA/DQC

推荐提示词:

按 SLA/DQC 规范为 [表名] 生成 9 类 DQC 规则:
 完整性:主键非空、分区数据量
 准确性:核心金额字段与上游比对(容差 0.01%)
 一致性:is_perform 与 perform_flag 联动逻辑
 时效性:产出时间 SLA ≤ 次日 8:00
输出 DQC 配置 JSON,可直接使用

SKILL 调用方式改造(减少主 context 消耗)

当前问题:触发 SKILL 时,SKILL 文件全文(约 10KB)加载进主 context,加速 compact。改造方向:

核心原则:主对话只接收决策级信息(PASS/FAIL、差异字段、优化方案),不接收过程数据(SQL 执行结果、原始血缘列表、完整 DDL 内容)。

精准对话流设计:控制AI思考的艺术

文章中多次提到 /dw-etl、/dw-自测 等命令,这是数仓研发全流程 SKILL 套件的核心触发词,每个命令对应一个封装了规范、产出格式和工具调用的标准化执行单元。核心理念:把每次都要重复讲的要求写进 SKILL,把每次都怕忘的检查点写进 SKILL,把每次都需要的结构化输出也写进 SKILL------这样谁来做需求都行,底座是一致的。

8 个 SKILL 命令一览

以 /dw-etl 为例:一条命令封装了什么?ETL 开发(Step 3)是 Harness 工程价值最高的步骤,SKILL 文件内封装了:① 规范内容(写死,不靠记忆):建表规范:分区字段必须是 partition_dt STRING(格式 YYYYMMDD);金额字段:DECIMAL(26,4),不用 DOUBLE;INSERT 模式:必须使用 INSERT OVERWRITE,必须带 PARTITION 子句;禁止:SELECT *、跨库 JOIN(非血缘关系)。② 产出格式(结构化,不走样):

输出文件:
├── ddl_[表名].sql      ← ODPS 建表语句(含注释三段式、生命周期配置)
├── insert_[表名].sql   ← ODPS Insert SQL(含分区裁剪、JOIN 规范)
└── ddl_sr_[表名].sql   ← SR 建表语句(Key 列顺序、DECIMAL 精度)

③ 自动护栏(Hook 配合):每次 .sql 文件写入后,PostToolUse hook 自动执行 validate_sql.sh;发现 SELECT * 或缺少 PARTITION → exit 2 阻断,Claude 强制修正。④ subagent 卸载(防 context 膨胀):"生成完毕后,用 sql-validator subagent 验证两个文件";验证结果全在 subagent context 里,主对话只收到"PASS/FAIL + 问题列表"。综合效益数据:

七、落地步骤

步骤一:项目级上下文持久化。在数仓项目目录下创建 .claude/CLAUDE.md,写入当前迭代状态。每次新迭代开始时更新"正在开发"和"本次迭代约束"两节,上线后清空约束节。全局规范永久保留,控制在 100 行以内。

步骤二:配置 hooks 自动验证。创建 .claude/settings.json + hooks/ 目录,配置 PostToolUse hook(每次写 .sql 后自动规范检查)和 PreToolUse hook(拦截危险 DDL)。效果:不需要每次手动说"帮我检查 SQL 规范",hook 在 Harness 层自动触发,不占用 Claude 推理资源。

步骤三:创建 subagents 隔离高 token 操作。创建三个核心 subagent 文件:sql-validator.md、dw-explorer.md、data-quality-checker.md。将 Step 4/5/7 的执行全部下放,预计主 context compact 频率降低 50%~70%。

八、Harness 工程能解决的核心问题

这一节是整个方案的出发点,也是对"为什么要这么做"的直接回答。

数仓 AI 开发当前的本质瓶颈:语义理解

在实际数仓 AI 开发中,技术能力不是瓶颈,语义理解才是。需求理解偏差占总返工的 40%~60%,大约 40%~50% 的工作时间花在理解需求和与业务核对口径上。精准血缘探查:准确率提升显著,远超传统方式。这两个观察揭示了同一个问题:AI 在数仓场景的不准确,根本原因不是"不会写 SQL",而是"不理解业务语义"------不知道这张表的 amount 单位是千元还是元,不知道 is_perform=1 在这个版本里意味着什么,不知道某字段在特定场景下会为空。

语义 × 数据 = 准确率

数仓 AI 开发的准确率,可以用一个公式来理解:

准确率 = 语义理解深度 × 数据规范覆盖度

结论:Harness 工程的本质,是把"语义"和"规范"从不可靠的 LLM 记忆中,迁移到确定性的 hooks + 持久化文件里,从而让 语义 × 规范 = 准确率 这个等式两边的变量都变得稳定。

具体能解决的四类问题

问题一:字段口径遗忘导致的计算错误

现状:对话开始时告知了"amount 字段单位是千元",compact 后 Claude 忘了,生成的 SQL 把千元当元用,导致数据差 1000 倍。Harness 解法:字段口径写进 .claude/CLAUDE.md(compact 后重新注入);踩坑经验写进 Auto Memory(跨会话持久化);结果:这类错误从"时常发生"降到"基本不出现"。

问题二:需求理解偏差导致的返工

现状:需求文档描述的是"用户视角的 GMV",但 AI 生成了"交易视角的 GMV",两者口径不同,数据对不上,需要返工。Harness 解法:需求分析的产出(口径草稿 + 待确认问题清单)写进 CLAUDE.md 的迭代约束节;Stop hook 检查任务完整性,确认待确认问题清单已全部明确后才放行;结果:需求一次交付通过率从约 50% 提升到 90%。

问题三:SQL 规范执行不一致

现状:规范文档写了"INSERT 必须带 PARTITION",但 Claude 有时会忘,或在 compact 后规范内容被清除后生成不合规的 SQL。Harness 解法:PostToolUse hook 在每次写 .sql 文件后自动执行规范检查,不依赖 Claude 记忆;违规时 exit 2 返回错误,Claude 强制修正后才能继续;结果:规范执行率从"依赖 LLM 记忆的 70%~80%"提升到"hook 强制的 95%+"。

问题四:大型需求开发中的 context 耗尽

现状:复杂需求(大型宽表、大量下游血缘)开发过程中,血缘查询 + 自测结果 + SKILL 文件内容堆满 context,compact 触发后丢失关键约束,Claude 开始犯低级错误。Harness 解法:血缘查询 → dw-explorer subagent(独立 context,只返回摘要);23 项自测 → data-quality-checker subagent(独立 context,只返回 PASS/FAIL 报告);SKILL 文件内容 → subagent 内部读取,主 context 只接收产出的 SQL 文件路径;结果:主 context compact 频率预计降低 50%~70%。

与传统数仓 AI 开发方式的对比

从"AI 帮我写代码"到"AI 嵌入研发流水线"

Harness 工程的最终目标,不是让 Claude 更聪明,而是让整个研发流水线更可靠。Claude(LLM)负责:理解需求、设计方案、生成代码------这些需要语义理解的事;Harness(hooks)负责:规范检查、危险拦截、任务完整性验证------这些需要确定性执行的事;Subagents 负责:大量文件读取、血缘查询、自测执行------这些会消耗大量 context 的事;CLAUDE.md + Memory 负责:字段口径、迭代约束、踩坑经验------这些需要跨会话持久化的事。这四层分工,让数仓 AI 开发从"对话驱动的一次性辅助"升级为"规则嵌入的流水线自动化"。

往期回顾

1.BP Claw 破解 AI 编码输入难题 ------FlinkSpec 需求智能化实践|得物技术

2.基于 Harness + SDD + 多仓管理模式的 AI 全栈开发实践|得物技术

3.通用 AI Agent 驱动网关路由安全审计实践|得物技术

4.AI驱动:从运营行为到自动化用例的智能化实践|得物技术

5.生成式召回在得物的落地技术分享与思考

文 /丹克

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。 )

2.基于 Harness + SDD + 多仓管理模式的 AI 全栈开发实践|得物技术

3.通用 AI Agent 驱动网关路由安全审计实践|得物技术

4.AI驱动:从运营行为到自动化用例的智能化实践|得物技术

5.生成式召回在得物的落地技术分享与思考

文 /丹克

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

Claude Code Harness 工程:数仓侧落地方案|得物技术

作者 得物技术
2026年5月21日 09:56

一、AI Coding 现状与痛点:为什么需要 Harness

当前使用情况

得物离线数仓各小组已基本完成 AI Coding 工具的覆盖,主力工具为 Claude Code,辅以数据平台的 IDE 插件,应对重复性工作时效率提升明显。

核心痛点

尽管整体提效已显现,但团队在实际使用中暴露出三类结构性痛点。

痛点一:AI 不记得上下文约束,开发过程中反复"失忆"。会话开始时告知了"金额字段单位是千元",对话进行到一半后 AI 忘了,生成的 SQL 把千元当元用,导致数据差了 1000 倍。这不是偶发问题,而是 Claude Code 的 context compact 机制(上下文压缩)的系统性限制:当对话 token 接近上限(约 95%)时,历史内容被自动压缩为摘要,临时口头说的约束全部丢失。

痛点二:规范执行不稳定,靠记忆兜底的部分最容易出问题。OneData 命名规范、注释三段式、INSERT 必须带 PARTITION 子句……这些规范大家都知道。在项目工期紧张时,人工规范遵守率降至 60%~70%,AI 靠 prompt 记忆的规范遵守率也只有 70%~80%。真正需要的是:把规范从"LLM 记忆中的指导性内容"变成"每次执行时强制检查的护栏"。

痛点三:大型需求开发中,context 很快被撑满,越到后期 AI 越不可靠。复杂需求(大型宽表、大量下游血缘)的典型开发过程:

血缘查询结果(500~3000 tokens) 自测 23 条 SQL 执行结果(5000~15000 tokens) SKILL 规范文件内容(~10000 tokens) 数据比对两表样本(大量行)= context 迅速膨胀 → compact 触发 → 关键约束遗忘 → AI 开始犯低级错误

核心矛盾:越是复杂的需求,越依赖 AI;但越复杂的需求,context 越容易撑满,AI 越容易"失忆"。

从"随手问 AI"到"把能力封装起来"

针对上述痛点,我们沿用了一条反复验证的结论:规范执行是人的短板、AI 的长板;业务判断是 AI 的短板、人的长板。Harness 工程的目标,就是把"执行层"的不稳定因素系统性地消掉:把规范写进 hooks,不再靠 AI 记忆,每次写 SQL 文件后自动触发检查;把迭代约束写进持久化文件,compact 后自动重新注入,不再靠临时口头说;把高 token 操作隔离到 subagent,主 context 只接收摘要,不被过程数据撑满。

二、先搞清楚"Harness"是什么

在 Claude Code 的 update-config skill 描述中有一句话:"Automated behaviors require hooks configured in settings.json — the harness executes these, not Claude"。

Harness = Claude Code 的宿主运行框架,即 Claude Code 客户端本身这个"工具链容器"。它:管理 context window 生命周期;在 LLM 推理循环之外确定性地执行 hooks;协调 subagents 的生命周期;不依赖模型判断,直接执行配置的自动化行为。区别总结:

三、核心问题:compact 到底丢掉什么?

每次数仓开发 context 接近满时,auto-compact 触发(默认 95% 时触发),会把整个对话历史替换为一份摘要,token 缩减到原来的约 12%。哪些内容 compact 后丢失:

数仓场景最痛的点:对话中说的"这次用 OVERWRITE 模式"、"先忽略 field_a 字段" → compact 后全忘;SKILL 文件读了一半,compact 后前几个 step 的内容没了 → Claude 重复询问;自测跑出来 50 行结果,加上血缘查询的几十行表结构 → context 很快膨胀到 compact 阈值。

四、五层防御体系(从简单到复杂)

第一层:写死进 CLAUDE.md(立即可用)

机制:项目根目录 .claude/CLAUDE.md 每次 compact 后从磁盘重新注入,是最可靠的持久化位置。将当前迭代的关键信息写入,格式建议:

# 当前迭代状态(每次迭代手动更新)## 正在开发- 表:db_a.dws_table_a
 版本:V1.0
 node_id:1000000001
 状态:ETL开发阶段(Step 3/8)

## 本次迭代约束- 禁止修改:dwd_table_b(已上线,只读)
 分区字段:partition_dt(格式 yyyyMMdd,不是 dt)
 amount 字段单位:千元(不是元)

## 数仓全局规范
 建表:分区字段必须是 partition_dt string
 禁止:SELECT *UPDATE/DELETEWHERE
 金额字段用 DECIMAL(20,4),不用 DOUBLE
 INSERT 必须带 PARTITION 子句

操作规则:进入新迭代时,更新"正在开发"和"本次迭代约束"两节;上线后清空"本次迭代约束";全局规范长期保留,控制在 100 行以内。

第二层:Auto Memory 自动积累(已在运行)

机制:Claude 自动将跨会话发现写入 ~/.claude/projects//memory/MEMORY.md,每次 compact 后重新注入。数仓场景下主动触发 Claude 写记忆的时机:"这张表的 amount 字段单位是千元,请记住";"field_a 在特定场景下会为空,请记住这个踩坑";"本次 V1.0 的关键变更是 field_b 逻辑调整,请记住"。Claude 会自动写入 MEMORY.md,下次会话或 compact 后自动恢复。

第三层:hooks 自动验证(核心防御,解决"忘了检查"的问题)

这是解决"每次写完 SQL 自动检查"的关键机制。

配置文件位置

数仓项目根目录/
└── .claude/
    ├── settings.json          ← hooks 在这里配置
    ├── CLAUDE.md              ← 数仓规范上下文
    └── hooks/
        ├── validate_sql.sh          ← SQL 规范自动检查
        ├── block_dangerous_ddl.sh   ← 危险 DDL 拦截
        └── inject_context.sh        ← compact 后重注入上下文

settings.json 完整配置

{"hooks": {"PostToolUse": [{"matcher": "Write|Edit","hooks": [{"type": "command","command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/validate_sql.sh","timeout": 60,"statusMessage": "检查 SQL 规范..."}]}],"PreToolUse": [{"matcher": "Bash","hooks": [{"type": "command","command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block_dangerous_ddl.sh"}]}],"SessionStart": [{"matcher": "compact","hooks": [{"type": "command","command": "cat \"$CLAUDE_PROJECT_DIR\"/.claude/context/dw_conventions.md","statusMessage": "重注入数仓规范..."}]}],"Stop": [{"hooks": [{"type": "prompt","prompt": "检查用户要求的所有任务是否都已完成。如果还有未完成项,返回提示但不要重新开始。检查 stop_hook_active 是否为 true,如是则直接 exit。","model": "claude-haiku-4-5-20251001"}]}]}}

SQL 规范自动检查脚本

.claude/hooks/validate_sql.sh:

#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo"$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('file_path',''))" 2>/dev/null)

# 只处理 .sql 文件
[[ "$FILE_PATH" != *.sql ]] && exit 0
[[ -z "$FILE_PATH" ]] && exit 0

SQL=$(cat "$FILE_PATH" 2>/dev/null)
[[ -z "$SQL" ]] && exit 0

ERRORS=()

# 规范1:禁止 SELECT *echo "$SQL" | grep -iqE 'SELECT\s+\*' && ERRORS+=("CRITICAL: 发现 SELECT *,必须明确列名")

# 规范2:INSERT 必须带 PARTITIONif echo "$SQL" | grep -iqE 'INSERT\s+(INTO|OVERWRITE)'; thenecho "$SQL" | grep -iqE 'PARTITION\s*\(' || ERRORS+=("CRITICAL: INSERT 缺少 PARTITION 子句")
fi# 规范3:DOUBLE 类型金额echo "$SQL" | grep -iqE '\bDOUBLE\b' && ERRORS+=("WARNING: 金额字段建议用 DECIMAL(20,4),不用 DOUBLE")

# 规范4:UPDATE/DELETE 必须有 WHEREif echo "$SQL" | grep -iqE '\b(UPDATE|DELETE)\b'; thenecho "$SQL" | grep -iqE '\bWHERE\b' || ERRORS+=("CRITICAL: UPDATE/DELETE 缺少 WHERE 条件")
fiif [ ${#ERRORS[@]} -gt 0 ]; thenecho "=== SQL 规范检查失败:$FILE_PATH ===" >&2
  for err in"${ERRORS[@]}"; doecho "  $err" >&2
  doneexit 2
fiecho "SQL 规范检查通过: $(basename $FILE_PATH)" >&2
exit 0

危险 DDL 拦截脚本

.claude/hooks/block_dangerous_ddl.sh:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo"$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('command',''))" 2>/dev/null)

# 拦截生产表 DROP/TRUNCATE(放行 _dev/_test/_stg 后缀)if echo "$CMD" | grep -iqE '\b(DROP\s+TABLE|TRUNCATE\s+TABLE)\b'; thenif ! echo "$CMD" | grep -qiE '(_dev|_test|_stg)\b'; thenecho "BLOCKED: 检测到生产表 DROP/TRUNCATE 操作,请确认表名是否正确" >&2
    exit 2
  fifiexit 0

hook 通信协议关键规则

图片

关键陷阱:阻断必须用 exit 2,用 exit 1 不会阻止 Claude 继续执行。

第四层:subagents 做上下文隔离(防 context 膨胀)

核心原则:把"高 token 消耗但结果只需要摘要"的操作放到 subagent 的独立 context 中执行。

数仓场景适合下放 subagent 的操作

图片

创建 subagent 文件

.claude/agents/sql-validator.md(SQL 语法验证):

---
name: sql-validator
description: ODPS/MaxCompute SQL 语法验证与规范检查专用 agent。当用户生成或修改 SQL 文件后需要验证时调用。在独立 context 运行,防止大量验证日志污染主对话。
tools: Read, Bash, Grep, Glob
model: haiku
permissionMode: dontAsk
---

你是数仓 SQL 规范专家,只做验证,不修改文件。

验证项(按优先级):
1. SELECT * 禁止
2. INSERT 必须带 PARTITION
3. 字段用 snake_case 命名
4. 金额字段用 DECIMAL 不用 DOUBLE
5. 多表 JOIN 必须有 ON 条件
6. 笛卡尔积风险检测

输出格式:
- 状态:PASS / FAIL
- 问题列表(CRITICAL / WARNING / INFO)
- 修改建议(具体到行号)

不超过 50 行,只返回结构化报告。

.claude/agents/dw-explorer.md(防止血缘查询撑爆主 context):


---
name: dw-explorer
description: 数仓结构探索 agent。当需要大量读取表结构、DDL、字段信息、血缘关系时自动调用,避免大量文件内容污染主 context。只读,不修改任何文件。
tools: Read, Glob, Grep, Bash
model: haiku
permissionMode: dontAsk
---

你是数仓探索专家,只读操作。

当被调用时:
1. 读取指定表的 DDL、字段信息、分区策略
2. 分析上下游血缘(一层)
3. 识别关键字段口径(金额、日期、状态类字段)

输出:不超过 80 行的结构化摘要,包含:
- 表基本信息(层级、粒度、分区策略)
- 核心字段定义(含口径说明)
- 上下游血缘(只列表名,不展开内容)
- 发现的特殊口径或踩坑点

使用方式

在主对话中自然触发:

用 dw-explorer 分析 db_a.dwd_table_a 的结构

对刚生成的 insert_dws_table_a.sql 用 sql-validator 验证

或强制指定(避免 Claude 自行判断):

@"sql-validator (agent)" 验证 path/to/insert.sql

第五层:SKILL 文件改造(减少 context 消耗)

当前的问题:每次调用 SKILL 文件(01~08.md),内容全部加载进主 context,加速 compact 触发。改造方向:把 SKILL 文件的"执行步骤"提炼成 subagent 指令,subagent 内部读完整 SKILL 文件,主 context 只接收结果摘要;用 path-scoped rules 替代 SKILL 文件中的规范章节,按需加载:

---
# .claude/rules/etl-rules.md
paths:
  - "**/*insert*.sql"
  - "**/*_di.sql"
  - "**/*_df.sql"
---

# ETL 开发规范(按文件路径自动加载)
- 必须有 partition_dt 分区
- INSERT OVERWRITE 前检查分区是否已存在
- 不允许跨库 JOIN

SKILL 文件保持现状,但改变调用方式:不要在主对话中直接触发,而是启动一个 subagent 来读 SKILL 文件执行 ETL,主对话只接收最终产出的 SQL 文件路径。

五、可行落地方案:数仓 Harness 架构

先让我们看一下整体的架构设计(整体架构图):

图片

这张架构图的核心逻辑是职责分层:不同类型的工作交给最合适的机制去做,而不是全部压在 Claude 的推理循环里。

持久化层解决的是"失忆"问题,任何临时口头说的约束,compact 后都会消失;但写进 .claude/CLAUDE.md 的内容,每次会话启动和 compact 后都会从磁盘重新注入——这是整套方案里最简单也最可靠的一层。

Harness 层(Hooks) 解决的是"规范靠记忆"的问题,PostToolUse hook 在每次写 .sql 文件后确定性触发,不依赖 Claude 有没有记住规范要求;违规时 exit 2 强制阻断,Claude 必须修正后才能继续,规范遵守率从 70%80% 提升到 95%+。

Subagent 层解决的是"context 被撑满"的问题,血缘查询、23 项自测、数据比对这类操作会产生大量 token,放到独立 context 的 subagent 里执行,主会话只接收一份摘要,compact 触发频率预计降低 50%70%。

三层机制分工明确,互不干扰:Hooks 处理"写动作触发的规范检查",subagent 处理"读操作的 context 隔离",CLAUDE.md 处理"跨会话状态持久化"。为了配合这套架构落地,数仓的研发流程可以拆解为 8 个大的步骤,流程图如下:

图片

从 Harness 架构的视角来看,8 个步骤可以按"对 context 的影响"分成两类:一类是直接在主会话处理(内容量有限,context 压力低):需求分析(读 PRD)、技术设计(写规范说明)、SR 导入(生成配置)、SLA/DQC(生成规则)。另一类必须通过 Harness 机制处理(否则会加速 compact 或规范失控):ETL 开发每次写 .sql 文件,PostToolUse hook 自动触发规范检查,不依赖人工提醒;自测时 23 条 SQL 的执行结果体量大,交给 data-quality-checker subagent 隔离,主会话只收 PASS/FAIL 摘要;数据比对时两表样本数据量大,交给 data-comparator subagent 隔离;性能优化时血缘 + 多层 DDL 每次 500~3000 tokens,交给 dw-explorer subagent 隔离。这种分工不是把步骤拆开独立执行,而是在同一个工作流里,让每个步骤以最合适的方式运行——context 压力小的步骤留在主会话保持流畅,context 压力大的步骤通过 subagent 隔离保持干净,规范检查通过 hook 自动执行不需要人工干预。

六、基于 SKILL 规范的数仓工作流设计

数仓 8 步 SKILL 规范(需求分析→技术设计→ETL→自测→数据比对→SR 导入→性能优化→SLA/DQC)天然对应 Harness 的三层机制。核心思路是:SKILL 文件不变,改变调用方式——主对话只读规范结论,实际执行由 subagent 或 hook 完成。

图片

各步骤推荐提示词与工作流

Step 1:需求分析

推荐提示词:

用 dw-explorer subagent 先读取上游表结构(只返回摘要),
然后按需求分析规范生成:
1. 需求摘要(≤5行)
2. 表字段口径草稿
3. 待确认问题清单(按优先级排序)
需求文档 URL:[粘贴PRD链接]

Hook 配合:SessionStart 注入当前迭代约束(版本号/表名/禁止修改的表)。

Step 2:技术设计

推荐提示词:

基于上一步确认的需求,按 OneData 规范完成技术设计:
 表名:[按 层级_域_主题_粒度_周期 格式命名]
 粒度:[描述]
 分区:partition_dt string(格式 yyyyMMdd)
 禁止:任何与上游不一致的字段命名
输出 OneData 建模说明,不超过 60

CLAUDE.md 写入(设计完成后手动更新):

## 当前迭代技术设计决策- 表名:db_a.dws_table_a
- 主键:order_no + partition_dt
- 特殊约束:amount 字段继承上游千元单位,不做转换

Step 3:ETL 开发

这是 Harness 工程价值最高的步骤,PostToolUse hook 在每次 SQL 文件保存时自动触发。

推荐提示词:

按 ETL 开发规范生成建表 DDL + Insert SQL- 建表文件:ddl_[表名].sql
- 插入文件:insert_[表名].sql
- 要求:INSERT 用 OVERWRITE 模式,PARTITION 子句必须包含 partition_dt
- 金额字段:DECIMAL(20,4),单位继承上游(千元)
生成完毕后,用 sql-validator subagent 验证两个文件

Hook 自动执行(无需手动触发):每次写入 .sql 文件 → PostToolUse hook 自动运行规范检查。若发现 SELECT * 或缺少 PARTITION → 返回 exit 2,Claude 收到错误自动修正。

Step 4:自测

推荐提示词(防止自测结果撑爆主 context):

用 data-quality-checker subagent 对 [表名] 执行 23 项标准自测,
bizdate = [日期]
补充口径约束:[如"is_perform=1 只取履约订单"]
只返回:PASS/FAIL 汇总 + FAIL 项详情(≤50行),不返回原始 SQL 执行结果

效果:23 条 SQL 的执行结果全在 subagent context 里,主对话只收到一份摘要报告。

Step 5:数据比对

推荐提示词:

用 data-comparator subagent 对比:
 新表:[新表名] partition_dt = [日期]
 参考表:[旧表名/线上表]
 比对字段:[核心金额字段列表]
 容差:≤ 0.01%(金额类)
只返回:差异超过容差的字段列表 + 差值,不返回全量对比数据

Step 6:SR数据库导入

推荐提示词(自动生成最优数据库建表参数):

用 dw-sr SKILL生成建表任务, 先查以下表的 DDL 和一层上下游血缘(只返回摘要):
- 源表:[ODPS表名]
- 目标表:[SR表名]

然后基于 DDL 摘要,分析当前 SR 同步任务的配置风险:
1. 字段类型是否有精度丢失风险(DECIMAL/DOUBLE → DECIMAL(38,18))
2. Key 字段选择是否合理(重复率是否过高导致 DUPLICATE KEY 膨胀)
3. 分区数量是否合理(partition_live_number 与下游查询窗口是否匹配)
4. DISTRIBUTED BY HASH 的 bucket 数与数据量是否匹配
5. 是否有 DATETIME 字段在 SR 侧用了 VARCHAR 存储(会导致时间过滤走全表扫描)

输出同步任务配置建议(按风险高低排序),不超过 20 行。
每条格式:[风险等级 高/中/低] 问题描述 → 建议修改方式

Step 7:性能优化

推荐提示词(防止血缘查询撑爆主 context):

用 dw-explorer subagent 先查 [表名] 的一层上下游血缘和 DDL(只返回摘要),
然后分析当前 Insert SQL 的性能瓶颈:
1. 是否有全表扫描
2. 是否有笛卡尔积风险
3. 是否可以用 MAP JOIN 替代 HASH JOIN
输出优化建议(按收益排序),不超过 30

Step 8:SLA/DQC

推荐提示词:

按 SLA/DQC 规范为 [表名] 生成 9 类 DQC 规则:
 完整性:主键非空、分区数据量
 准确性:核心金额字段与上游比对(容差 0.01%)
 一致性:is_perform 与 perform_flag 联动逻辑
 时效性:产出时间 SLA ≤ 次日 8:00
输出 DQC 配置 JSON,可直接使用

SKILL 调用方式改造(减少主 context 消耗)

当前问题:触发 SKILL 时,SKILL 文件全文(约 10KB)加载进主 context,加速 compact。改造方向:

图片

核心原则:主对话只接收决策级信息(PASS/FAIL、差异字段、优化方案),不接收过程数据(SQL 执行结果、原始血缘列表、完整 DDL 内容)。

精准对话流设计:控制AI思考的艺术

文章中多次提到 /dw-etl、/dw-自测 等命令,这是数仓研发全流程 SKILL 套件的核心触发词,每个命令对应一个封装了规范、产出格式和工具调用的标准化执行单元。核心理念:把每次都要重复讲的要求写进 SKILL,把每次都怕忘的检查点写进 SKILL,把每次都需要的结构化输出也写进 SKILL——这样谁来做需求都行,底座是一致的。

8 个 SKILL 命令一览

图片

以 /dw-etl 为例:一条命令封装了什么?ETL 开发(Step 3)是 Harness 工程价值最高的步骤,SKILL 文件内封装了:① 规范内容(写死,不靠记忆):建表规范:分区字段必须是 partition_dt STRING(格式 YYYYMMDD);金额字段:DECIMAL(26,4),不用 DOUBLE;INSERT 模式:必须使用 INSERT OVERWRITE,必须带 PARTITION 子句;禁止:SELECT *、跨库 JOIN(非血缘关系)。② 产出格式(结构化,不走样):

输出文件:
├── ddl_[表名].sql      ← ODPS 建表语句(含注释三段式、生命周期配置)
├── insert_[表名].sql   ← ODPS Insert SQL(含分区裁剪、JOIN 规范)
└── ddl_sr_[表名].sql   ← SR 建表语句(Key 列顺序、DECIMAL 精度)

③ 自动护栏(Hook 配合):每次 .sql 文件写入后,PostToolUse hook 自动执行 validate_sql.sh;发现 SELECT * 或缺少 PARTITION → exit 2 阻断,Claude 强制修正。④ subagent 卸载(防 context 膨胀):"生成完毕后,用 sql-validator subagent 验证两个文件";验证结果全在 subagent context 里,主对话只收到"PASS/FAIL + 问题列表"。综合效益数据:

图片

七、落地步骤

步骤一:项目级上下文持久化。在数仓项目目录下创建 .claude/CLAUDE.md,写入当前迭代状态。每次新迭代开始时更新"正在开发"和"本次迭代约束"两节,上线后清空约束节。全局规范永久保留,控制在 100 行以内。

步骤二:配置 hooks 自动验证。创建 .claude/settings.json + hooks/ 目录,配置 PostToolUse hook(每次写 .sql 后自动规范检查)和 PreToolUse hook(拦截危险 DDL)。效果:不需要每次手动说"帮我检查 SQL 规范",hook 在 Harness 层自动触发,不占用 Claude 推理资源。

步骤三:创建 subagents 隔离高 token 操作。创建三个核心 subagent 文件:sql-validator.md、dw-explorer.md、data-quality-checker.md。将 Step 4/5/7 的执行全部下放,预计主 context compact 频率降低 50%~70%。

八、Harness 工程能解决的核心问题

这一节是整个方案的出发点,也是对"为什么要这么做"的直接回答。

数仓 AI 开发当前的本质瓶颈:语义理解

在实际数仓 AI 开发中,技术能力不是瓶颈,语义理解才是。需求理解偏差占总返工的 40%~60%,大约 40%~50% 的工作时间花在理解需求和与业务核对口径上。精准血缘探查:准确率提升显著,远超传统方式。这两个观察揭示了同一个问题:AI 在数仓场景的不准确,根本原因不是"不会写 SQL",而是"不理解业务语义"——不知道这张表的 amount 单位是千元还是元,不知道 is_perform=1 在这个版本里意味着什么,不知道某字段在特定场景下会为空。

语义 × 数据 = 准确率

数仓 AI 开发的准确率,可以用一个公式来理解:

准确率 = 语义理解深度 × 数据规范覆盖度

图片

结论:Harness 工程的本质,是把"语义"和"规范"从不可靠的 LLM 记忆中,迁移到确定性的 hooks + 持久化文件里,从而让 语义 × 规范 = 准确率 这个等式两边的变量都变得稳定。

具体能解决的四类问题

问题一:字段口径遗忘导致的计算错误

现状:对话开始时告知了"amount 字段单位是千元",compact 后 Claude 忘了,生成的 SQL 把千元当元用,导致数据差 1000 倍。Harness 解法:字段口径写进 .claude/CLAUDE.md(compact 后重新注入);踩坑经验写进 Auto Memory(跨会话持久化);结果:这类错误从"时常发生"降到"基本不出现"。

问题二:需求理解偏差导致的返工

现状:需求文档描述的是"用户视角的 GMV",但 AI 生成了"交易视角的 GMV",两者口径不同,数据对不上,需要返工。Harness 解法:需求分析的产出(口径草稿 + 待确认问题清单)写进 CLAUDE.md 的迭代约束节;Stop hook 检查任务完整性,确认待确认问题清单已全部明确后才放行;结果:需求一次交付通过率从约 50% 提升到 90%。

问题三:SQL 规范执行不一致

现状:规范文档写了"INSERT 必须带 PARTITION",但 Claude 有时会忘,或在 compact 后规范内容被清除后生成不合规的 SQL。Harness 解法:PostToolUse hook 在每次写 .sql 文件后自动执行规范检查,不依赖 Claude 记忆;违规时 exit 2 返回错误,Claude 强制修正后才能继续;结果:规范执行率从"依赖 LLM 记忆的 70%~80%"提升到"hook 强制的 95%+"。

问题四:大型需求开发中的 context 耗尽

现状:复杂需求(大型宽表、大量下游血缘)开发过程中,血缘查询 + 自测结果 + SKILL 文件内容堆满 context,compact 触发后丢失关键约束,Claude 开始犯低级错误。Harness 解法:血缘查询 → dw-explorer subagent(独立 context,只返回摘要);23 项自测 → data-quality-checker subagent(独立 context,只返回 PASS/FAIL 报告);SKILL 文件内容 → subagent 内部读取,主 context 只接收产出的 SQL 文件路径;结果:主 context compact 频率预计降低 50%~70%。

与传统数仓 AI 开发方式的对比

图片

从"AI 帮我写代码"到"AI 嵌入研发流水线"

Harness 工程的最终目标,不是让 Claude 更聪明,而是让整个研发流水线更可靠。Claude(LLM)负责:理解需求、设计方案、生成代码——这些需要语义理解的事;Harness(hooks)负责:规范检查、危险拦截、任务完整性验证——这些需要确定性执行的事;Subagents 负责:大量文件读取、血缘查询、自测执行——这些会消耗大量 context 的事;CLAUDE.md + Memory 负责:字段口径、迭代约束、踩坑经验——这些需要跨会话持久化的事。这四层分工,让数仓 AI 开发从"对话驱动的一次性辅助"升级为"规则嵌入的流水线自动化"。

往期回顾

1.BP Claw 破解 AI 编码输入难题 ——FlinkSpec 需求智能化实践|得物技术

2.基于 Harness + SDD + 多仓管理模式的 AI 全栈开发实践|得物技术

3.通用 AI Agent 驱动网关路由安全审计实践|得物技术

4.AI驱动:从运营行为到自动化用例的智能化实践|得物技术

5.生成式召回在得物的落地技术分享与思考

文 /丹克

关注得物技术,每周三更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

BP Claw 破解 AI 编码输入难题 ——FlinkSpec 需求智能化实践|得物技术

作者 得物技术
2026年5月14日 13:30

一句话理解 BP Claw:它是 FlinkSpec 上游的 “AI 数据 BP”,把产品经理的非标 PRD 自动转化为 AI Coding 可消费的高质量需求文档。在深入阅读之前,先用一张表告诉你 BP Claw 能带来什么。

image.png

如果你的团队也在被以下问题困扰,这篇文章值得读完:AI Coding 效果不稳定,同样的框架、不同的需求,结果天差地别;需求沟通来回反复,一个指标口径要确认三四轮;PRD 质量参差不齐,开发阶段频繁踩雷、返工延期。BP Claw 的答案是:问题的根源在输入,解法在源头。

一、FlinkSpec:实时数仓的 AI 工程化底座

在深入 BP Claw 之前,我们先来看一个更大的图景 ——FlinkSpec。FlinkSpec 是实时数仓团队打造的 AI 工程化开发框架,它以 “需求驱动、制品为锚” 的理念,将一条实时数据链路的生命周期拆解为四个阶段,每个阶段都有严格的门控评估,确保交付质量。

FlinkSpec 全景架构

image.png

BP Claw 在 FlinkSpec 中的定位

在 FlinkSpec 的四个阶段中,需求澄清阶段是一切的起点。而需求澄清阶段的质量,取决于一个关键输入 ——PRD 文档。如果 PRD 质量不达标,后续的一切都是空中楼阁:需求定义模糊 → Intake 门控反复打回 → Define 阶段耗时翻倍;技术口径缺失 → Flink-SQL Agent 无法编码 → 频繁触发阻塞协议(BLOCK-N);验收标准不清 → Review 阶段发现问题 → 回退到 Define 重来。

image.png

BP Claw 解决实际问题案例

问题定义

商业化广告投放链路中,一次广告曝光往往由多个商家共同参与竞价。这种一对多的流量-主体映射关系,在指标聚合时会产生一个结构性的歧义:以"商家"为维度下钻时,同一次流量事件会被多个商家各自计入,导致商家侧明细加总后,与平台侧总量不等。这不是数据质量问题,而是两套在各自语义下都正确的口径共存在同一张宽表里,却没有被显式区分:impression_cnt(平台侧)去重到流量维度,一次曝光 = 1;impression_cnt(商家侧)展开到主体维度,N 个商家参与 = N。当下游消费方使用同一个字段名、却按不同语义聚合时,CTR、CVR、ROI 等衍生指标就会系统性失真。

为什么难以在开发阶段发现

实时数仓的指标开发通常以 FlinkSQL 为载体,开发侧看到的输入是 Kafka 事件流和维度表,字段语义的边界在建模时已经隐式确定。问题在于: FlinkSQL 层面的 GROUP BY 逻辑无法自动感知上游指标应该以哪个粒度聚合。如果流量事件里同时携带了 advertiser_id 列表,不同的展开方式对应完全不同的业务语义,而这一选择在代码里只是一行 UNNEST 或一个 JOIN 的差异。常规的 Code Review 能发现 SQL 逻辑错误,却很难发现"SQL 逻辑正确、但口径选择与业务预期不符"这类问题——因为两种写法都能跑通,数据差异在没有对比基准的情况下也不会报错。

BP Claw 的介入点

BP Claw 作为需求到编码之间的中间层,其核心能力是在指标定义阶段做口径显式化,而不是在开发完成后做数据校验。

具体做法是结合 OpenViking 知识库(团队历史建模文档、字段定义、历史踩坑记录)做语义召回,识别当前需求涉及的指标是否存在多粒度歧义,并在进入 FlinkSpec 之前,将以下约束显式写入需求文档:

image.png

这套约束作为 FlinkSpec 的输入,让 AI Coding 在生成 DDL 和 INSERT 逻辑时,直接基于已经对齐的语义边界,而不是从模糊描述中自行推断。

与通用 AI Coding 的差异

通用 AI Coding 工具在给定输入后,会选择一种"看起来合理"的实现——对于多商家指标,它会倾向于展开商家维度(因为需求里写了"按商家查看"),但不会主动判断这是否会导致平台侧口径膨胀。

BP Claw 的差异在于知识来源:它使用的不是通用语言模型对业务逻辑的推断,而是团队在同类建模问题上积累的历史决策和约束条件。对于"多商家指标是否需要分口径建模"这个问题,OpenViking 里已经有过明确结论,BP Claw 将其召回并作为强约束注入当前需求,而不是重新推断一次。

BP Claw 正是为了解决这个"源头问题"而生。它站在 FlinkSpec 的上游,确保进入 Define 阶段的 PRD 文档质量足够支撑后续的 AI 自动化编码。

二、产品设计:从痛点出发的解决方案

面向谁?解决什么?

image.png

设计哲学:贴合工作流,而非改造工作流

BP Claw 的设计遵循三条核心原则,原则一:嵌入现有场景——用户不需要打开新页面、学习新工具,直接在飞书群聊中 @ 机器人即可触发,和日常"拉群评审"的行为完全一致;原则二:产品经理零感知提效——产品经理只需要提交原始 PRD 文档,BP Claw 自动完成规范化转换,产品经理无需关心格式,产品经理收到的是结构化、高质量的评审群,而非一堆格式要求;原则三:不硬卡点,做参照系——PRD 评分是"参照",不是"阻塞",帮助团队建立质量意识,而非制造流程摩擦,逐步提升 PRD 质量基线,而非一刀切。

三、核心能力层

对实时数仓而言,一份好的 PRD 应该是什么样的?

在深入技术实现之前,我们先回答一个根本性问题:实时数仓对 PRD 文档的要求是什么?一份好的实时数仓 PRD,需要覆盖七大模块:

image.png

然而,产品经理提交的文档往往只覆盖了其中的 2-3 个模块,而且格式五花八门。这正是 BP Claw 要解决的核心问题 —— 需求转化。

能力一:智能需求转化(核心能力)

这是 BP Claw 最核心、最有技术含量的能力。它做的事情,本质上是 模拟一个经验丰富的数据 BP 的工作过程。

转化过程详解

image.png

转化的技术难点

如何处理常见的业务需求类型?我们总结了实时数仓中最常见的几类需求模式:

image.png

转化的核心原则:忠实于原文

原文有的信息进行结构化提取,按模板填充;原文没有的信息标记为待补充,绝不凭空捏造;原文有歧义的信息保留原始表述,同时标注歧义点;原文划删除线的标注为"本期不纳入,暂缓"。

能力二:PRD 质量评分(参照能力)

在完成需求转化后,BP Claw 会对标准化文档进行多维度质量评估,生成诊断报告。

五大评分维度

image.png

三条核心评分规则

规则一:技术口径一票否决——如果技术口径得分 < 15 分(满分 25),即使总分 ≥ 90,也标注为不可执行。原因:没有技术口径,FlinkSpec 的 Flink-SQL Agent 完全无法启动编码。规则二:验收标准缺失扣分——验收标准完全缺失,总分直接扣除 20 分;严重不足(≤5 分),扣除 10 分。原因:没有验收标准的需求,上线即翻车。规则三:溢出得分机制——某维度特别优秀可超出该维度满分,但总分上限仍为 100 分。原因:鼓励在关键维度上做到极致。

image.png

需要强调的是:PRD 评分不是硬卡点,不是流程阻塞。它是一面镜子,帮助团队看到当前 PRD 的质量水位,逐步建立质量意识。

能力三:自动拉群(工作流融合能力)

自动拉群看似简单,但它承载着一个重要的产品设计意图——降低落地阻碍。为什么做自动拉群?如果 BP Claw 只能生成文档,用户还需要手动拉群、手动 @ 人、手动转发文档,那使用体验就是割裂的。自动拉群让整个流程变成了"一步触发、全程自动":用户只需要在飞书群里 @ 机器人、@ 评审人,附上文档链接。BP Claw 自动完成:读取文档 → 生成标准化文档 → 质量评估 → 创建评审群 → 邀请成员 → 发送文档和诊断报告。评审人在新群里直接看到结构化的文档和质量报告,开始评审。这就是"贴合现有工作流"的具体体现——用户的行为没有变,但背后的效率翻了20倍。

四、技术难点与解决方案

省 Token 的技巧

在 AI 应用中,Token 消耗直接关系到成本和响应速度。BP Claw 在这方面做了多项优化。

技巧一:分段生成策略

对于包含 10 个以上指标的大文档,我们不会一次性生成完整文档(这会导致上下文溢出),而是采用分段生成:先创建文档骨架(业务背景 + 角色-页面-指标矩阵),逐个追加指标定义模块,每追加 5 个指标发送一次进度反馈,最后追加验收标准和用数链路。本质是把"一次大事务"拆成"多次小提交",即使中途失败也保留了已写入内容,不需要从头来。同时每段写入后向群聊发送进度消息(已生成 5/12 个指标),让用户有等待感知,不会误以为机器人卡死。收益:避免单次 API 调用超时,同时减少重复上下文传递的 Token 消耗。

技巧二:分层调用架构

BP Claw 采用编排者(动态调度,按需组合 Skill,职责清晰)模式,将核心逻辑拆分到三个独立 Skill 中:

image.png

每个 Skill 独立运行、独立管理上下文,避免了将所有逻辑放在同一个上下文中导致的 Token 膨胀。

技巧三:模板化 Prompt 设计

标准化文档的七大模块,每个模块都有严格定义的模板结构。通过模板约束 AI 的输出格式,避免了冗余输出:明确指定输出字段,不多不少;使用 Markdown 表格约束结构;通过 Few-Shot 示例引导输出风格。

稳定性保障:如何避免幻觉?

这是 BP Claw 最重要的技术挑战。AI 生成的文档如果出现"幻觉"(编造不存在的业务口径),后果比不生成还严重。

策略一:严格的忠实性约束

在 Skill 的核心 Prompt 中,我们设置了多层约束:

核心规则:忠实于源材料原文有的 → 结构化提取原文没有的 → 标记 ⚠️ 待补充绝不凭空发明业务定义绝不猜测技术口径

策略二:标记机制取代猜测

当 AI 遇到无法确定的信息时,不允许"猜测后继续",而是必须:明确标记为待补充;说明缺失的具体内容;给出建议补充的方向。这样做的好处是:用户看到的文档中,每一条确定的信息都是可信的。

策略三:质量评分的交叉验证

prd-quality-scorer 作为独立的评分 Skill,会对生成的文档进行"第二遍"审查。如果文档中存在明显的逻辑矛盾或不合理之处,评分报告中会直接指出。

策略四:参数校验与重试机制

• 调用飞书 API 前,强制校验所有必填参数• 文档生成失败 → 最多重试 3 次(间隔 2s → 5s → 10s 指数退避)• 3 次均失败 → 终止流程,发送明确的错误消息• 绝不降级生成"简化版"文档(不完整不如不生成)

打磨 Skill 的技巧与难点

难点一:如何让 AI 理解"实时数仓"的领域语义?普通的 LLM 并不理解"去重视图""Lookup Join""sink.properties.columns"这些领域概念。我们通过以下方式解决:领域知识注入(在 Skill 定义中嵌入实时数仓的核心概念解释);模板驱动(通过模板结构限定输出范围,减少 AI 的"自由发挥空间");Few-Shot 示例(提供真实的标准化 PRD 样例作为参考)。

难点二:如何处理超长文档?有些 PRD 文档超过 10000 字符、包含 15+ 指标,直接处理会导致 API 超时(默认 60 秒不够用)、Token 超限、输出截断。解决方案:显式设置 timeoutSeconds=1200(20 分钟);采用分段生成策略,每次只处理 3-5 个指标;实时进度反馈,让用户知道系统仍在工作。

难点三:如何协调多个 Skill 的执行顺序?BP Claw 作为"指挥家/编排者",需要严格控制 4 个步骤的执行顺序和依赖关系:

规则:严格串行,前序成功才执行后续STEP 1 成功 → STEP 2STEP 2 成功 → STEP 3STEP 3 成功或失败 → STEP 4(评分失败不阻塞)STEP 4 成功 → 完成任一关键步骤失败 → 立即终止,通知用户

为什么 STEP 3 失败不阻塞?因为质量评分是"参照"而非"卡点"。即使评分失败,标准化文档和评审群依然有价值。

五、与 FlinkSpec 的联动:全链路赋能

BP Claw → FlinkSpec 的价值传递

image.png

体验效果:PRD 质量提升对 AI Coding 的赋能

场景一:技术口径完整的 PRD——BP Claw 评分 ≥ 90 分,FlinkSpec Define 阶段一次通过,无 BLOCK,Flink-SQL Agent 直接编码无需人工干预,整体交付周期为天级 ⏱️。场景二:技术口径缺失的 PRD——BP Claw 评分 < 60 分,触发技术口径一票否决,FlinkSpec Define 阶段频繁触发阻塞协议,Flink-SQL Agent 无法编码需反复沟通,整体交付周期为周级。结论: BP Claw 每提升 10 分的 PRD 质量,FlinkSpec 的编码阶段效率约提升 30%。

六、落地运营:产品 + 运营 = 真正的落地

一个好的产品工具,如果没有运营手段的配合,是无法真正落地的。BP Claw 在落地过程中,我们采用了产品能力 + 运营能力双轮驱动的策略。

运营手段一:成熟度评分体系

我们建立了 域级 PRD 成熟度评分 机制,通过持续追踪各业务域的 PRD 质量水位,推动整体提升:

image.png

运营手段二:质量趋势追踪

通过持续收集每次 PRD 评分数据,建立质量趋势看板:按业务域维度追踪质量变化;识别高频缺失项,定向改进;月度质量复盘,表彰优秀案例。

运营手段三:最佳实践沉淀

将高分 PRD 案例沉淀为模板,形成可复用的知识资产:优秀案例库(≥ 90 分的 PRD 自动入库);改进指南(针对常见扣分项提供标准化的补充模板);新人培训(通过 BP Claw 评分报告快速上手 PRD 编写规范)。

七、快速上手

使用方法

只需一步:在飞书群聊中发送一条消息:

@商业化MOSS @评审人1 @评审人2 @评审人N.... 需求拉群 飞书PRD文档链接

image.png

然后等待 1-5 分钟,你将在新的评审群中看到:标准化 PRD 文档、质量诊断报告、改进建议清单。

注意事项

image.png

八、展望后续

本文为 FlinkSpec 系列之开篇,亦是这场工程化变革的序章。BP Claw 所立之处,不过链路之源。FlinkSpec 所图,乃以 AI 之力,将实时数仓从需求落地至验收上线的全程工序,熔铸为一套精密自洽、生生不息的智能工程体系。宏图未竟,后续系列将逐章揭幕,敬请期待!

往期回顾

1.基于 Harness + SDD + 多仓管理模式的 AI 全栈开发实践|得物技术

2.通用 AI Agent 驱动网关路由安全审计实践|得物技术

3.AI驱动:从运营行为到自动化用例的智能化实践|得物技术

4.生成式召回在得物的落地技术分享与思考

5.立正请站好:一个组件复用 Skill 的工程化实践|得物技术

文 /子宸

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

通用 AI Agent 驱动网关路由安全审计实践

作者 得物技术
2026年4月30日 09:57

本项目构建了一个网关路由 AI 安全审计系统,采用"通用 Agent + 业务 Skill"分层设计,增量日检/存量月检。落地 Open 网关路由越权漏洞检测流程,通过 AI 批量筛查 + 人工深度验证的人机协同模式,为大规模 API 安全审计提供了可复用的智能化解决方案。充分发挥通用 Agent 能力,业务逻辑在 Skill 中快速迭代。

一、背景与技术方案

安全审计的核心挑战

随着平台 API 规模持续扩张,安全审计面临新的规模化挑战。

image.png

主要挑战:

  • 覆盖面不足:抽样审计约覆盖 ~20%
  • 时效性压力:新接口需要更快的安全评估
  • 规则一致性:标准化检测规则难以沉淀

技术选型与建设契机

当前,以大型语言模型为基座的 AI Agent 在代码语义理解、逻辑推理与自动化执行等维度的能力已超预期成熟,工程落地准确率与稳定性得到大规模验证。这一技术跃迁使全量自动化安全审计从概念验证走向可靠实践。

传统人工抽样模式在数万条 API、数百个微服务的规模下已难以为继,而基于 AI Agent 的方案可实现 100% 路由覆盖与分钟级检测响应。本文将围绕这一契机,阐述如何构建贯穿全链路调用链的智能审计体系,解决覆盖面、时效性与规则一致性三大核心挑战。

二、技术架构

整体架构设计

架构说明:常规代码负责任务调度与结果存储,所有 AI 分析工作由超级 Agent 完成。具体项目分析告警时采用 AI 批量筛查 + 人工深度验证的人机协同模式。

image.png

具体项目分析告警时采用 AI 批量筛查 + 人工深度验证的人际协同模式:

image.png

场景化应用:

image.png

架构设计原则:通用 Agent + 业务 Skill 分离

设计优势:

image.png

  • 通用 Agent 能力最大化:充分利用 Claude Code/OpenCode 的代码理解、推理分析、上下文管理、会话恢复等标准能力,不重复造轮子
  • 业务逻辑快速迭代:检测规则、分析流程、报告格式等业务逻辑全部沉淀在 Skill 中,可随时调整优化
  • 任务可追溯可复现:通过 --resume 恢复会话现场,任何分析过程都可回溯、可验证

Skill 层核心组成

gateway-route-vuln-analyzer/
├── SKILL.md # 核心:漏洞分析主流程 
│ ├── 检测决策树(Step 1-4)
│ ├── 危害评估规则
│ └── 报告输出模板 
├── references/ 
│ ├── unauthorized_patterns.md # 越权漏洞模式库
│ ├── logic_flaws.md # 逻辑漏洞检测指南
│ ├── data_classification.md # 数据敏感性分级
│ └── report_template.md # 标准化报告模板
└── scripts/ 
└── mcpcli-gateway # CLI入口(Token优化)

MCP 工具集设计

image.png

三、漏洞检测方法论(以越权为例)

越权漏洞精细化分类

基于公开漏洞案例库分析,细分越权漏洞类型:

image.png

检测决策流程

检测分四步,前两步设有短路退出以降低成本:

路由配置检查:检查 auth_config.publicrequired_scopes,配置无异常则跳过后续审计。登录态识别:遍历调用链查找认证节点,标准认证路由直接信任,跳过代码审计 代码审计(三维检测)。:检查权限注解(@PreAuthorize)、用户 ID 来源(登录态 vs 请求参数)、所有权校验(DB 过滤 vs 代码显式校验)。精细化危害评估:区分越权读取(数据敏感性)和越权操作(利益流向),输出风险等级与修复建议。

精细化危害评估机制

越权读取 - 数据敏感性评估

依据《数据安全法》确立的数据分类分级保护制度及《网络安全法》关于网络运营者数据安全管理义务的相关要求,通过 AI Agent 对源代码文本分析(基于变量名、字段类型、接口定义等代码特征进行技术推断),对路由功能返回涉及的数据资产进行分级评估。

image.png

越权操作 - 利益流向评估

image.png

四、技术优化:Token 成本降低 95%+

问题诊断

通过对多个会话日志的深入分析,识别出 Token 消耗的关键问题:

image.png

Token 消耗热点:

image.png

优化策略与效果

MCP → CLI 转换(mcp2cli)⭐核心优化

原理:将 MCP 工具暴露为 CLI 命令,避免每次会话加载 MCP 上下文。

# 优化前:MCP调用(需加载完整MCP上下文)
Claude → MCP Server → 工具执行
# 优化后:CLI调用(直接执行,无额外上下文)
Claude → Bash → mcp2cli → 工具执行

效果:节省 61% Token 消耗。

工具返回值优化 ⭐关键优化

问题:无参数调用返回完整文件(最大 1.47MB ≈ 500K tokens)。解决方案:为 gitlab_file 添加精准参数,实现按需提取。

image.png

效果:v2 vs v1 再节省 88%。

Early-Exit 模式

原理:标准认证路由直接信任,跳过冗余代码审计。

image.png

效果:标准认证场景节省 50-70%。

AI 友好返回格式 YAML

原理:YAML 天然比 JSON 的 Token 量更少,对 AI 阅读更友好,降低模型解析成本。

五、模型选型原则与决策框架

在路由安全审计场景下,模型选型需围绕准确率与召回率两大核心指标建立决策矩阵:

image.png

最终选型:满足 P0/P1/P2 三重约束的最优模型。选型理由:在召回率 100% 的候选模型中,qwen3.5-plus 以更低的单位成本实现可接受的准确率,是批量场景下的最优解。

局限性说明:

测试集局限性:上述结论基于独立手工标注测试集(100+ 样本),与生产告警数据相互隔离,仅可作为基线参考依据。模型迭代风险:大模型迭代更新速度极快,市场中或存在性能更优、成本更低的全新模型,暂未纳入本次评测范围

AI 不是替代人工,而是放大安全工程师的能力:AI 处理重复性筛查,人工聚焦深度分析和复杂判断。

六、方法论沉淀

定制化漏洞分析能力沉淀:针对 API 越权漏洞场景,构建专属漏洞分析技能体系,持续沉淀检测规则与标准化分析流程,保障规则具备落地实战有效性。精细化危害评估体系:严格区分越权读取与越权操作两类风险行为,引入利益流向分析维度,规避一刀切式风险评级,评估更贴合业务实际风险。Token 成本系统化优化:通过 MCP→CLI 格式转换 + 代码精准按需提取 + Early-Exit 提前终止三层优化方案,整体实现 Token 成本降幅 95%+。场景化分层模型选型:批量例行场景采用高性价比模型,核心关键场景启用高精度模型,在检测效果与使用成本之间实现最优平衡

七、误报分析与改进方向

误报根因分析

基于已完成的复核告警深度分析,识别出以下主要误报原因及改进方案:

image.png

针对性改进方案

强化信任边界追踪(解决 35% 误报)

问题:AI 发现中间层没校验就停止,直接认为存在漏洞,未追踪到最终数据操作层。方案:在 Skill 中增加指导规则:发现校验就停止,发现缺失就继续,必须追踪到信任边界,中间层不能下结论。

上下游参数一致性校验(解决 25% 误报)

问题:下游方法参数有越权可能,但上游调用时未传入资源 ID。方案:分析 Controller 层 Request 对象,确认是否包含资源 ID 字段。如果上游 Request 中无资源 ID 字段,判定为"仅操作当前用户数据"。

Dubbo 配置信息补充(解决 10% 误报)

问题:内部网关转 Dubbo 传参信息 AI 无法获取,导致认证判断错误。方案:引入 Open 网关 Dubbo 配置信息(通过内部管理平台获取),新增 MCP 工具 get_dubbo_config,获取路由的 Dubbo 调用配置。

# 新增工具
"get_dubbo_config": {
    "description": "获取路由的Dubbo调用配置和参数映射",
    "inputSchema": {"route_path": "string", "service_name": "string"}
}

响应体价值预判优化(解决 10% 误报)

问题:AI 将无敏感信息的读操作误判为越权。方案:细化响应体敏感性判断规则。不敏感(可忽略):

纯状态码返回
通用配置信息(活动名称、时间、状态)
流程节点信息

后续规划

image.png

八、小结

网关路由 AI 驱动审计是一个面向 API 安全场景的智能化交付范式,将规模化安全审计升级为 AI 自动化检测 + 精细化危害评估 + Token 成本优化的标准化机制。它回答的问题:如何在网关路由规模快速扩张的背景下,实现安全漏洞的全量自动化检测,同时将成本控制在可接受范围。它证明的事:多个高危外网漏洞的实际发现,验证了 AI 在代码审计场景的有效性。单条成本 ¥0.23,某大型业务集群全量扫描一轮不到 1 万元,成本完全可控。人机协同模式有效:AI 批量筛查 + 人工深度验证,既保证效率又确保准确性。它沉淀的方法:MCP→CLI 转换、精准代码提取、Early-Exit 优化,可复用于其他 AI 安全审计场景。

九、附录

标准化告警报告模板

本项目输出标准化的漏洞分析报告,以下是模板结构:

## 漏洞分析报告

### 1. 路由信息
- 路由ID: [必填:从 analyze_route 返回的 route_id]
- 路径: [必填:分析的路由路径]
- 目标服务: [必填:目标服务名称]
- 描述: [必填:路由描述,如无则填"无"]

### 2. 接口功能分析
- 接口用途: [必填:简要说明接口用途]
- 业务场景: [必填:业务场景描述]
- 调用方: [必填:H5前端/APP客户端/小程序/其他服务]
- 数据敏感性评估:
  - 涉及数据类型: [必填:PII/金融数据/订单信息/配置信息等]
  - 敏感等级: [必填:critical/high/medium/low]
  - 影响用户范围: [必填:全平台用户/特定用户群/内部用户等]

### 3. 调用链分析
[必填:调用链树形展示,使用缩进表示层级关系,标记漏洞点]

示例格式:
[网关入口] (总耗时)
  └─ [认证服务]: [认证接口] (耗时) [认证节点]
  └─ [业务服务A]: [业务接口] (耗时) [漏洞点]
     └─ [业务服务B]: [数据库查询] (耗时)

关键中间件操作(只写与漏洞分析直接相关的部分):
- SQL: [可选:列出执行的 SQL 操作类型]
- Redis: [可选:如有 Redis 操作则填写]
- MQ: [可选:如有 MQ 操作则填写]

### 4. 漏洞详情

⚠️ 说明:
- 如果发现漏洞,必须填写此章节
- 如果未发现漏洞,填写"未发现漏洞"并跳过后续小节

#### 漏洞 1: [必填:漏洞标题]
- 严重等级: [必填:critical/high/medium/low]
- 类型: [必填:越权读取/越权操作/逻辑漏洞/竞争条件]
- 漏洞位置:
  - 服务: [必填:漏洞所在服务名称]
  - 方法: [必填:漏洞所在方法名]
  - 文件: [必填:文件路径:行号]
  - 仓库链接: [必填:GitLab 代码链接]
  - Trace ID: [必填:对应的 trace_id]
- 问题描述: [必填:详细描述漏洞原因和利用机制]
- 调用链位置: [必填:标注漏洞在调用链中的位置]
- 问题代码: [必填:漏洞代码片段,包含行号]
- 漏洞危害:
  1. [必填:直接危害]
  2. [必填:间接危害]
  3. 潜在连锁攻击: [必填:可能的连锁攻击场景]
  4. 合规风险: [必填:法律合规风险]
- 修复建议:
  1. [必填:具体修复方案]
  2. [必填:具体修复方案]
  3. [可选:额外加固建议]

### 5. 分析置信度
- 置信度: [必填:高/中/低]
- 依据: [必填:说明置信度的判断依据]

### 6. 局限性
⚠️ 数据获取不全说明:

| 限制类型 | 说明 | 影响范围 | 建议操作 |
|----------|------|----------|----------|
| [限制类型] | [说明] | [影响范围] | [建议操作] |

### 7. 二方包依赖
- 涉及的二方包: [必填:group_id:artifact_id:version - 用途说明,如无则填"无"]
- 源码获取: [必填:已获取/未获取/不需要]

### 8. 涉及的微服务
⚠️ 重要:必须包含 commit_id 和 project_path

- [service_name1] (commit: [commit_id], project: [project_path])
- [service_name2] (commit: [commit_id], project: [project_path])

往期回顾

  1. AI 驱动:从运营行为到自动化用例的智能化实践|得物技术
  2. 生成式召回在得物的落地技术分享与思考
  3. 立正请站好:一个组件复用 Skill 的工程化实践|得物技术
  4. 财务数仓 Claude AI Coding 应用实战|得物技术
  5. 日志诊断 Skill:用 AI + MCP 一键解决 BUG|得物技术

文 / 炁源

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

AI驱动:从运营行为到自动化用例的智能化实践|得物技术

作者 得物技术
2026年4月23日 10:53

一、项目背景

随着交易业务的快速增长,对质量保障工作提出了更高标准与全新要求。为提升研发体验和架构升级,大量后台页面经历从 Vue -> React -> 全栈的迁移过程。业务演进过程中,后台能力持续迭代与优化;团队在交付新能力的同时,同步保障存量链路的稳定与可预期行为。为进一步完善测试用例覆盖范围,高效支撑回归测试与重构验证工作,需通过技术手段升级质量保障模式,为业务与架构迭代提供更充分的质量支撑。

E2E 测试: 即端到端测试,是一种从用户视角出发,模拟真实操作验证应用完整业务流程的自动化测试方法。自动化生成用例: 用线上内部运营操作日志自动生成 E2E 测试用例,快速覆盖核心流程,解决用例缺失问题。智能元素定位: 自动识别重构等场景 UI 变化并调整定位策略,实现维护流程的自动化。平台化管理: 通过数据看板管理用例和执行结果,让 E2E 测试可追踪、可优化,提升测试效率。

基于以上分析,我们致力于构建一套自动化 + 智能化的 E2E 测试方案,该方案旨在支撑快速迭代开发模式,有效应对用例覆盖与重构验证等场景,从而在现有资源条件下,持续为业务快速迭代和技术架构升级提供可靠的质量保障。

二、价值收益

提供基于线上真实运营行为的自动化 E2E 测试能力,能够实际发现页面线上/重构等场景的体验问题。在页面重构等迭代任务中,通过优化回归测试流程与资源分配,有效进一步提升测试支持效率。测试的页面代码覆盖率≥X%;无代码覆盖率场景步骤执行成功率≥X%。

页面代码覆盖率:页面用例在测试过程中 运行的代码行数 / 该页面关联的所有代码行数 * 100%步骤执行成功率:页面用例在测试过程中 执行成功的步骤数 / 用例总步骤数 * 100%。

三、方案选型

传统 E2E(DOM)

名词解释 核心差异
传统 E2E 基于 DOM 的测试方案,主要通过操作和验证浏览器中的页面元素,来模拟用户行为的测试方案。 定位方式:依赖 XPath/CSS 选择器。用例生成:手动编写或录制。维护成本:(DOM 变化需手动更新用例)。

AI E2E

名词解释 核心差异
AI E2E 指利用人工智能技术,增强传统 E2E 测试的智能化、自适应性和效率的测试方案。 定位方式:视觉识别、语义化分析(如按钮文本、图标)。用例生成:自动生成(基于用户行为日志或需求描述)。维护成本:(AI 自动适应 UI 变化)。

方案对比

传统 E2E 优势: 贴近真实用户操作:实际触发页面渲染和事件。跨页面流程验证:适合测试多步骤业务场景(如登录→下单)。传统 E2E 劣势: 脆弱性:DOM 结构变化易导致用例失败(需频繁维护定位表达式)。执行速度慢:依赖浏览器渲染和网络请求。

AI E2E 优势: 降低维护成本:减少因 UI 微调导致的用例失败。提升覆盖率:AI 可探索非预期路径(如异常输入)。AI E2E 劣势: 黑盒性:AI 决策过程不透明,调试困难。高成本:需积累足够数据优化模型,复杂视觉处理需要更高性能。

基于上述对比分析,我们选用 AI 驱动的 E2E 测试方案,能够在支持重构场景的同时,显著提升用例生成的自动化水平,从而形成高效可持续的自动化测试解决方案。

四、AI 工具选型

特征
Midscene 原生 JavaScript + WebExtensions API;开源 AI 驱动 UI 自动化工具; 支持 Playwright、Puppeteer 定制行为逻辑;支持 Dom 分析和视觉分析,如 Qwen-vl、Chain-vl。
browser-use Python + 大语言模型(LLM)+ 浏览器驱动;基于 Playwright;同时支持视觉和非视觉模型;同时支持 DOM 分析和视觉分析。

Midscene优点: 基于 JS 技术栈,前端友好,开发成本较低;支持 Playwright、Puppeteer 定制行为逻辑;公开渠道反馈与迭代节奏相对清晰;支持 DOM 与视觉多模态分析。如上优点对工程化落地更友好。Midscene缺点: 调用视觉/大模型时存在 Token 消耗与成本。

browser-use优点: 支持 Playwright 定制行为逻辑;支持 DOM 与视觉分析,能力面较全。browser-use缺点: 同样存在 Token 消耗与成本;基于 Python 技术栈,有开发语言熟悉成本。

综合评估后采用 Midscene,主要考量:与现有技术栈匹配: 以 JavaScript 为主,便于与前端工程、现有工具链协同,降低接入与维护成本。能力与扩展方式符合需求: 支持 DOM 与视觉等多路径信息输入,并可在需要时用 Puppeteer / Playwright 补充确定性、可编排的自动化逻辑,覆盖模型不稳定或不适用的环节。工程化与定制空间: 定制与扩展路径清晰,便于按业务拆解控制流、做兜底与回归,贴合当前团队的交付方式。

五、流程设计

核心流程图:

图片

Midscene 测试过程详情:

图片

核心流程可以概括为:将运营真实操作记录转化为可执行的测试用例,并通过智能化的方式在测试环境中回放验证。具体实现链路分为四个阶段:

图片

阶段一:智能用例生成——从“行为记录”到“可执行脚本”

这是整个流程的源头与起点,目标是实现测试用例的“自动化生产”。

image.png

阶段二:灵活执行触发——从“静态资产”到“动态任务”

本阶段负责调度,将静态的测试用例转化为具体的执行任务。

image.png

阶段三:AI驱动执行——从“指令”到“结果”的转化

img_v3_0210v_543748eb-43ae-4d1d-a3e6-8781967b08dg.png

阶段四:平台化数据运营——从“结果”到“决策”的质量闭环

img_v3_0210v_62103562-ae83-42a0-9e55-33fa6e26a09g.png

通过这四个阶段的闭环,系统实现了从真实运营行为到自动化测试用例的完整转化,并将执行结果转化为可运营的质量数据。

六、技术亮点

基于真实环境中的运营行为生成测试用例

image.png

基于 Midscene+Qwen2.5-VL-72B 执行用例

image.png

AI 驱动的精准 UI 交互测试

image.png

代码覆盖率作为硬指标

image.png

七、平台化效果

我们在页面上实现了以下可运营能力,将 E2E 测试从黑盒脚本转变为可管理、可追踪、可复盘的平台系统。

整体数据看板

页面列表(入口):

图片

展示内容:按业务域 / 系统 / 负责人筛选、页面级 PV/UV、用例数量、步骤执行成功率、代码覆盖率等指标。系统能力:页面维度汇总视图,将访问热度(PV/UV)与自动化质量指标(成功率 / 覆盖率)结合,指导用例优先级(高 PV 页面优先铺用例、优先治理)。

用例详情视图

用例列表(抽屉):

图片

展示内容:每条用例绑定监控系统信息、点击行为数量、执行结果、步骤成功率、打标及备注、执行/删除操作。系统能力:以线上运营行为列表为用例数据,将 可执行性评估/识别执行结果与预期偏差/可信度(打标)统一实现。

执行详情(弹窗):

图片

展示内容:按步骤展示 CLICK 结果、详细错误堆栈/描述、页面截图缩略图、单步覆盖率、页面地址与 监控系统链接。系统能力:将每一步的线上行为与 E2E 执行对照落库,让失败从黑盒变为可复盘的证据链。

点击明细(单页面的用例序列):

图片

展示内容:点击序号、点击描述(如点击某某预览弹窗/眼睛按钮)、点击行为数量等。系统能力:系统会为 Click Scope 生成更可读的描述,便于非开发同学理解与复盘,也是后续策略库/稳定性治理的输入。

八、总结展望

面对交易业务快速增长、技术栈频繁迁移、测试资源紧张的多重挑战,我们成功实现了基于真实运营行为的 AI 驱动E2E 测试方案。通过 Midscene 的视觉 AI 能力结合 Puppeteer 的精准控制,实现了用例自动化生成、智能交互执行和质量数据闭环。

之后我们将持续优化 AI 模型的准确率和稳定性,逐步实现从「用例执行」到「质量预测」的升级。同时推动平台向标准化、智能化方向发展,让质量保障真正成为业务创新的加速器而非瓶颈。

往期回顾

1.生成式召回在得物的落地技术分享与思考

2.立正请站好:一个组件复用 Skill 的工程化实践|得物技术 

3.财务数仓 Claude AI Coding 应用实战|得物技术

4.日志诊断 Skill:用 AI + MCP 一键解决BUG|得物技术

5.Redis 自动化运维最佳实践|得物技术

文 /卓翎

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

立正请站好:一个组件复用 Skill 的工程化实践|得物技术

作者 得物技术
2026年4月14日 09:53

一、背景:为什么要做这个 Skill

做这个 Skill 的初衷很直接,也很现实:功能开发时容易"顺手新建一个",而不是先复用已有组件,造成组件库越来越臃肿。这件事对团队的伤害其实是复利型的:

  • 重复组件越来越多;
  • 维护成本越来越高;
  • UI/交互一致性越来越差;
  • AI 生成代码时也更容易继续复制混乱。

所以做这个 Skill 的目标不是"帮 AI 搜索一下",而是:把"复用优先"的思考过程流程化,让 AI 在写代码前先走一遍"查索引 → 判断是否复用 → 命不中再新建"的路径。

二、想解决的不是搜索问题,而是“思考顺序”问题

一开始很容易把问题理解成:"做个组件搜索工具给 AI 用就好了"。但实际落地后发现,真正的问题不是工具有没有,而是:

  • AI 会不会主动用;
  • AI 什么时候用;
  • AI 用完之后是否还能回到项目上下文;
  • AI 能不能稳定走同一条流程。

这和 Vercel 在他们的 agent 评测里观察到的现象很像:skills 本身不是没用,而是 agent 往往不会稳定触发;而把基础知识放进 AGENTS.md 这种"被动上下文"后,稳定性反而更高。Vercel 的实验里,默认 skill 触发并没有提升通过率,加入显式指令后才明显改善,而 AGENTS.md 文档索引方案表现更稳定。这给了我一个很关键的设计方向:先解决 AI 的"决策点"问题,再解决 AI 的"能力"问题。

三、核心设计思路:AGENTS.md + Hook + Skill(三层结构)

最终采用的是三层结构:

AGENTS.md:放基础上下文(常驻)

把"组件复用优先"的规则、组件索引入口、扫描后需要做的事情,放进 AGENTS.md(或同类常驻上下文机制)里。目的不是塞满文档,而是让 AI 每轮都知道:

  • 这个仓库有组件复用机制;
  • 默认应该先查可复用组件;
  • 查不到再考虑新建;
  • 扫描后还有描述补全流程需要继续执行。

这层解决的是:AI 根本不知道你有这套机制。不写进去,AI 主动使用 skill 的概率确实会很低(这点我踩过坑)。

Hook:做路由增强(提高触发概率)

如果运行环境支持 hooks(例如 Claude Code 的 UserPromptSubmit 支持在用户 prompt 处理前注入额外上下文),就可以做一层"意图路由增强":在用户提到"组件复用 / 是否有现成组件 / 封装组件 / 查组件"等语义时,给 AI 注入提示,让它优先走组件复用流程。Claude 的文档明确写了 UserPromptSubmit 会在处理前触发,并且可通过 additionalContext 注入上下文。这层解决的是:AI 知道有 skill,但不一定想起来用。

Skill:提供流程和工具(真正执行)

Skill 不是只写说明文档,而是要提供:

  • 明确的调用入口;
  • 稳定的输出格式;
  • 可执行脚本;
  • 失败时的兜底逻辑。

OpenAI 的 Codex Skills 文档里提到 skills 是"渐进披露"机制:运行时先看到 skill 的元信息(尤其是 description),只有决定使用时才加载完整 SKILL.md;而且隐式触发高度依赖 description。这也是为什么 skill 的触发边界和描述要写得非常清楚。这层解决的是:AI 想用了,但执行过程不稳定。

四、这套 Skill 在源码里是怎么落地的(我的实现)

下面是我这次组件复用 Skill 的几个关键实现点:

先把"入口"收敛成一个:find-component.js

我在 SKILL.md 里明确规定:Agent 必须调用统一入口find-component.js。这样做的原因很简单:

  • 避免 AI 在多个脚本之间犹豫(scan-components、match-component、resolve-scope……);
  • 避免 AI 漏掉前置步骤(比如索引不存在时先扫描);
  • 避免 AI 调用路径不一致导致结果不稳定。

统一入口做了几件事(都在 find-component.js 里):接收查询词(query)、仓库根路径(repoRoot)、当前聚焦路径(startDir)。

  • 如果 components.csv 缺失,内部自动触发run-scan.js;
  • 调用 resolve-scope 计算当前应用和允许搜索范围;
  • 调用 match-component 做匹配排序;
  • 命中时记录使用(用于后续加权);
  • 按固定 JSON 协议返回结果(成功/失败/无匹配/是否触发扫描等)。

这一步本质上是把分散逻辑聚合成"一个业务动作":"查一下有没有可复用组件",而不是"先算 scope,再查 CSV,再排序,再补扫,再记 usage"。这对 AI 很关键。

不是"全仓库乱搜",而是"当前应用 + 根级共享"优先

在 monorepo 场景里,组件复用很容易踩两个坑:

  • 只搜当前 app,漏掉根级共享组件;
  • 全仓乱搜,结果太多太噪音。

所以我在 resolve-scope.js 里做了一个比较工程化的范围解析策略:

  • 读取 pnpm-workspace.yaml 解析 workspace 包;
  • 根据当前聚焦文件/目录反推 currentAppRoot;
  • 再结合 root_scope_patterns(例如 apps/_share/、packages/ 等)构建允许范围;
  • 最终形成一个搜索集合:当前应用 + 根作用域共享包。

如果没有聚焦子项目(比如 startDir 就是 repo root),则切换为全量 scope。这个设计很像人类工程师的查找策略:先看"我这个业务应用里有没有",再看"全局共享有没有",而不是直接在整个 monorepo 海里捞针。

匹配不是纯关键字:我做了"多因素加权"

组件匹配如果只做字符串包含,很快就会变成垃圾召回器。我在 match-component.js + fuzzy-match.js 里做了一个组合评分,核心包括:

  • 名称精确/包含匹配;
  • 模糊匹配(编辑距离);
  • Token 重叠;
  • 首字母缩写匹配(例如 dlp 匹配 DateLinkPicker);
  • 当前应用加权(当前 app 的组件优先);
  • 使用频率加权(常用组件更靠前);
  • 来源质量加权(README 推断质量高于纯 inferred);
  • 存在性校验(文件不存在则降权/过滤);
  • 记录类型权重(组件优先于依赖)。

这一步的目标不是追求"算法先进",而是让排序更符合团队真实使用习惯:"更可能被复用的组件排在前面"。此外我还加了一个低分阈值(NO_MATCH_SCORE_THRESHOLD):

  • 如果最高分太低,就认为是噪音命中;
  • 可以触发一次扫描后再查;
  • 还是低分则按"无匹配"返回,不把噪音结果塞给 AI。

这个点很重要,因为 AI 一旦拿到一些低质量候选,很容易"将错就错"。

把"索引构建"做成可复用流水线,而不是一次性脚本

很多类似方案停在“扫一遍生成 CSV”,然后就过时了。我这次把扫描做成了 run-scan.js -> index-manager -> enrich 的流水线,核心考虑是持续维护:

run-scan.js 负责编排流程

  • resolve-scope;
  • updateIndex;
  • 自动触发 autoEnrich(可配置)。

index-manager.js 负责索引更新策略

  • 保留历史记录并合并;
  • 根据 source_hash 跳过未变化组件;
  • 记录 last-scan-changed-ids.json;
  • 支持并行扫描(包数量较多时启用);
  • 对缺失文件支持标记 exists=0(在查找阶段也会回写)。

扫描后进入 Agent 富化(enrich)流程

  • 读取 agent-enrich-prompts.json;
  • 找出 summary 占位符项;
  • 按 id 回到 components.csv;
  • 读取源码/README;
  • 生成 summary + keywords;
  • 再通过 update-component-summary.js 写回。

更关键的是在配置里启用了:

  • agent_mode_no_fallback = true。

也就是说,在 Agent 模式下不走规则引擎降级,而是要求 Agent 必须完成这一步。这其实就是"流程化思考"的精髓:不是建议,而是纳入主流程。

让 Skill 不只是"搜索器",还是"反馈回路"

一个很容易被忽视的点是:查找命中后,我还记录了使用行为(usage-tracker)。这意味着系统不是静态的,它会逐步学习团队偏好:

  • 哪些组件经常被复用;
  • 哪些组件在某个 app 里更常出现;
  • 哪些结果应该在排序中更靠前。

这是一种很轻量但非常实用的反馈机制——不需要搞复杂训练,也能提升 AI 下一次推荐质量。

五、这次实现里,总结出"让 AI 流程化"的 3 条原则

这也是我最想分享的部分:

原则 1:把基础上下文放进 AGENTS.md(或用 Hook 注入)

如果不这样做,AI 主动使用 skill 的概率很低。原因不是 AI 笨,而是 agent 的执行是有"决策成本"的:

  • 它要先意识到有 skill;
  • 再判断该不该用;
  • 再决定什么时候用。

而把基础上下文放进 AGENTS.md 或通过 hook 提前注入,本质上是在减少决策点。Vercel 的评测结果说明了这种"被动上下文"在某些场景下会更稳定。

原则 2:Skill 需要直接提供工具函数给 AI 调

只写一堆说明文档不够。AI 在工程任务里最需要的是:

  • 一个可以直接执行的入口;
  • 明确的参数;
  • 稳定的返回结构。

所以我把 find-component.js 做成统一入口,并定义了固定 JSON 输出(ok / matches / noMatch / scanTriggered / hint / error 等),这会明显提升 AI 的执行稳定性。

原则 3:显式告诉 AI 调哪些函数,并把分散逻辑聚合到一个入口

这是最容易被忽略、也是最影响稳定性的一点。如果给 AI 暴露一堆脚本:

  • resolve-scope.js;
  • match-component.js;
  • run-scan.js;
  • scan-components.js;
  • index-manager.js。

它理论上能拼起来,但实践里很容易漏步骤、顺序错、参数错。所以我在 Skill 里显式规定:

  • 查找时用 find-component.js;
  • 构建时用 run-scan.js;
  • 更新描述时用 update-component-summary.js。

把复杂系统收敛成几个明确入口,AI 才容易稳定执行。

六、这次实践里一个很重要的认知转变

我原来以为"写 skill"是在给 AI 增加能力。现在更像是在做:给 AI 增加"默认工作方式"。换句话说,skill 不只是能力包(capability bundle),也是流程控制器(workflow controller)。

  • AGENTS.md 负责"告诉 AI 世界观";
  • Hook 负责"提醒 AI 现在该用哪套流程";
  • Skill 负责"把动作做完,并且做得稳定";
  • 日志/CSV/usage 负责"让系统可观测、可迭代"。

这套思路不只适用于组件复用,后面也可以迁移到:

  • 任务优化闭环;
  • 日志分析标准化;
  • 策略诊断流程;
  • 代码规范治理。

七、这套方案当前的价值

  • AI 开发前先查可复用组件,而不是直接新建;
  • monorepo 下按"当前应用 + 共享组件"范围检索;
  • 索引缺失自动扫描;
  • 组件描述富化进入主流程;
  • 匹配质量有加权与反馈回路;
  • 整体流程有明确入口和输出协议。

八、结语:让 AI 少一点"即兴发挥",多一点"工程纪律"

这次组件复用 Skill 的开发过程,对我最大的启发不是"AI 能帮我写多少代码",而是:AI 其实非常适合被放进一套清晰流程里工作。只要把下面三件事做好:

  • 基础上下文(AGENTS.md / hooks);
  • 可执行入口(工具函数);
  • 明确流程边界(统一入口 + 输出协议)。

AI 就不会只是"一个会说话的代码补全器",而会更像一个遵守团队规范的工程协作者。而这,才是我做这个 Skill 真正想要的结果。

引用文档: vercel.com/blog/agents…

往期回顾

1.财务数仓 Claude AI Coding 应用实战|得物技术

2.日志诊断 Skill:用 AI + MCP 一键解决BUG|得物技术

3.Redis 自动化运维最佳实践|得物技术

4.Claude在得物App数仓的深度集成与效能演进

5.Claude Code + OpenSpec 正在加速 AICoding 落地:从模型博弈到工程化的范式转移|得物技术

文 /魏无涯

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

Claude Code + OpenSpec 正在加速 AICoding 落地:从模型博弈到工程化的范式转移|得物技术

作者 得物技术
2026年3月24日 10:22

一、破局:AI 编码的真正瓶颈不是模型,是上下文管理

在软件开发的历史进程中,每一次效率的飞跃都伴随着抽象层次的提升。从汇编语言到高级语言,从手动内存管理到垃圾回收,开发者始终在寻求降低认知负荷的方法。进入 2026 年,生成式人工智能(GenAI)已成为编程领域不可或缺的力量。 然而,行业正经历从 “模型崇拜” 向 “工程落地” 的深刻转型,单纯依靠增加大语言模型(LLM)的参数规模已无法解决复杂业务逻辑中的幻觉与失控问题。

当前的共识是,AI 编码(AICoding)的真正瓶颈不在于模型的逻辑能力,而在于上下文管理(Context Management)的失效与开发意图(Intent)的模糊。

通过对 Anthropic 推出的 Claude Code(以下简称 CC)与 Fission AI 倡导的 OpenSpec 进行深度解构可以发现,两者正在通过 “代理化执行” 与 “规格化驱动” 双轮驱动,构建一套闭环的 AI 研发体系。这种结合不仅标志着 AI 编程工具从 IDE 插件向终端原生代理(Agentic Tool)的转变,更预示着 “规格驱动开发”(Spec-Driven Development, SDD)将成为企业级 AICoding 落地的核心范式。

在 AICoding 的早期阶段,开发者普遍认为只要模型足够强大,就能解决所有编程难题。然而,随着项目复杂度的增加,这种观点遭到了现实的挑战。研究表明,虽然 AI 编码助手的使用率在提升,但软件交付的稳定性却在下降。例如,Google 的 DORA 2024 报告指出,AI 采用率每增加 25%,交付稳定性反而下降 7.2%。

生产力悖论与认知负荷

AICoding 领域存在一个显著的 “生产力悖论”:开发者在使用 AI 时主观感知速度提升了 20%,但实际完成任务的时间却增加了 19%。这一现象的根源在于 AI 在处理长上下文时的效能衰减。随着任务推移,AI 往往会陷入修正循环(Fix/Test Loops),无法触及深层的业务功能,反而需要更多的人工干预。

模型的逻辑推理能力(Reasoning)在短小上下文中表现卓越,但在大型工程环境中,模型面临的是 “上下文中毒”(Context Poisoning)和 “注意力漂移”(Attention Drift)。当对话历史过长或包含过多无关代码时,模型的性能会呈现非线性下降。例如,GPT-4o 等先进模型在 1K Token 时的准确率为 99.3%,而当上下文扩展到 32K Token 时,准确率会暴跌至 69.7%。这种 “性能断崖” 意味着,单纯依靠扩大上下文窗口(Context Window)并不能解决问题。

上下文工程的兴起

上下文工程(Context Engineering)正在取代提示词工程(Prompt Engineering),成为 AICoding 的核心技术方案。上下文工程的核心不在于 “如何写更好的指令”,而在于 “如何为模型筛选最精准的 Token 集合”。

下表对比了传统缩放路径与上下文工程路径的局限性:

在大型组织中,上下文管理面临更严峻的挑战。很多关键决策并未记录在代码中,而是散落在飞书文档评论、群消息、会议或开发者的认知中。AI 代理在缺乏这些隐性知识(Implicit Knowledge)的情况下,生成的方案虽然符合语法,但却违背了架构初衷或业务约束。

上下文作为一等系统

现代 AI 代理架构开始将上下文视为一种具有自身架构、生命周期和约束的 “一等系统”。在这种视角下,上下文管理不再是临时的字符串拼接,而是一条精密的 “编译器管道”:

  • 存储与呈现分离: 区分持久化的会话状态(Session)与单次模型调用的工作上下文(Working Context)。
  • 显式转换: 通过命名的、有序的处理器(Processors)构建上下文,而非随机堆砌。
  • 默认作用域: 每个子代理仅能看到执行任务所需的最小上下文,通过工具(Tools)按需获取更多信息。

二、Claude Code:把 AI 变成真正懂你项目的编码伙伴

Claude Code (CC) 是 Anthropic 推出的原生代理工具,它直接运行在终端中,具备读取文件、运行命令、执行重构以及自主验证的能力。与传统的 IDE 插件相比,CC 的核心优势在于其“代理循环”(Agentic Loop)和对上下文协议的深度掌控。

代理循环:收集、行动与验证

CC 的工作流程被定义为一个闭环系统,旨在模仿人类工程师的思维过程:

  • Gather Context(收集上下文): CC 不会盲目读取整个目录,而是通过文件搜索、Git 状态检查以及读取特定的 CLAUDE.md 文件来建立认知。
  • Take Action(采取行动): 基于推理,CC 可以跨多个文件执行编辑,或者利用终端工具(如 npm install、git commit)操作环境。
  • Verify Results(验证结果): 这是 CC 最具杀伤力的特性。它能自动运行测试、捕捉错误,并根据反馈调整方案。研究表明,带有验证步骤的 Coding 生成过程,其成功率远高于单次生成。

终端原生的工程哲学

CC 选择了终端而非图形界面作为主场,这体现了其 “代理优先” 的设计哲学。CC 遵循 Unix 哲学,支持管道(Pipe)、脚本化和自动化集成。这种设计使得 CC 能够与现有的 CI/CD 流程完美衔接,例如在 GitHub Actions 中自动执行代码审计。Anthropic 最新推出的 Code Review 功能,就是通过 Claude Code 基于 PR 的方式进行 bug 的追踪。

下表详细对比了 CC 与行业领先的 AI 编辑器 Cursor 的差异:

MCP 与“即时上下文”

CC 深度整合了模型上下文协议(Model Context Protocol, MCP)。MCP 是一个开放标准,允许 AI 代理安全地访问外部数据源。

为了应对大规模工具定义导致的上下文溢出,CC 引入了 “工具搜索” 和 “代码执行” 模式。代理不再一次性加载成千上万个 API 定义,而是通过编写代码按需调用 MCP 服务。例如,在分析大型数据库时,CC 不会加载全量数据,而是编写针对性的查询语句,仅将结果摘要读入上下文。这种 “按需加载” 策略极大地提升了 Token 的效用。

CLAUDE.md 与自动记忆

CC 引入了 CLAUDE.md 文件作为项目的 “操作手册”。这是一个置于根目录的 Markdown 文件,用于存储项目特定的编码标准、架构决策和测试指令。与临时提示词不同,CLAUDE.md 提供了持久的、跨会话的约束。

此外,CC 具备 “自动记忆”(Auto Memory)功能。它会自动在 MEMORY.md 中记录项目的构建命令、调试心得和用户的偏好设置。每当新会话启动时,CC 会加载这些记忆的前 200 行,从而确保 AI 在长期协作中能够 “越用越懂你”。

三、OpenSpec:给 AI 编码加上"规格书",从失控到可沉淀

虽然 Claude Code 提供了强大的执行引擎,但在复杂业务中,AI 仍然可能因为意图不明而跑偏,最终导致交付的代码不符合预期。

OpenSpec 的出现为 AI 编码提供了 “规格说明书”,将 AICoding 从 “凭感觉写代码” 提升到了 “按规格执行任务” 的高度。

规格驱动开发 (SDD) 的兴起

OpenSpec 倡导的是一种 “规格驱动开发”(Spec-Driven Development)范式。其核心理念是:在写任何一行代码之前,先由人类与 AI 共同协商并锁定一份机器可读、人可评审的规格文档。

下表展示了 SDD 的三个演进阶段:

OpenSpec 的工件体系 (Artifacts)

OpenSpec 弃用了笨重的开发文档,转而采用一套轻量级的、面向 AI 优化的 Markdown 工件体系。每个变更(Change)都被组织在独立的文件夹中:

  • proposal.md: 描述变更的初衷(Why)和范围(What)。
  • specs/: 具体的逻辑规格,通常包含 “Scenario(场景)” 描述,通过具体的输入输出消除模糊性。
  • design.md: 技术设计方案,包括本次变更涉及的数据库变更、接口调整等。
  • tasks.md: 原子化的任务清单,作为 AI 的执行路径图。

解决上下文污染:提案、应用与归档

OpenSpec 最具洞察力的设计在于其生命周期管理。AI 在处理新任务时,最忌讳被旧任务的陈旧信息干扰。OpenSpec 的 “归档(Archive)” 机制解决了这一问题:

  • Proposal 阶段: 建立一个独立的变更上下文,让 AI 只关注当前变更。
  • Apply 阶段: AI 严格按照 tasks.md 执行,避免了盲目扫描全库导致的 Token 浪费。
  • Archive 阶段: 任务完成后,临时变更文档被移入归档,核心规格更新至主规格文件。这保证了 AI 始终在一个 “卫生” 的上下文环境下工作,同时也为项目留下了可追溯的决策链路。

四 、实战:CC + OpenSpec 如何落地真实业务

在实际的企业业务场景中,如何整合这两大工具?答案在于将 OpenSpec 的标准化指令集注入到 Claude Code 的会话环境中。

案例实战:复杂业务逻辑的重构

假设一个电商项目需要重构其优惠券结算逻辑。在传统的 AI 辅助下,AI 可能会在修改 CouponService.java 时遗漏分布式锁,或者破坏原有的满减叠加规则。采用 CC + OpenSpec 模式,流程如下:

第一步:提案初始化

执行 /opsx:propose "重构优惠券结算逻辑,引入 Redis 分布式锁并支持多卷叠加"。CC 会在 openspec/changes/refactor-coupon-logic/ 下生成整套骨架。AI 会通过分析现有代码,在 spec.md 中自动列出已知的结算场景。

第二步:规格对齐与边界确认

这时不用急着让 AI 写代码,而是需要先审阅 spec.md。如果发现 AI 没考虑 “优惠券过期临界点” 的并发问题,可以直接要求 AI 修改规格:“在 spec.md 中增加过期校验场景,并要求使用 Lua 脚本保证原子性”。

第三步:受控应用(Apply)

一旦规格通过人工评审,就可以执行 /opsx:apply 了。这时,CC 就变成了完美的执行机器。它不再 “猜” 开发者的意图,而是对照 tasks.md 逐项实施。每一项修改后,它都会运行相关的测试。如果测试失败,CC 会自动分析错误并重新修复,直到该项 Task 标为 “完成”。

第四步、归档与知识固化

任务结束后,执行 /opsx:archive。原本散落在会话记录中的重构逻辑,现在变成了 openspec/specs/coupon-settlement.md 中的标准规格。当下一次另一个 AI 代理(或新入职同事)需要修改此模块时,它只需读取这份规格,即可获得完整的业务语境。

工具链对比:为何选择 OpenSpec

在 SDD 工具链中,OpenSpec 展现出了极高的工程性价比:

OpenSpec 的优势在于它不试图改变开发者的工具偏好。无论是使用 Claude Code、Cursor 还是 Aider,都可以无缝接入 OpenSpec 的规格管理层。

五、沉淀:让 AI 编码能力在团队中持续积累

AICoding 落地的终极目标不是让个体开发者写得更快,而是提升整个团队的知识资产质量。AI 编码能力不应随对话窗口的关闭而消失,而应作为 “团队记忆” 沉淀下来。

从个人技能到组织技能

团队可以通过自定义 Skill 和 MCP Server 来固化组织资产。

  • Skill: 将公司特有的代码风格、安全审计清单,或者特定中间件的使用指南封装为 .claude/skills/。当团队成员使用 CC 时,AI 会自动加载这些技能,仿佛有一位资深架构师在时刻盯着每一行代码。
  • MCP Server: 连接企业内部的向量数据库(如基于 Zilliz 的语义搜索),让 AI 代理能够从数千万行历史代码中找到最佳实践。

建立 AICoding 效能飞轮

AICoding 的成功落地需要建立一套正向循环的 “飞轮”:

  • 规格积累: 每完成一个 PR,都强制更新对应的 OpenSpec 规格文件。
  • 指令进化:发现 AI 反复犯的错,就将其转化为 CLAUDE.md 中的负向约束(Prohibited rules)。
  • 并行执行: 利用 CC 的 Agent Teams 能力,让一个代理负责写规格,另一个代理负责审计代码,第三个代理负责集成测试。

角色转变:从 “码农” 到 “规格定义者”

在 CC + OpenSpec 模式下,软件工程师的角色正在发生质变。如果 AI 能够根据完美的描述生成任何代码,那么 “代码” 本身就变成了编译后的中间产物,而 “规格” 才是核心产品。领域专家(Domain Experts)的重要性显著提升,因为他们能提供最高质量的业务意图描述。这种趋势将迫使开发者从关注 “语法实现” 转向关注 “系统设计” 和 “逻辑严密性”。

六、结语:AICoding 落地的飞轮正在转动

在 2026 年,AICoding 已不再是科幻。Claude Code 提供的强大代理能力,配合 OpenSpec 提供的精密规格框架,为企业提供了一套可复制、可量化的研发新范式。

我们必须承认,AI 编码的瓶颈从来不是模型不够聪明,而是我们与 AI 之间的 “沟通带宽” 太低且 “上下文” 太脏。通过上下文工程化管理(CC)和意图标准化表达(OpenSpec),我们正在构建一套让 AI 能够长期、稳定产出的工程环境。

随着这一模式的普及,软件开发的门槛将进一步降低,而创新的上限将被无限拉高。AICoding 落地的飞轮已经转动,那些能够率先将 AI 编码能力转化为团队组织资产的企业,将在未来的数字化竞争中占据绝对的先机。毕竟,在 AI 时代,掌握了 “意图” 与 “上下文” 的人,才掌握了软件工程的未来。

参考文档:

  1. thenewstack.io/context-is-…
  2. github.blog/ai-and-ml/g…
  3. solguruz.com/blog/spec-d…
  4. medium.com/@eran.swear…
  5. www.anthropic.com/engineering…
  6. code.claude.com/docs/en/how…
  7. www.anthropic.com/engineering…
  8. code.claude.com/docs/en/bes…
  9. dev.to/webdevelope…

往期回顾

1.大禹平台:流批一体离线Dump平台的设计与应用|得物技术

2.基于 Cursor Agent 的流水线 AI CR 实践|得物技术

3.从IDE到Terminal:适合后端宝宝体质的Claude Code工作流|得物技术

4.AI编程能力边界探索:基于 Claude Code 的 Spec Coding 项目实战|得物技术

5.搜索 C++ 引擎回归能力建设:从自测到工程化准出|得物技术

文 /后羿

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

从IDE到Terminal:适合后端宝宝体质的Claude Code工作流|得物技术

作者 得物技术
2026年3月17日 13:38

一、背景

事情是这样的,之前对 AI 编程一直是观望态度,但是部门最近在做 AI 辅助编程 POC,有幸成为 POC 用户,用上了自己舍不得买的高级编程模型 (感谢公司)。尽管我自认为是一个在代码上很挑剔的人,但是试了下感觉居然还可以 (Go、React)!只能说还得是谷歌,调整重心略微发力,Gemini 3 表现确实很不错。既然尝到甜头了,觉得自己是时候好好地琢磨琢磨,研究研究,沉淀一套自己的工作流、方法论,解放自己的生产力,顺应潮流努力成为 AI 时代的受益者,而不是被淘汰的人!

新的开发范式需要搭建新的开发环境和匹配自己开发习惯的工作流,这就像刚学编程那会,需要挑一个自己喜欢的 IDE、熟悉 IDE 快捷键和优化 IDE 设置一样。过程中间肯定有阵痛,Java 开发者们回忆一下多年之前从 Eclipse 转 IDEA 那会的阵痛吧,但是磨刀不误砍柴工,阵痛之后一定是生产力提升。借本文分享下我摸索后的方案,供大家参考。

二、工具选型

目前 AI 辅助编程领域热火朝天,各种 GUI 工具、TUI 工具如雨后春笋让人目不暇接,这对于花心的强迫症选手(比如我)来说选型很困难。但是我觉得有两个基础认知可以帮助我们更好地做决定:

(一)AI 辅助编程工具由脑和手两部分组成。脑是外接的大模型 API,手是各个产品调教的提示词和内部工作流。按我理解,【脑】决定了工具的上限,【手】决定了工具的下限。在这个场景里,大模型就像是汽车里的发动机,而且所有型号的汽车支持的【发动机】规格都是通用的、统一的、标准化的。有了这个基础,我们可以随便选一个趁手的工具,然后自行按场景选配【合适】的【发动机】。

(二)AI 辅助编程当前是一个【千帆竞发】的热门领域,而且单纯就【工具】来说,这个领域【没有技术壁垒】。A 产品抛出的杀手级特性,不出半个月一定会有 B 产品跟进。毕竟现在软件迭代的速度借助 AI 提升了很多,A 产品验证过的想法,B 产品可以很快地跟进和实现。Claude Code CLI 的开发者就使用 Claude Code CLI 迭代 Claude Code CLI,有点绕口,大概就是【工具自举】的意思吧。

Claude Code CLI

综上,其实没啥纠结的,我们照着这两点来选型就好:1. 这个工具一定得便捷地支持模型插拔,就是我随时可以根据场景换一个更适合的、更便宜的、表现更好的大模型。而且这种插拔一定要简单。 2. 这个工具一定要有积极的维护者,不断地迭代、优化它的工作流、提示词。最好是一个商业化产品,因为商业化产品出于其商业目标,一定会投入资源积极进行迭代。 

当前满足这两个条件的,我想也就是 Claude Code CLI 了: 1. Claude Code CLI 是一个商业化产品,有专门的技术团队在不停地更新、迭代。 2. Claude Code CLI 可以非常便捷地支持大模型插拔,我可以随时根据成本、效率、体验来切换合适的大模型。因此,这个环节我选 【Claude Code CLI】。

后文以CC代指Claude Code CLI。

快速切换模型

我通过自定义 Shell 函数来实现便捷的模型切换,不同的场景、不同的任务使用不同的模型。基本原理就是,CC 支持环境变量注入 LLM 配置信息,因此我只需要按场景注入【行内临时环境变量】即可。

详见:Bash - 行内环境变量,Bash 是标准的 Shell 实现,其他 Shell 如 Zsh 都兼容其行为。

Shell配置

我到处弄了一堆免费的、收费的模型用,然后给他们取了我记得住的别名:

使用效果

为了兼容,设置了一个 claude 别名:

这样输入claude 时,默认使用智谱 GLM 模型。

脚本源码

Shell 脚本大概这样,可以修改后配置到自己的 ~/.zshrc 中。如果不熟悉 Shell,嫌麻烦也可以试试这个开源工具:farion1231/cc-switch。

# claude 默认
alias claude='zcc'
# Kimi
function kcc(){
    echo Kimi Claude Code...
    local model="kimi-k2.5"
    ANTHROPIC_BASE_URL="https://api.moonshot.cn/anthropic" \
    ANTHROPIC_AUTH_TOKEN="sk-xxxxxxxxx" \
    ANTHROPIC_SMALL_FAST_MODEL="$model" \
    ANTHROPIC_DEFAULT_OPUS_MODEL="$model" \
    ANTHROPIC_DEFAULT_SONNET_MODEL="$model" \
    ANTHROPIC_DEFAULT_HAIKU_MODEL="$model" \
    CLAUDE_CODE_SUBAGENT_MODEL="$model" \
    launch_claude_code $@
}
# 智谱GLM
function zcc(){
    echo GLM Claude Code...
    ANTHROPIC_BASE_URL="https://open.bigmodel.cn/api/anthropic" \
    ANTHROPIC_AUTH_TOKEN="sk-xxxxxxxxx" \
    launch_claude_code $@
}
# 七牛
function qcc(){
    echo QiNiu Claude Code...
    local model="minimax/minimax-m2.1"
    ANTHROPIC_BASE_URL="https://api.qnaigc.com" \
    ANTHROPIC_AUTH_TOKEN="sk-xxxxxxxxx" \
    ANTHROPIC_SMALL_FAST_MODEL="$model" \
    ANTHROPIC_DEFAULT_OPUS_MODEL="$model" \
    ANTHROPIC_DEFAULT_SONNET_MODEL="$model" \
    ANTHROPIC_DEFAULT_HAIKU_MODEL="$model" \
    CLAUDE_CODE_SUBAGENT_MODEL="$model" \
    launch_claude_code $@
}
function launch_claude_code(){
    CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \
#    clear
    command claude $@
}

三、开发环境

在当前的气氛下,我想我算是一个【古板】的开发者,我做不到【fire and forget】,或者说完全靠黑盒的自然语言对话来完成代码开发。

我还是只将 AI 当助手,还是想要白盒的掌控 AI 写的代码,还是希望最终交付的代码有我的风格、我的审美、我的品味。毕竟 AI 也只能帮我写代码,并不能帮我背锅。尽管我选择了 TUI 工具 Claude Code CLI,但是我还做不到全程只在终端操作,我还是习惯 JetBrains 特色的双栏 diff。

因此,当前我开发流程的起点还是传统的 IDE,比如我最喜欢的 JetBrains。每天上班第一件事是接水,第二件事就是打开 IDE。所以我需要想办法来将 GUI 工具和 TUI 工具流畅的衔接起来,减少代码开发时的频繁切换产生的割裂感!

多屏协作

如上图,我有 3 个显示器,我的构想是这样的:

  1. MacBook 内置显示器 —— 常驻两个空间:一个用来打开浏览器,还有 VPN、网易云音乐、Finder 软件,用来承接各种临时的操作。一个用来打开飞书,用来沟通、协作。

  1. 中间主屏 —— 常驻两个空间:一个用来打开浏览器,用来做各种【输出】。一个用来打开 IDE,专注于写代码、看代码,用标签页打开多个 Project。

  1. 左边竖屏 —— 常驻两个空间:一个用来打开浏览器,用于看文档、查资料等各种【输入】。一个用来打开 TUI 工具,进行辅助编程!

GUI/TUI衔接

现在问题来了,我希望我的开发工作的【主轴】是 IDE,流程的起点是 IDE。但是我的 IDE 在中间屏幕,终端在左边屏幕,它俩是独立软件,没法协作、自动跟随切换 Project 的工作目录。我希望有个【自动化流程】,当我在 IDE 里切换项目的时候,CC 自动跟随切换!

衔接流程

我期待的流程是这样的:

因为某个原因,我在 IDE 里打开了一个项目 A  准备写代码了,点击 IDE 里的某个【按钮】,左边屏幕自动【新建】一个项目 A 的 CC 会话终端并激活到前台显示   我跟左边的 CC 对话,让他干活  我在中间的 IDE 里评审、调试、诊断  因为某些原因我又要在 IDE 打开一个别的项目 B  我再次点击那个【按钮】,左边屏幕自动【新建】一个项目 B 的 CC 会话终端并激活到前台显示  我在 IDE 里又切回了项目 A,我又点击了那个【按钮】,左边屏幕自动【切换】到 A 的 CC 会话终端并激活到前台显示。

好的想法已经有了,AI 时代就怕你没有想法,有想法就一定有办法实现!

代码实现

  1. macOS 上的原生软件,大部分支持 AppleScript 自动化,也就是说我们可以写脚本驱动软件的行为、模拟人机交互,比如打开软件、新建 tab、点击按钮等。

  2. JetBrains IDE 支持集成外部命令,也就是说:可以在 IDE 里点击一个按钮,自动执行一个 Shell 脚本或者别的可执行文件。

产品需求清晰了,接下来开始让 AI 干活!一顿沟通和调试之后,我们有了一个【自动化】创建 iTerm2 新标签的可执行脚本!

这是给大模型的需求提示词,大家可以按需选用,做个性化的调整:

## 📌 工具功能说明
请帮我创建一个 macOS 上的 iTerm2 自动化工具,主要功能包括:
### 核心需求
1. **智能窗口管理**:自动使用或创建 iTerm2 窗口
2. **项目标签管理**:为每个项目目录维护独立的标签页,支持标签复用
3. **三面板布局**:自动创建固定的三面板布局(上方一个全宽面板,下方两个并排面板)
4. **命令自动执行**:在每个面板中自动切换到项目目录并执行预定义的命令
### 使用场景
```bash
# 基本用法:在当前目录打开
./open-claude-in-iterm.sh
# 指定项目目录
./open-claude-in-iterm.sh /path/to/project
```
---
## 🎯 技术架构要求
### 技术栈
- **Shell 脚本** (open-claude-in-iterm.sh):参数处理、路径规范化、日志管理
- **AppleScript** (open-claude-in-iterm.applescript):iTerm2 自动化核心逻辑
**依赖**:macOS、iTerm2、Bash
---
## 📋 详细功能规格
### 1. Shell 脚本 (open-claude-in-iterm.sh)
#### 参数处理
- **参数1**:项目目录(可选,默认当前目录)
- **自动处理**:相对路径转绝对路径
#### 面板命令配置
```bash
PAN1_CMD="claude"     # 上方面板命令
PAN2_CMD="claude"     # 左下面板命令
PAN3_CMD="claude"     # 右下面板命令
```
### 2. AppleScript (open-claude-in-iterm.applescript)
#### 主要流程
**步骤1:窗口管理**
- 检查 iTerm2 是否运行(未运行则自动启动)
- 使用当前激活的 iTerm2 窗口,如果没有则创建新窗口
**步骤2:标签管理(关键逻辑)**
- 在找到的窗口中,查找 `session.path` 变量等于项目目录的标签
- **复用逻辑**:如果找到现有标签 且 窗口不是新创建的 → 直接切换标签并返回
- **创建逻辑**:如果未找到标签 或 窗口是新创建的 → 创建新标签和布局
**步骤3:三面板布局创建**
```
布局示意图:
┌─────────────────────────┐
│   上方面板 (全宽)         │
│   执行: PAN1_CMD         │
├──────────────┬──────────┤
│  左下面板    │  右下面板 │
│  PAN2_CMD   │  PAN3_CMD │
└──────────────┴──────────┘
```
**分割顺序(重要)**:
1. 初始状态:一个全屏 session(上方面板)
2. 第一次分割:对上方 session 执行**水平分割**,创建下方面板
3. 第二次分割:对下方 session 执行**垂直分割**,创建右下面板
**步骤4:命令执行**
在每个面板中依次执行:
1. 切换到项目目录:`cd "/path/to/project"`
2. 清屏:`clear`
3. 等待 0.3 秒(确保目录切换完成)
4. 执行命令:`PAN_CMD`
5. 等待 0.5 秒(确保命令启动)
## ⚠️ 常见错误
- ❌ 符号链接未处理,导致找不到 AppleScript 文件
- ❌ 分割顺序错误,导致布局不正确
- ❌ 缺少 delay,导致命令执行失败或在错误目录执行
- ❌ 新窗口处理错误,导致多余空白标签
- ❌ 标签复用逻辑错误,导致同一项目创建多个标签
- ❌ 路径未引用,导致包含空格的路径失败

IDE配置

创建外部工具

添加到工具栏

使用效果

点击工具栏按钮后,自动在全屏的 iTerm2 窗口新建或激活项目目录下的 CC 会话,下图里就是 3 个项目。

四、多Agent协作

会的越多,让你干的就越多。既然 AI 那么牛,一个 CC 会话已经满足不了我膨胀的想法和需求了。我希望我可以同时支配多个 AI 开发工程师,而我变成 PM!所以参考酒米的思路,我给每个项目的终端,自动化的划分了 3 个子窗口,每个子窗口都是一个 CC 会话。效果大概这样:

主从架构

每个项目自动打开 3 个常驻的 AI 会话,我设想的工作流是这样的:

【架构师】上面的大屏,用贵的模型!专门用来跟我聊需求、对方案、产出任务列表。

【开发者】下面的两个小屏,用领域特定的模型,专门用来落地大屏架构师产出的方案和任务。比如前端需求用前端效果好的模型,后端需求用后端效果好的模型。

知人善用才是好 PM!这个模式也很匹配现实中的组织架构和成本取舍,现实中每个需求一般也都是由一个架构师和多个中高级开发者来协作完成!感谢热心市民无声雨,给我们小组共享了自己采购的纯血 Claude 模型,所以目前我用 Claude 模型来对方案,用 GLM 或者 MiniMax 来实施方案!

规范驱动开发(SDD)

主从智能体的协作很重要,我跟【架构师】聊了半天确定的方案和设计,需要有一个清晰的、对大模型友好的方案和任务文档作为【开发者】的输入。这就很巧,刚好最近在流行 SDD,规范驱动开发。大致就是模拟现实中的软件开发流程将开发生命周期拆分为 3 个阶段:

  • 【proposal】需求对齐、方案设计、【任务细化】;
  • 【apply】开发任务实施;
  • 【archive】功能验收、文档沉淀

围绕这个流程,开源社区设计和研发了一系列对大模型非常友好的工具和提示词(比如 OpenSpec),【阶段 1】和【阶段 2】中间通过格式设计良好的【设计文档和任务文档】来进行上下文交接。

也就是说,我可以在上述的 3 窗口环境中,按照 SDD 流程来:【proposal】跟【架构师】交互,对齐需求、设计和任务 A  【apply】让【开发者 1】着手完成任务 A  【proposal】继续跟【架构师】交互,对齐需求、设计和任务 B  【apply】让【开发者 2】着手完成任务 B  【proposal】继续跟【架构师】交互,对齐需求、设计和任务 C  【apply】让【开发者 1】着手完成任务 C  ……

五、CC拓展

CC 当然很厉害,但它本质上也就是一个朴素的 ReAct 模式智能体。

ReAct 这么火,大家肯定也都耳熟能详了,我们也就不说太多。当然 CC 团队围绕编程这个课题做了很多细致的提示词调优和内置工作流设计,这个我们黑盒的用就好了,也没必要关注太多。我们最需要关注的,是 CC 提供给我们使用者的【拓展点】,那些允许我们个性化设置的东西。

命令(command)

命令的本质就是预定义的提示词模板。目的是为了省事,不用每次都重复的输入类似的提示词。比如想让 CC 帮我提交代码,每次我们可能都要交代一大堆字,比如:

请调用 git diff --cached 获取当前暂存区的代码变动。
忽略所有的 node_modules 或二进制文件。
基于变动内容,判断这是一个 feat (新功能), fix (修复) 还是 chore (杂务)。
生成一个不超过 50 字符的标题,并在正文详细列出影响的文件。
由我确认后执行 git commit。”

就像写代码的时候将重复代码提取为一个独立方法一样,我们可以把这些可以复用的提示词固定成一个【命令】,后续使用的时候,直接输入命令名字就好。斜杠命令是一段提示词的快捷方式。

技能(skill)

技能和命令最大的差别就是:命令是用户主动提交的提示词,而技能是 Agent 自己决策后自动导入的提示词。当然技能包里除了提示词,一般还会携带一些配套的工具、脚本、命令或者文档。

比如,我安装了一个【html 转 pdf 的技能包】,这只能提示 CC 可以使用这个技能,但是具体用不用、什么时候用、怎么用都是 CC 自己规划、决策的。

子代理(subAgent)

SubAgents 是可以并行处理任务的独立 AI 代理,每个子代理拥有独立的上下文窗口,可以分配不同任务以提高效率。【主代理】的上下文窗口中包含有【子代理】的【简短】描述信息,可以基于这个描述信息规划、决策使用哪个子代理。

{
  "agents":{
    "code-reviewer":{
      "description":"专门负责代码审查的子代理",
      "model":"claude-opus-4-5",
      "instructions":"你是一个专业的代码审查专家,专注于检查代码质量、安全漏洞和性能问题。",
      "tools":["read","search","git"],
      "permissions":{
        "allowWrite":false
      }
    },
    "test-writer":{
      "description":"专门负责编写测试的子代理",
      "model":"claude-sonnet-4-5",
      "instructions":"你是一个测试工程师,专注于编写全面的单元测试和集成测试。",
      "tools":["read","write","bash"]
    },
    "doc-generator":{
      "description":"专门负责生成文档的子代理",
      "model":"claude-sonnet-4-5",
      "instructions":"你是一个技术文档专家,专注于生成清晰、准确的技术文档。",
      "tools":["read","write"]
    }
  }
}

独立上下文窗口的好处是:避免上下文污染和占用。比如我要在代码里找一个接口的所有实现类,这个就很适合子代理来做。主代理只需要交代给子代理接口名,然后就等子代理返回实现类列表。

这样在主代理的上下文窗口里,只会有子代理的输入和输出(几个类文件路径),而子代理在搜索过程中遍历文件、目录、读取文件内容产生的临时 token,不会对主代理产生影响。我目前认为 SubAgent 和 Skill 差不太多。不过我不确认 Skill 是不是在独立的上下文中执行。

MCP

MCP 和技能一样,都是由 CC 自主规划、决策使用的。差别有两个:

  1. MCP 工具的说明信息占用的上下文太多了!不管是否被使用,每次都需要一口气提交所有工具的完整元信息(使用说明 + 出入参 Schema)供大模型规划、决策,占用大量上下文。而【技能】选择了【渐进式披露】,先向大模型提供少量关键信息,只有在大模型选择了使用技能时,才告诉大模型更多关于技能的补充说明信息,让大模型进一步推理、决策。

  2. MCP 工具更多的偏向【远程 RPC】,基于网络来实现原子化的远程能力调用。而【技能】更多的偏向【本地 IPC】,具体能力更多通过【编排】本地脚本、本地命令来实现,有点像 stdio 模式下的 MCP。

钩子(hook)

hook 是在特定事件触发时自动执行的脚本,用于自定义工作流、拦截危险操作、自动格式化代码等。就类似 Linux NetFilter,CC 在很多地方植入了流程执行的劫持点,将流程上下文交给用户开发的脚本或者命令。

插件(plugin)

plugin 就是上述各种拓展打包、分发、安装的一种格式。你可以把它想象成 npm 包、pip 包、apk 包等我们比较熟悉的概念。然后我们可以按流程和格式建设插件市场,类似 pip-index、npm-index 等。

我没有细看流程和格式,但是大概也就是一个特定文件布局的 zip 文件包,里面有插件描述信息和各类拓展,比如可以包含:

  • 5 个 Skills;
  • 10 个斜杠命令;
  • 3 个 MCP 服务器配置;
  • 2 个 SubAgent 定义;
  • 若干 Hooks。

六、CC技巧

飞书MCP

飞书官方提供了 MCP,我主要用它来读写飞书文档,蛮好用的,大家可以试试。比如我每周都要在固定目录下创建固定标题格式的【系统巡检文档】,所以我借助飞书 MCP 整了个自定义 Command 帮我自动创建这些文档去除重复劳动,感觉真香!之前每次都要手动建 3 个文档、选目录、改名字!

@模糊搜索

有时候我们需要精确的告诉 CC,哪个文件需要读或者改,其实不用从 IDE 里复制文件路径,直接在终端里模糊搜索就好了。

WebFetch

CC 默认集成了 WebFetch 命令,就是指定 URL 读取网页内容,这个理论上就是一个本地执行的 curl 命令,没有云端成本,不需要云端协作。但是有个问题:(一)CC 在访问地址之前,会先调用 anthropic.com 的一个风控接口,判断这个网络地址是否有安全风险。(二)政策原因,anthropic.com 会拒绝所有来自中国大陆、香港的请求,风控接口返回 404 或者其他。(三)风控不通过,WebFetch 失败。

在 ~/.claude/settings.json 中添加如下配置,禁用 WebFetch 工具前置的风控检查就好了。

{
  "skipWebFetchPreflight":true,
}

详见:linux.do/t/topic/114…

WebSearch

WebSearch 是需要云端协作的,需要有个搜索引擎服务提供能力。因为我们没有用官方的付费订阅,所以默认的 WebSearch 工具我们用不了,调用 WebSearch 工具得到的结果都是 0。

办法是去找一个免费或者收费的 MCP 服务。免费的我看大家都推荐 Brave<brave.com>,大家也可以找找别的。收费的也有很多,我看智谱的套餐里限量提供了 <联网搜索 MCP - 智谱 AI 开放文档>。也有很多按量付费的,大概几分钱一次,有需要的可以找找。

添加了 MCP 搜索工具后,建议禁用 CC 自带的 WebSearch 工具,不然每次跟大模型交互时,工具信息还会带给大模型,产生额外的 token 开销和推理误判。在 ~/.claude/settings.json 中添加如下配置:

{
  "permissions":{
    "deny":[
      "WebSearch"
    ]
  }
}

iTerm2通知

终端上的任务需要我们输入的时候,可以配置下,让 iTerm2 发出声音和通知。这样我们就不会因为忘记确认操作而阻塞进度。

详见:Optimize your terminal setup - Claude Code Docs

清空上下文

因为我们每个项目都复用一屏内的 3 个子窗口,一般不会重开。为了避免上下文溢出或者之前对话对新任务产生干扰,当我们完成一个任务时,需要及时的执行 /clear 命令,清空上下文,从 0 开始新对话。

如果任务没有完成,但是又不得不 clear,那么可以维护一个自定义命令,在 clear 后提示大模型根据 git status 看到的文件变更快速找回上下文。把 git 状态当作 AI 的 “短期记忆快照”,/clear 只清上下文,不清工作进度。

# Context Catch-up
当前对话已被 `/clear`,请通过 git 状态恢复上下文。
使用方式:
1. 阅读 `git status`(必要时结合 `git diff`2. 仅基于文件变更推断正在进行的任务
3. 延续现有实现思路,不要假设额外背景
4. 在未收到明确指令前,先给出你对当前上下文的判断
目标:
- 快速找回任务状态
- 避免旧对话或错误假设干扰新任务

注意力哨兵

在记忆文件里要求大模型扮演一个特别的角色,如果聊着聊着角色行为丢失了,说明大模型注意力失焦了,已经丢掉了你最开始的要求。这时候就该 clear 一下重开会话了。

拓展市场

为了便于相关个性化拓展物料的分发、便于大家搜索、安装,市面上已经有了相关的分发平台和便捷安装命令了。

  1. skills.sh

  1. www.aitmpl.com

状态行个性化

状态行显示在 Claude Code 会话界面底部,可以自定义显示的内容,比如git分支名、目录名、模型名等。推荐使github开源项目:claude-code-statusline-pro-aicodeditor,效果如下:

详见:github.com/HorizonWing…

七、总结

差生文具多,尽管我暂时还没有使用 CC 产出啥说得上来的东西,但是确实花了很多时间琢磨怎么让它用起来更顺手。一些不成熟的想法,希望可以给到大家启发。

参考:

  1. www.ginonotes.com/posts/how-i…
  2. www.cnblogs.com/knqiufan/p/…

往期回顾

1.AI编程能力边界探索:基于 Claude Code 的 Spec Coding 项目实战|得物技术

2.搜索 C++ 引擎回归能力建设:从自测到工程化准出|得物技术 

3.得物社区搜推公式融合调参框架-加乘树3.0实战

4.深入剖析Spark UI界面:参数与界面详解|得物技术

5.Sentinel Java客户端限流原理解析|得物技术

文 /羊羽

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

AI编程能力边界探索:基于 Claude Code 的 Spec Coding 项目实战|得物技术

作者 得物技术
2026年3月12日 11:20

一、前言

10 天,2.5 万行代码,提效 36%。 基于 Claude Code 的 Spec Coding(规格驱动编码) 深度实战。通过 2,754 次工具调用,我们不仅完成了从 0 到 1 的前端项目搭建,更在“约束+示范+视觉”的三层规范体系下,摸清了 AI 编程的真实能力边界。本文将复盘这场实战,拆解如何用结构化工作流消除 AI 的不确定性,重构开发者的核心竞争力。

二、Spec Coding

什么是 Spec Coding 工作流

众所周知,Spec Coding(规格驱动编码)的核心思想是:在写代码之前,先写规格文档。通过 openspec 工具,每个功能变更都经历以下阶段:

Spec 工作流的实际价值

减少返工: 在 proposal 阶段明确为什么以及怎么做,避免实现完才发现方向不对。适合复杂功能: 对于需要跨多个文件多个层次的功能,tasks 分组让 AI 聚焦在当前步骤。可审计: 每个 Change 的完整决策链(proposal→design→specs→tasks)都留有记录,方便回溯。

三、项目是什么

一个标准企业级中后台搭建,包括表格、表单、卡片列表、数据看板等中后台常见核心功能,项目从零搭建到完成以下全部功能,全程使用 Claude Code 辅助开发。

四、数据概览

在这次使用Claude Code 做 Spec Coding的从0到1项目探索中,我们积累了一份完整的原始数据,以下所有数字均来自Claude Code对 109 个 .jsonl 会话文件的整体数据统计:

2,754 次工具调用的分布揭示了 AI 的"工作方式", AI 自主完成的 738 次文件读取、550 次代码编辑、662 次终端命令执行,以及 208 次任务进度标记——几乎覆盖了一个研发日常工作的全部动作类型。

五、开发时间线:10 天的演进过程

阶段一:设计阶段

在动工之前,我们完成了产品方向的确认和 UI 设计稿、产品PRD的输出。过程主要使用 Cursor + 设计规范 Rules,直接从概念沟通到生成高保真 UI 稿(HTML文件),再生成标准的 PRD 需求描述,覆盖系统所有核心页面。这一阶段的产出是一套可直接用于开发对齐的视觉参考,也是后续 AI 生成代码时的重要上下文来源。

阶段二:项目搭建(2个工作日,20 条指令)

此阶段我们以问答式交互为主,聚焦于项目基础设施的搭建和简单需求的尝试。我们向 AI 提出架构问题,由 AI 给出方案,我们决策后执行。在这个过程中,AI 帮助我们熟悉技术栈、搭建项目结构、配置开发环境,并完成了第一个核心列表页面的开发,成功打通了前后端的数据链路。

阶段三:功能开发(4个工作日,89 条指令)

这是整个项目开发强度最高的阶段,我们引入了“规格驱动编码”(Spec Coding)的工作流,约 80% 的功能代码在此阶段完成。我们不再是简单地给 AI 下达指令,而是先与 AI 共同定义清晰的功能规格(Specification),然后 AI 基于这份“蓝图”自主进行编码。通过这种方式,我们高效地完成了包括授权管理、数据分析看板、文档树状结构等多个复杂功能的开发。

阶段四:细节打磨与生产部署(4个工作日,108 条指令)

最后阶段的工作重心转向功能迭代、系统重构和生产环境的部署排障。我们与 AI 一起,对已有功能进行了多轮优化,例如完善了核心业务流程、重构了侧边栏导航、修复了登录跳转逻辑等。同时,我们也对项目首页进行了深度的代码重构,解决了前期快速迭代中积累的技术债。最后,在部署阶段,我们遇到了复杂的构建问题,通过与 AI 的多轮分析和尝试,最终定位并解决了问题,成功将应用部署上线。

六、典型案例

案例一:AI 驱动产品设计

没有产品经理、没有 UI 设计师,一个工程师如何用 AI 独立完成从产品定义到高保真原型、再到研发文档的全流程。

背景:

传统意义上,从 0 到 1 开发一个企业级知识问答平台需要三个角色:产品经理(需求分析 + 用户路径 + PRD)、UI 设计师(交互稿 + 高保真设计稿)、工程师(编码实现)。这个项目设计过程中,通过让 AI 在不同阶段扮演不同角色,覆盖了全部三个职责。

让 AI 扮演产品经理:

在 Rules 中植入「首席产品专家」Persona 提示词,将 AI 从工程师的「急于执行」模式切换为产品经理的「先想清楚」模式,与 AI 聊清楚我们想干什么。

让 AI 扮演 UI 设计师:

在 Rules 中定义设计规范,通过对话式生成逐页产出高保真 HTML 文件,而不是源码:

让 AI 生成研发可读的 PRD:

基于产品经理角色,将 HTML 设计稿作为上下文,最后生成精确到组件行为级别的 PRD:

案例二:SDD 驱动前端功能研发

在已有系统上增量交付一个完整功能模块,SDD 如何保证「增量」功能快速开发,并系统性提升前后端联调效率。比如其中有个SSD需求开发「定时任务管理」完整模块,并且对接 6 个后端接口。这是 SDD 工作流第一次被完整运用于新功能模块开发,也是验证「SDD + MCP」前后端联调提效的关键场景。

页面功能开发: opsx:new 到 archive,人工指令 < 10 条,AI代码占比100%,交付完整任务管理模块(独立路由 + 完整 CRUD + 执行记录 + 检索结果)。

前后端联调: SDD + MCP 的联调路径:接口 URL → MCP直连文档 → 一次性获取字段、枚举、必填项 →  接口文件一次生成 → ****联调一次通过,6 个接口零联调返工。

研发效率: 同日额外交付了两个完整模块,3个独立完整模块,单日全部开发完成,按纯人工开发,当天人效提升3倍。

案例三:SDD 驱动系统重构

重构与新功能的根本差异:

新功能开发是「从无到有」:AI 可以大胆生成,错了删掉重来。重构是「在活体系统上动手术」:这种高风险对 AI 执行提出了截然不同的要求——不仅要知道改什么,更要知道不能改什么,以及按什么顺序改。 SDD 的价值正在于此:在动代码之前,把这三件事全部写清楚。

知识问答首页重构:

架构债务: 大量首页业务组件与公共组件混放、useChat 导出 20+ 方法(4 种无关职责混合)、ChatInterface 接收 17 个 props(参数3 层传递)。

执行TASKS: 9 组 34 个子任务,从「grep 确认组件当前归属」→「按新分层迁移」→「更新所有 import 路径」→「tsc 类型检查」→「冒烟验证」,每一步有明确输入和验收标准。

执行结果: 34个任务全部完成(含 4 个验证任务),AI 全程独立执行,人工干预 < 5 条指令。7个业务组件与公共组件完成解耦,useChat 拆为 3 个单职责 hook,ChatInterface 从 17 个 props 缩减至 6-8 个。

案例四:复杂问题排障

并不是所有编程相关的问题AI都可以解决,哪类工程问题从结构上超出了 AI 的能力边界?这里举一个遇到的场景。

其中有一天遇到一个测试环境构建失败的问题,结果过程约 4 小时,7 个会话、15+ 次方案尝试、59 条指令。整个项目单日指令最多的一天,也是 AI 独立解决能力最受限的一天。

这一天有一个值得注意的特征:AI 每次分析都是正确的——问题不在于 AI 的分析能力不足,而在于问题的结构性特征超出了 AI 的信息范围和反馈机制:

  • 云服务器构建时发生,本地无法复现: 每次验证方案必须提交代码等待 CI(一轮约 10 分钟),AI 分析的是日志截图,无法感知「现在的 CI 环境还有哪些隐性配置」。
  • 多根因互相掩盖,解决一层才暴露下一层: AI 每次分析都正确,但正确分析的只是当前暴露的那一层,问题全貌无法被单次分析覆盖。
  • 隐性行为无文档,根因藏在依赖源码内部: Prisma postinstall 境外下载没有任何显式错误,引导AI 不得不深入阅读 node_modules 源码第 2319 行才能发现根因。这类「运行时行为藏在依赖内部、没有文档描述」的问题,超出了 AI 通过训练数据或当前上下文主动推断的范围。

最后确认的原因:

  • .npmrc 历史副作用: 早期为跳过 @next/swc-darwin-arm64 在 Linux 下载而加入的 omit=optional,无意间也跳过了 @tailwindcss/oxide-linux-x64-gnu(Tailwind v4 的 native binding),postinstall 陷入循环等待
  • Prisma v6 境外下载沉默卡死: AI 需要阅读 node_modules/@prisma/fetch-engine/dist/index.js 第 2319 行才能发现这个行为——postinstall 不报错、不超时,只是无限等待。
  • pnpm 跨平台 lockfile 不一致: macOS arm64 生成的 lockfile 不含 Linux x64 的 native package;切回 npm 则 lockfile 被忽略,安装结果每次不同。

最终解法(4 小时探索后得出):

七、代码规范落地:CLAUDE.md 和 Rules 的实际效果

规范体系设计思想:三层结构

本项目的规范体系是三个层次的协同约束, 每层解决不同的问题:

第一层:约束层(.claude/rules/)      ← 告诉 AI「禁止什么、必须怎样」
第二层:示范层(.claude/code-design/)← 告诉 AI「标准产出长什么样」
第三层:视觉层(.claude/ui-design/)  ← 告诉 AI「页面应该长什么样」

为什么需要三层?

只有「约束层」时,AI 知道规则但缺乏参考实现,容易在复杂场景下产生符合规则但不符合团队风格的代码。加入「示范层」和「视觉层」后,AI 可以直接对齐团队的标准产出,减少「虽然合法但不地道」的代码。

第一层:约束层(.claude/rules/)

7 个规范文件,分别约束不同维度:

.claude/rules/
├── ts.md          # TypeScript 规范(禁止 any、使用可选链等)
├── code-names.md  # 命名规范(kebab-case/camelCase/PascalCase)
├── comment.md     # 注释规范(JSDoc、@ai-context/@ai-rules 文件头)
├── lint.md        # 代码风格(单引号、文件末尾换行)
├── style.md       # 样式规范(Tailwind CSS、less 文件)
├── pages.md       # 页面目录结构规范(constants/services/hooks/components 分层)
└── service.md     # API 接口生成规范(fetch{Name}Api 命名、UniversalResp 泛型)

第二层:示范层(.claude/code-design/)

将项目常见场景预置完整的「标准模板代码」,AI 在生成新页面时可以直接参照,后续可以切换为skills:

.claude/code-design/
├── pro-table/          # 通用列表页模板(含搜索、分页、批量操作、行操作)
├── pro-form/           # 通用表单页模板(含创建/编辑双模式、字段验证)
├── editable-pro-table/ # 可编辑表格模板(含行内编辑、添加/保存/删除)
├── drawer/             # 抽屉组件模板(含标准打开/关闭逻辑)
├── compontent/         # 通用组件模板(含 README、Props 定义、使用示例)
└── utils/              # 工具函数模板

示范代码的作用不只是「看个格式」。以 pro-table 为例,当开发者让 AI「参考 .claude/code-design/pro-table 生成知识治理列表页」时,AI 直接继承了这套模式,一次就能生成符合团队风格的代码,无需多轮调整。

第三层:视觉层(.claude/ui-design/)

注意存放 HTML 设计稿,覆盖主要页面的视觉参考:

.claude/ui-design/
├── knowledge-spaces.html  # 知识空间列表页设计稿
├── search-strategy.html   # 检索配置页设计稿
├── space-detail.html      # 空间详情页设计稿
└── xxx设计稿

这些 HTML 文件可以直接在浏览器中打开预览,AI 也可以读取其中的结构和样式信息。实践中,提供 HTML 设计稿后,AI 生成的 UI 与设计意图的吻合度明显高于纯文字描述,尤其是布局结构、颜色方案、间距配置等细节。

规范约束的实际效果

正面效果(规范被遵循的案例):

  • 接口命名一致性: 所有接口函数均以 fetch{Name}Api 命名,类型以 I{Name}Req/Res 格式,整个项目 205 个文件保持高度一致。
  • 目录分层被遵守: constants/、services/、hooks/、components/ 分层在每个新页面中都被正确创建。
  • 代码模板被继承: CURD页面均参照了 pro-table 模板的 hooks 分离方式,代码结构高度一致。
  • 使用可选链: 几乎所有数据访问都使用了 ?. 和 ??,有效避免运行时报错。

需要人工干预的案例:

  • 2/24,AI 生成知识空间列表后,将所有代码写在单文件中,未按规范分层。通过一条追问后,AI 重构为正确结构。
  • 2/27,AI 错误地使用了 .less 后缀,但项目实际配置使用 SCSS,在收到错误提示后立即修正。
  • 出现 antd v5 废弃 API(destroyOnClose、dropdownStyle),AI 习惯于使用训练数据中更常见的旧 API,需要通过报警信息触发修正。

结论:

规范体系对 AI 的约束是有效的,但规范文件只是「约束」而非「能力」——只有「约束层」时,AI 知道不能做什么,但遇到复杂场景仍可能生成不够地道的代码;加入「示范层」和「视觉层」后,AI 有了对齐的锚点,输出质量和一致性明显提升。

八、MCP 工具:消除信息断层

在 AI 辅助前端开发中,有两类高频信息断层,在此项目中进行了接入:

接口文档断层: 接口文档在 API平台,AI 无法直接访问,只能靠用户手工复制字段,容易遗漏、版本不一致。需求文档断层: PRD、设计文档存在飞书云文档中,每次引用都需要用户打开→复制→粘贴到对话框,打断思路。

MCP 一:接口文档直连

通过该工具,AI 可以根据接口 URL 自动拉取完整接口文档——包括入参字段、出参结构、枚举值定义、必填项标注。累计被调用了 21 次,完成39个接口联调 ,覆盖了几乎所有接口的初次接入和更新迭代场景。服务端接口未生效之前,并且支持同步生成mock数据,减少后端依赖。interface.ts 类型定义质量非常高,字段注释完整,无需人工校对。

MCP 二:飞书云文档直读

通过该MCP工具,AI 可以直接读取飞书云文档的内容(PRD、设计说明、技术文档等),无需用户手工打开→复制→粘贴。

典型应用场景:

九、AI Spec Coding 经验总结

重新理解「AI 辅助编程」是什么

流行的说法是「AI 是你的 Copilot」。这个比喻在日常补全层面成立,但在 Spec Coding 实践之后,我更倾向于另一个模型:AI 是一个极度服从、无限耐心、但没有内部业务知识常识的「顶级执行者 」。

这个比喻捕捉了三个关键特征:

极度服从: AI 会一字不差地执行你写的规范,不会主动质疑「这样做合理吗」。这是优势,也是风险——规范写得越准确,执行越可靠;规范有歧义,AI 会选一个「看起来合理」的解释,而不是停下来问你。

无限耐心: 34 个任务的重构、9 组联调任务、跨会话的上下文恢复——这些在人类身上需要消耗大量意志力的事情,AI 做起来没有摩擦成本。本项目 208 次 TodoWrite 调用背后,是 AI 持续更新进度状态、从不嫌烦的特性。

没有内部业务常识: AI 不知道你们公司的部署环境是什么样的,不知道这个接口上周刚换过版本,不知道「这个交互做成这样用户会抱怨」。它只知道你告诉它的。这也是 3/4 生产构建排障花了大量时间的根本原因。

AI 的能力边界在哪里

从 10 天、2,754 次工具调用中,我们归纳出一个更精确的能力边界框架,而不是简单的「能做/不能做」:

真实项目中的并不是所有的需求都值得写一份 Spec。在真实的项目迭代中,我们需要根据需求颗粒度来选择协作模式。

小颗粒需求:对话框即扫即改

  • 场景:改个文案、修个显隐逻辑、调整 CSS 间距。
  • 策略:直接在 Cursor Chat  中对话。
  • 理由:沟通成本低于编写规范的成本,AI 的即时反馈效率最高。

中颗粒标准化需求:基于Rules 或者 Skills 预设规范生成

  • 场景:增加一个标准的 CRUD 页面、创建一个简单的业务组件。
  • 策略:利用预设的 Cursor Rules 或 Skills(如 pro-table.mdc)。
  • 理由:这类需求有强烈的“模式感”。只要规则定义清晰(如“执行流程:识别场景 -> 读取示例 -> 生成类型 -> 完成 UI”),AI 就能基于标准化模板高质量输出。

中大颗粒复杂功能:OpenSpec 深度协作

  • 场景:重构核心逻辑、新增带有复杂业务逻辑的模块、无参考代码的新功能。
  • 策略:OpenSpec 标准流 (SDD)。
  • 理由:业务逻辑复杂时,AI 极易产生幻觉或需求偏移。通过 Spec 强制进行“先设计后编码”,可以确保 AI 的每一步都在既定轨道上,且 Spec 记录了设计的决策过程,对于后期维护价值巨大。

AI 失效的三种模式

经过本项目的实践,AI Coding 的失效不是随机的,而是可归类的:

模式一:规范真空

任务涉及的领域没有规范约束,AI 自行填充「合理默认值」。

  • 表现:生成的代码功能正确,但风格/结构偏离团队约定。
  • 发生频率:高(尤其在新功能开发初期)。
  • 应对:在 CLAUDE.md 或 code-design 中补充对应规范,一次修复,全局生效。

模式二:信息孤岛

AI 掌握的信息是当前会话的快照,看不到系统外的状态。

  • 表现:本地正常,CI 失败;AI 分析每次都对,但解的都是当前暴露的问题。
  • 发生频率:低,但代价高。
  • 应对:跨平台、跨环境的依赖要在架构设计阶段提前锁定;环境差异要写成规范前置处理。

模式三:任务目标模糊

AI 把「该问人的问题」当成「执行问题」来解决。

  • 表现:用户说「优化一下首页」,AI 悄悄改了组件结构,而不是先澄清目标。
  • 发生频率:中。
  • 应对:Spec 工作流的 proposal 阶段强制要求先描述「Why」,避免 AI 自行填充目标。

开发者角色的重构

AI Coding 不是让开发者「消失」,而是让开发者的工作向上迁移:

这意味着:

规范设计能力成为 AI 时代开发者的核心竞争力——能写出让 AI 可靠执行的规范,价值比能写出同等功能代码更高。

系统性思维变得更重要——生产构建问题的排障经历说明,AI 可以帮你解决每一个局部问题,但无法帮你看到真实业务全局。

质量意识前移——过去 Code Review 在代码写完后进行,现在需要在 方案设计/任务执行 阶段就介入,而不是等 AI 执行完再纠错。

值得期待的方向

基于本项目的数据和经验,后续在以下方向可作深入探索:

规范体系的结构化积累: 每次踩坑后补充到 CLAUDE.md/rules,形成团队共享的「AI 执行约束库」。目前 7 条规范文件是手动维护的,下一步可以建立「踩坑→提炼规范→自动追加」的闭环。

MCP 工具链的纵向延伸: 本项目 MCP 仅覆盖了接口文档、飞书文档。后续针对设计稿、测试用例、发布平台、日志平台接入,可以进一步形成完整的AI Coding链路。

多 Agent 并行开发: 本项目开发过程中,发现大型任务执行等待时间较长,下一步可以尝试多Agen并发生成,同时开发不同功能模块。

一句话总结

AI Coding 的本质不仅仅是用 AI 写代码,而是用结构化的规范和工作流把不确定性消除在执行之前——AI 负责在确定性空间里高速执行,人负责维护和扩展那个确定性空间的边界。

10 天、217 条指令、2,754 次工具调用、25,546 行净增代码——这个数字背后,是一套让 AI 可以「看见」、「理解」、「遵守」团队约定的规范体系。规范是杠杆,AI 是力,Spec 工作流是支点。

本报告由claude code基于claude code 109 个真实历史会话、2,754 次工具调用记录生成,人工补充并校准,数据来源:~/.claude/projects/-Users-admin-Desktop-code-knowledge-qa/。

往期回顾

1.搜索 C++ 引擎回归能力建设:从自测到工程化准出|得物技术

2.得物社区搜推公式融合调参框架-加乘树3.0实战 

3.深入剖析Spark UI界面:参数与界面详解|得物技术

4.Sentinel Java客户端限流原理解析|得物技术

5.社区推荐重排技术:双阶段框架的实践与演进|得物技术

文 /阳凯

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

❌
❌