阅读视图

发现新文章,点击刷新页面。

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

一、背景

推荐系统在提升用户体验的同时,也面临着信息茧房、兴趣收敛和内容同质化的挑战。随着用户与系统交互的深入,"推荐→用户反馈→再推荐"的闭环会逐渐强化用户的少数主兴趣,导致推荐结果趋同,降低用户的新鲜感与满意度。

生成式AI技术的快速发展为推荐系统带来了新的机遇。与传统的判别式匹配范式不同,生成式召回通过预测用户下一个可能点击的内容,实现从"匹配已知"到"预测潜在"的范式转变。在得物社区这一潮流生活方式平台上,用户对内容多样性和新颖性的需求尤为突出,这为生成式召回的探索提供了天然的场景。

基于此背景,得物启动了生成式召回方向的一期探索,旨在为下一代智能推荐系统的构建积累经验,探索推荐系统的 scaling-law 规律。

传统召回方法的局限性与生成式召回的动机

传统判别式ANN召回的局限性

  • 时序信息建模不足:难以有效捕捉用户行为序列中的长期兴趣、短期偏好及其动态演变过程。
  • 兴趣多样性受限: 基于历史行为的匹配范式容易收敛到少数高频兴趣点,难以拓展用户的兴趣广度。
  • 匹配范式天花板:判别式兴趣建模受限于已有历史数据,难以预测用户未来的、潜在的兴趣方向。
  • 兴趣融合能力弱:各兴趣点通常独立建模,缺乏对用户多兴趣间协同关系的端到端建模能力。

生成式召回的核心优势

  • Next-Token Prediction 范式:通过预测用户下一个可能点击的内容,实现端到端的用户兴趣融合建模。
  • 引导式召回机制:为生成式模型提供可控的、结构化的召回条件,确保召回内容的相关性与业务目标一致性。
  • 时序依赖建模:基于 Transformer 架构,自然捕捉用户行为序列中的时序依赖关系。
  • 兴趣预测能力:不仅能匹配已知兴趣,还能基于历史行为模式,预测用户的潜在兴趣方向。
  • 端到端优化:从用户行为序列直接生成召回结果,减少中间环节的信息损失。
  • 具有 scaling-law 规律:随着样本与模型规模的提升,能大幅提高模型的表达能力,提高线上的推荐效果。

二、技术方案

得物生成式召回系统采用 Generative Model 与 Rerank Model 联合训练的端到端设计,实现了生成与排序的协同优化。

image.png

Generative Model设计细节

生成式模型基于 Transformer 架构实现 Next-Token 生成任务,主要特征包括:

  • 主序列特征:使用用户图文和视频的有效点击序列,以及对应的一 / 二 / 三级类目序列,截断最近 100 个行为;
  • 首位 User Token 生成策略:联合训练辅助双塔模型产出首位 user_token,通过梯度隔离机制,确保生成任务与双塔任务的独立优化;
  • 模型参数配置:采用当前 DeepRec 框架可承受的最大参数规模,配置为 n_layers=3,n_heads=4,dim=64,并加入 position embedding,增强时序建模能力。

Rerank Model设计细节

重排模型与生成式模型联合训练,通过多任务学习提升召回精度:

  • 联合训练机制:通过召回目标同时训练 rerank 模型的 item 塔与 user 塔,与 Generative Model 共享底层特征表示;
  • 多任务梯度平衡:设计合理的损失权重分配策略,确保生成任务与重排任务的梯度协同优化。

推理过程:从一级类目生成到精准召回

生成式召回在线上推理时遵循"生成→向量化→检索→重排"的四步流程,兼顾了生成式模型的预测能力与向量检索的效率。

一级类目生成

推理过程首先通过生成式模块的 Decoder 生成 Top-K 一级类目。经过离线 recall@100 参数搜索对比,确定 K=4 为最优配置,在召回效果与计算成本间取得平衡。生成的一级类目作为后续步骤的 “硬条件” 向量,为多兴趣建模提供结构化引导。

多兴趣向量构造

基于生成的 K 个一级类目,通过条件双塔的 user_tower 分别得到图文和视频的 K 个用户兴趣向量。这一设计实现了兴趣解耦,每个兴趣向量专注于特定类目下的用户偏好,避免了传统单向量表示中的兴趣混淆问题。

ANN召回与Rerank排序

各兴趣向量分别进行 ANN 向量检索,从候选池中召回相关 item。召回结果再由 Rerank 模型进行精细化打分排序,最终通过蛇形 Merge 策略将多个兴趣通道的结果融合,作为最终召回列表输出。

三、实验效果

为验证生成式召回的实际效果,我们在得物社区进行了严格的AB测试。结果也带来了社区线上指标的显著提升。验证了生成式算法的在得物落地的可行性,并预示着更大的探索潜力。

核心消费指标显著提升

生成式召回在多个核心消费指标上取得显著正向效果:

指标名称 相对提升(%) 显著性
人均推荐有效VV +0.41% 显著
社区DAU均时长(秒) +0.37% 显著
人均推荐总时长(秒) +0.45% 显著
推荐曝光UV人均内容VV +0.39% 显著

多样性指标改善

除了消费深度,生成式召回在兴趣广度拓展上也表现突出:

多样性指标 相对提升(%) 显著性
人均点击一级类目数 +0.18% 显著
人均点击三级类目数 +0.23% 显著
人均曝光三级类目数 +0.19% 显著

未来工程优化方向

基于一期实践经验,后续工程优化将聚焦于:

  • 框架迁移:从 DeepRec 迁移至 DeepSea-Torch 框架,支持更大参数量与稀疏特征;
  • 架构升级:探索 One-Rec 框架落地,统一生成式与判别式召回范式;
  • 推理加速:研究模型压缩、量化等推理优化技术,进一步降低服务延迟;
  • 成本优化:通过训练策略改进和资源调度优化,降低单位效果的成本。

四、总结与展望

得物生成式召回一期实践表明,通过 “生成预测 + 引导召回” 的技术路径,可以在可控成本下,同时实现用户消费深度与兴趣广度的双重提升,为下一代智能推荐系统的构建提供了重要参考。本次实践成功验证了生成式召回在工业级推荐场景的可行性与有效性。通过 Generative Model 与 Rerank Model 的联合训练架构,实现了从判别式匹配到生成式预测的成功范式迁移。技术方案在保持推荐相关性的同时,显著提升了兴趣探索能力,为打破信息茧房提供了新的技术路径。

当前方案以一级类目作为生成目标,这是考虑到类目体系的稳定性和可解释性。下一步将基于社区样本训练 Item Embedding,并将 Item Token 离散化与用户 Next-Token 生成任务联合训练。这一演进将实现从粗粒度到细粒度的兴趣预测,提升召回的精准度。

模型能力升级

通过框架迁移大幅提升模型参数量,支持大规模稀疏特征,探索更强大的生成式模型架构。具体方向包括:

  • 扩展上下文窗口:从当前的 100 行为扩展到更长序列,更好建模用户长期兴趣;
  • 改进注意力机制:研究稀疏注意力、线性注意力等高效注意力变体,平衡效果与效率。

与LLM结合的可能性

借鉴得物在基于大语言模型的新颖性推荐上的经验,生成式召回可与 LLM 知识增强结合。LLM 的世界知识可以帮助识别用户潜在但未明确表达的兴趣,而生成式模型则负责将这些兴趣转化为可执行的召回策略,形成知识增强的生成式召回新范式。

多模态与跨域生成

探索利用多模态信息生成更丰富的用户兴趣表示,并尝试跨业务域的生成式兴趣迁移。在得物的业务生态中,社区内容与电商商品之间存在天然关联,通过跨域生成式召回,可以实现从内容兴趣到商品需求的自然过渡,提升业务协同价值。

往期回顾

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

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

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

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

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

文 /流煜曦

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

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

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

让 Claude Code 在你睡觉时持续运行:完整实战指南

Claude Code 可以通过 -p 标志、权限绕过、循环模式和终端持久化的组合,实现数小时甚至整夜的无人值守运行。 开发者社区已经形成了一套可靠的操作手册:容器化运行环境、使用 “Ralph Wiggum” 循环模式、安装四个关键 Hook 防止卡死、保持 CLAUDE.md 精简。有开发者记录了 27 小时连续自主会话完成 84 个任务;另一位在睡觉时让 Claude 构建了一个 15,000 行的游戏。但社区也反馈,大约 25% 的过夜产出会被丢弃,而且如果没有适当的防护措施,Claude 曾在至少一位开发者的机器上执行过 rm -rf /。以下是你今晚就能用上的完整设置方案。


一、消除人工干预的三种模式

Claude Code 提供三个级别的自主运行模式,每个级别都在安全性和速度之间做取舍。理解它们是所有过夜方案的基础。

模式 1:-p(print/pipe)标志 —— 所有自动化的核心。 这是非交互式运行模式。接收 prompt,执行到完成,输出到 stdout,然后退出。无需 TTY,512MB 内存的服务器也能跑。

1
claude -p "查找并修复 auth.py 中的 bug" --allowedTools "Read,Edit,Bash"

模式 2:--permission-mode auto —— 更安全的折中方案。 2026 年初推出,使用 Sonnet 4.6 分类器自动批准安全操作,同时阻止高风险操作。分类器分两阶段运作:快速判定(8.5% 误报率),对标记项目进行思维链推理(0.4% 误报率)。如果连续 3 次操作被拒绝或单次会话累计 20 次被拒,系统会升级到人工介入——或者在 headless 模式下直接终止。

1
claude --permission-mode auto -p "重构认证模块"

模式 3:--dangerously-skip-permissions —— 完全绕过权限。 所有操作无需确认直接执行。Anthropic 自己的安全研究员 Nicholas Carlini 也使用这个模式,但有一个关键前提:*”在容器里跑,不要在你的真实机器上。”* 一项调查发现 32% 的开发者使用这个标志时遭遇了意外的文件修改,9% 报告了数据丢失

1
2
# 仅限 Docker/VM —— 绝对不要在宿主机上运行
claude --dangerously-skip-permissions -p "构建这个功能"

推荐的过夜运行方式是将 -p 与细粒度工具白名单 --allowedTools 结合使用,允许特定命令而非授予全面访问权限:

1
2
3
4
claude -p "修复所有 lint 错误并运行测试" \
--allowedTools "Read" "Edit" "Bash(npm run lint:*)" "Bash(npm test)" "Bash(git *)" \
--max-turns 50 \
--max-budget-usd 10.00

--max-turns--max-budget-usd 是无人值守会话的必备成本控制手段。没有它们,一个失控的循环可以在几分钟内烧光你的 API 预算。


二、Ralph Wiggum 循环:开发者的实际过夜方案

最经过实战验证的长时间自主工作模式是 Ralph Wiggum 循环——以《辛普森一家》中的角色命名,现已成为 Anthropic 官方插件。概念非常简单:一个 bash while 循环持续向 Claude 喂相同的 prompt。每次迭代中,Claude 查看当前文件状态和 git 历史,选择下一个未完成的任务,实现它,然后提交。

1
2
3
4
5
while true; do
claude --dangerously-skip-permissions \
-p "$(cat PROMPT.md)"
sleep 1
done

那位记录了 27 小时会话 的开发者使用了这个模式,配合一个详细的 prompt 文件,包含架构说明、目标、约束条件和明确的”完成”标准。他的核心发现:*”一句话 prompt 在一两个小时后就没劲了。27 小时的会话能持续下去,是因为 prompt 文件有足够多的上下文。”*

Prompt 文件比循环本身更重要。 一个有效的过夜 PROMPT.md 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 任务:测试并加固认证系统

## 上下文
- 后端:Express + TypeScript,位于 src/api/
- 数据库:PostgreSQL,schema 在 prisma/schema.prisma
- 认证流程:JWT 中间件在 src/middleware/auth.ts

## 目标
- 查看 docs/plan.md,选择下一个未完成的任务
- 实现它,包含完善的错误处理
- 运行测试,修复失败,确认没有回归
- 做通用修复,不要打临时补丁
- 每完成一个任务后用描述性消息提交

## 成功标准
- 每次修改后所有测试通过
- 不会引入之前修复的回归
- 当 plan.md 中所有任务完成后输出 DONE

社区有几个工具扩展了这个基础循环。Ralph CLI 增加了速率限制(100次调用/小时)、熔断器、会话过期(默认24小时)和实时监控仪表板。Nonstop 增加了飞行前风险评估和阻塞决策框架——走之前输入 /nonstop 即可。Continuous-claude 自动化完整 PR 生命周期:创建分支、推送、创建 PR、等待 CI、合并。


三、防止过夜灾难的四个 Hook

开发者 yurukusa 记录了 108 小时无人值守运行,识别出七类过夜事故——包括 Claude 执行 rm -rf ./src/、进入无限错误循环、直接推送到 main 分支,以及产生每小时 8 美元的 API 费用。解决方案:四个关键 Hook,共同预防最常见的故障模式。

10 秒快速安装:

1
npx cc-safe-setup

Hook 1:No-Ask-Human 阻止 AskUserQuestion 工具调用,强制 Claude 自主做出决定,而不是坐在那里等几小时等人回复。这个 Hook 决定了 Claude 是整夜工作还是在晚上 11:15 卡住。在你坐在电脑前时,用 CC_ALLOW_QUESTIONS=1 覆盖。

Hook 2:Context Monitor 将工具调用次数作为上下文使用量的代理指标,在四个阈值(剩余 40%、25%、20%、15%)发出分级警告。在临界水平时,配套的空闲推送脚本会自动向终端注入 /compact 命令——两个进程,共 472 行代码,零人工干预

Hook 3:Syntax Check 在任何文件编辑后立即运行 python -m py_compilenode --checkbash -n,在错误级联成 50 次调试之前就捕获它们。

Hook 4:Decision Warn 在执行前标记破坏性命令(rm -rfgit reset --hardDROP TABLEgit push --force)。通过 CC_PROTECT_BRANCHES="main:master:production" 配置受保护分支。

.claude/settings.json 中配置:

1
2
3
4
5
6
{
"permissions": {
"allow": ["Bash(npm run lint:*)", "WebSearch", "Read"],
"deny": ["Read(.env)", "Bash(rm -rf *)", "Bash(git push * main)"]
}
}

四、tmux 设置与保持机器不休眠

Claude Code 的交互模式需要 TTY —— 不能用 nohup 或将其作为 systemd 服务运行(大约 15-20 秒后会因 stdin 错误崩溃)。tmux 是会话持久化的必备工具

1
2
3
4
5
6
7
8
9
10
11
12
13
# 启动命名会话
tmux new -s claude-work

# 在其中启动 Claude
claude --permission-mode auto

# 分离(Claude 继续运行):Ctrl+B,然后按 D

# 从任何地方重新连接(SSH、手机 Termius 等)
tmux attach -t claude-work

# 不连接就查看进度
tmux capture-pane -t claude-work -p -S -50

对于真正的 7×24 运行,社区推荐 VPS + Tailscale + tmux 方案:便宜的 VPS(Hetzner、Vultr、DigitalOcean)提供永不关机的算力,Tailscale 提供私有网络,mosh 在不稳定网络上保持连接持久性。给 Claude 一个任务,分离,合上笔记本,明天再回来。

macOS 防止休眠:

1
2
3
4
5
# 绑定到 Claude 进程
caffeinate -i -w $(pgrep -f claude) &

# 或者在接通电源时全局禁用休眠
sudo pmset -c sleep 0

管理多个并行会话方面,Amux 是一个约 12,000 行的 Python 文件,提供 Web 仪表板、手机 PWA 监控、自愈看门狗(自动重启崩溃会话)、按会话 token 追踪和 git 冲突检测。Codeman 提供类似的 Web UI,带 xterm.js 终端,支持最多 20 个并行会话。

一个强大的过夜 agent tmux 配置:

1
2
3
4
5
6
7
8
9
#!/bin/bash
tmux new-session -d -s claude-dev
tmux rename-window -t claude-dev:0 'Claude'
tmux new-window -t claude-dev:1 -n 'Tests'
tmux new-window -t claude-dev:2 -n 'Logs'
tmux send-keys -t claude-dev:0 'claude --permission-mode auto' Enter
tmux send-keys -t claude-dev:1 'npm run test:watch' Enter
tmux send-keys -t claude-dev:2 'tail -f logs/app.log' Enter
tmux attach-session -t claude-dev

五、CLAUDE.md 与长时间运行的上下文管理

过夜失败的最大原因是上下文窗口耗尽。Claude Code 的上下文窗口大约 200K token,使用率超过 70% 时性能开始下降。自动压缩在接近阈值时触发,但会丢失信息——仅保留 20-30% 的细节。有开发者报告 Claude 压缩后遗忘了所有内容,重新开始同一个任务,浪费了三个小时。

解决方案是检查点/交接模式,能够在上下文重置后存活:

1
2
3
4
5
6
# 在 CLAUDE.md 中
当上下文变大时,将当前状态写入 tasks/mission.md。
包括:已完成的、下一步的、被阻塞的、未解决的问题。
错误处理:最多重试 3 次。如果没有进展,记录到
pending_for_human.md 然后转到下一个任务。
压缩前,务必保存完整的已修改文件列表。

将 CLAUDE.md 控制在 200 行以内——每个词在每个会话中都消耗 token。从 800 行切换到 100 行的开发者达成社区共识:更短的配置实际上表现更好,因为 Claude 不会忽略被噪音淹没的指令。使用”仅在不可逆时才提问”规则,将提问频率降低约 80%:

1
2
3
4
5
6
# 自主运行的决策规则
- 技术方案不确定 → 选择传统方案
- 两种可行实现 → 选择更简单的那个
- 尝试 3 次后仍有错误 → 记录到 blocked.md,切换任务
- 需求模糊 → 应用最合理的理解,记录假设
- 永远不要提问。做出最佳判断然后继续。

CLAUDE.md 文件是分层的:~/.claude/CLAUDE.md(全局)、./CLAUDE.md(项目级,git 追踪)、.claude/CLAUDE.local.md(个人覆盖,gitignore)。自主运行时,全局文件保持最小,把运行特定指令放在项目文件中。

关键 token 节省技巧:在里程碑后主动使用 /compact,而非等待自动压缩;对独立任务使用子 agent(每个有自己的上下文窗口);不相关的工作启动新会话;积极使用 .claudeignore 排除无关文件。


六、过夜运行的速率限制处理

速率限制作为三个独立的、重叠的约束运作:每分钟请求数、每分钟输入 token 数、每分钟输出 token 数。一个可见的命令在内部可能产生 8-12 个 API 调用(lint、修复、测试、修复循环)。15 次迭代后,单个请求可能发送 20 万+ 输入 token

过夜运行速率限制生存策略:

在非高峰时段运行。 Anthropic 确认工作日太平洋时间早 5 点到 11 点限制更严格。过夜运行和周末会话完全避开高峰期限流——恰好就是你在睡觉的时候。

利用 Ralph 循环的内置重试。 运行 while 循环时,速率限制错误只会导致当前迭代失败,但循环不在乎——它在速率限制窗口重置后的下一次迭代中重试。有开发者警告:*”不要在 API/按用量计费模式下运行——重试会烧光你的预算。”*

运行中切换模型。 Sonnet 能处理 60-70% 的常规任务,每 token 成本比 Opus 低约 1.7 倍。过夜工作设置 --model sonnet,将 Opus 留给复杂推理。也可以设置 --fallback-model sonnet,让 Claude 在主模型过载时自动降级。

Token 消耗的真实数据:20 条消息会话消耗约 105,000 token;30 条消息会话跳到 232,000 token。大约 98.5% 的 token 花在重新读取对话历史——只有 1.5% 用于实际输出。这就是为什么全新会话和积极压缩如此重要。

成本估算:持续运行 Sonnet 大约 $10.42/小时。基于 cron 每 15 分钟运行一次的 agent,预计约 $48/天。使用 --max-budget-usd 作为硬上限。


七、CI/CD 流水线与 Cron 任务集成

对于计划性的自动化工作,Claude Code 可直接与 CI/CD 系统集成。官方 GitHub Action 是 anthropics/claude-code-action@v1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: "审查这个 PR 的安全和代码质量问题。"
claude_args: "--max-turns 5 --model claude-sonnet-4-6"

对于基于 cron 的自主 agent,Boucle 模式通过 state.md 文件在运行之间维持状态:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# run-agent.sh —— 由 cron 调用
STATE="$HOME/agent/state.md"
LOG="$HOME/agent/logs/$(date +%Y-%m-%d_%H-%M-%S).log"

claude -p "你是一个自主 agent。读取你的状态,决定做什么,
然后用你学到的内容更新 state.md。
$(cat $STATE)" \
--allowedTools Read,Write,Edit,Bash \
--max-turns 20 \
--max-budget-usd 1.00 \
--bare 2>&1 | tee "$LOG"
1
2
# crontab -e
0 * * * * /path/to/run-agent.sh

200 次迭代后的关键教训:state.md 必须保持在 4KB 以下(它会被注入每个 prompt),使用结构化键值对而非散文,并添加文件锁防止重叠运行。每次迭代后 git commit——git log 就是你最好的调试工具。

CI 环境使用 --bare 模式(跳过 hook、MCP 服务器、OAuth 和 CLAUDE.md 加载,最快最可复现的执行方式)和 --permission-mode dontAsk(拒绝所有未显式允许的操作——自动化环境中最安全的模式)。


八、已知陷阱与可能出错的地方

社区已广泛记录了以下故障模式:

故障模式 后果 预防方法
破坏性命令 Claude 运行 rm -rfgit reset --hard 或覆盖生产数据 PreToolUse hook 阻止危险命令;Docker 配合 --network none
无限错误循环 修复 → 测试 → 同样错误 → 修复 → 重复 20+ 次 CLAUDE.md 规则:”最多重试 3 次,然后记录到 blocked.md 继续下一个”
压缩后上下文丢失 Claude 遗忘一切,重新开始同一任务 压缩前将状态写入 mission.md;使用 Ralph 循环获得全新上下文迭代
权限提示阻塞 会话无限期挂起等待人工输入 No-Ask-Human hook;--dangerously-skip-permissions--permission-mode auto
直接推送到 main 未测试的代码部署到生产环境 分支保护规则;PreToolUse hook 阻止 git push 到受保护分支
API 成本失控 子 agent 进入循环调用外部 API($8/小时) --max-budget-usd;速率限制 hook;熔断器
OAuth token 过期 中途打断自主工作流 所有自动化使用 ANTHROPIC_API_KEY 环境变量而非 OAuth
订阅 ToS 违规 用 Pro/Max 订阅(非 API key)的 headless 模式可能违反消费者条款 自动化/脚本使用务必用 ANTHROPIC_API_KEY

最重要的单一安全措施是容器化。多位经验丰富的开发者独立推荐使用带网络隔离的 Docker:

1
2
3
4
5
docker run -it --rm \
-v $(pwd):/workspace -w /workspace \
--network none \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
claude-code:latest --dangerously-skip-permissions -p "$(cat PROMPT.md)"

正如一位开发者所说:*”用 --dangerously-skip-permissions 运行 Claude Code 就像不做防护措施。所以用个套… 我是说容器。”*


九、今晚的快速启动清单

15 分钟设置过夜自主运行:

  1. 创建 git 检查点git add -A && git commit -m "pre-autonomous checkpoint"
  2. 安装四个关键 Hooknpx cc-safe-setup
  3. 编写 PROMPT.md,包含架构上下文、任务列表、成功标准,以及每完成一个任务就提交的指令
  4. 启动 tmux 会话tmux new -s overnight
  5. 防止休眠(macOS):caffeinate -s &
  6. 启动循环
1
2
3
4
5
6
7
8
while true; do
claude -p "$(cat PROMPT.md)" \
--allowedTools "Read" "Edit" "Bash(npm run *)" "Bash(git *)" \
--max-turns 30 \
--max-budget-usd 5.00 \
--permission-mode acceptEdits
sleep 2
done
  1. 分离 tmuxCtrl+B,然后按 D
  2. 去睡觉

早上起来:tmux attach -t overnight,然后查看 git log(git log --oneline)看 Claude 完成了什么。预计保留大约 75% 的产出,丢弃 25%。这很正常——正如一位开发者说的,*”不是完美,甚至不是最终版,但是在前进。”*

十、总结

先用 plan 模式,把 PRD.mdTODO.md 生成好。

  • 安装 cc-safe-setup

    1
    npx cc-safe-setup
  • 安装 format-claude-stream

    1
    npm install -g @khanacademy/format-claude-stream
  • 编写项目的 CLAUDE.md

    1
    2
    3
    - 当上下文变大时,将当前状态写入 tasks/mission.md。包括:已完成的、下一步的、被阻塞的、未解决的问题。
    - 错误处理:最多重试 3 次。如果没有进展,记录到 pending_for_human.md 然后转到下一个任务。
    - 压缩前,务必保存完整的已修改文件列表。
  • 编写 PROMPT.md

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ## 目标
    - 查看 TODO.md,选择一个未完成的任务执行
    - 执行的代码必须包含测试用例并测试通过
    - 每做完一个任务,及时提交 Git,并在 TODO.md 标记为已完成
    - 当所有任务都完成后,在 TODO.md 中顶部注明:“全部任务已完成”

    ## 要求
    - 技术方案不确定 → 选择传统方案
    - 两种可行实现 → 选择更简单的那个
    - 需求模糊 → 应用最合理的理解,记录假设
    - 永远不要提问,做出最佳判断然后继续

    ## 环境(如有)
    # - CLOUDFLARE API 在 key.md 中
  • 编写 key.md

    1
    2
    CLOUDFLARE_API_TOKEN=xxx
    CLOUDFLARE_ACCOUNT_ID=xxx
  • 编写 nostop.sh

    1
    2
    3
    4
    5
    6
    7
    8
    9
    mkdir -p logs
    while true; do
    claude -p "$(cat PROMPT.md)" \
    --dangerously-skip-permissions --model opus \
    --output-format stream-json --verbose \
    tee "logs/$(date +%Y%m%d_%H%M%S).jsonl" \
    | format-claude-stream
    sleep 60
    done

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

一、引言:财务数仓为什么需要AI?

财务数仓的特殊性

在电商数仓体系中,财务域是复杂度最高、容错率最低的领域。不仅因为财务对于数据准确性的要求高,也因为财务是横向域,与几乎所有的域都有数据交叉,因此对业务 Sense 的要求很高。财务数仓工程师本质上在做三件事:

  • 业务翻译: 将交易、支付、资金、促销补贴、成本等数十个业务系统的数据,翻译成通用的财务语言;
  • 资产架构: 从 ODS 到 DWD、DWS、ADS 层层构建,确保财务 UE、财务管报等公司核心指标算得准、算得快;
  • 质量兜底: GMV 口径是否统一,退款是否扣减,分摊是否跨周期对齐,任何一个字段的偏差都可能导致错误的经营决策。

财务域的独特挑战在于:字段间存在严格的数学公式关系(正向-冲销=冲销之后),业务规则涉及跨周期分摊,对于质量的要求极高。如果单纯依靠人工兜底,要么容易出错,要么需要冗余大量人力做复核。尤其是在交付压力大的时候,质量问题就更容易被忽视。

痛点聚焦

从财务数仓的特殊性出发,我们可以总结财务数仓的痛点,大体可以分为如下几类:

基本上,在需求承接的每个环节,都可能因为"人"的问题,带来隐患。

AI 大模型能带来什么改变

为了有效解决"人"的问题,比如催得太急、看不过来、没看仔细、理解错误等问题,我们引入 AI 来做改变。核心思路是:大模型的介入不是替代数仓开发工程师,而是在「需求理解 → 代码编写 → 质量测试 → 文档沉淀」每个环节注入强推理能力。利用 AI 来代替人做大量的重复性工作,同时减少低级错误概率。

那么为什么 AI 能做到这一点?从技术发展的趋势看,有三个核心能力支撑了这一变革:

  • 超大上下文打破知识孤岛: 200k+ token 的上下文窗口,可以将表结构定义、词根字典、指标计算逻辑一次性注入模型的 “工作记忆”,实现基于全域元数据的推演,让大模型具有记忆;
  • 业务语义的自动抽象与对齐: 大模型能理解 “日活”“留存率”“归因窗口” 等业务术语,并映射为具体 SQL 实现,减少因需求理解偏差导致的返工;Claude 在编码领域显著优于其他模型,是因为它能 “懂” 业务逻辑,而不是简单的机械执行;
  • 突破人类极限的规范执行力: 人工在紧迫工期下规范遵守率通常明显下降,而大模型注入规范后,可稳定维持在高位。只要指令给得明确,大模型 “几乎” 不会出错。

参考:亚马逊 AWS 对于构建一个强大、具备自我纠错能力且能查询多种数据源的 Text-to-SQL 解决方案架构图。

二、应用场景概览:从「单点提效」到「全链路增强」

场景与提效预期

基于上述观点,在财务领域,大模型可以在哪些具体的环节落地呢?以下是根据笔者近期实践经验,列出的可落地场景及提效预期。

人机协作模式:数仓研发的「L3 时刻」

如果借用自动驾驶的分级标准,当前数仓大模型应用正处于从 L2(辅助驾驶)向 L3(有条件自动驾驶)过渡的阶段,即在明确的 Prompt 约束与规范文档支撑下,AI 能接管绝大部分标准化的执行动作。

在财务域的实践中,我们也是按照这套自动驾驶分级的方法,将日常工作拆解成了三级:

这种分工背后的逻辑是:规范执行是人类的短板、AI 的长板;业务判断是 AI 的短板、人类的长板。 人工在紧迫工期下对命名规范、分区约束、注释要求的遵守率通常明显下降,且容易因疲劳产生遗漏;而 AI 一旦"学会"了团队规范,输出的规范遵守度可稳定维持在较高水平。反过来,AI 无法替代的是那些需要理解业务上下文、权衡取舍、处理分歧的工作。

AI 对于数仓全链路研发的提效作用

学习 Andrej Karpathy 关于 ChatGPT 分享的内容时,最大的感受是:AI 最强的能力,是 "泛化"。 因此,如果我们可以把数仓研发的链路拆分清楚,那么 AI 必然能够对其中的每一个环节提效,最终带来研发效率的大幅度提升!

三、核心应用场景深度解析

AI OneData 标准化建模(财务核算数据项目)

背景:财务核算 OneData 为什么难搞?

因为:仅第一轮模型设计,就涉及百张以上的表、多个子域、十余个业务过程、数百个指标。如果考虑到后续的二次/三次迭代,工作量势必大到无法想象。在当前以交付为主的阶段,很难花费如此多的时间做基建。以某次核算项目为例,各层表数量分布如下:

同时,财务域的核心特征是来源多(全公司系统)、指标多(单表字段数众多),但以可累加指标为主。财务严格意义上没有原子指标,全是基于业务指标加工出来的派生指标,且一个财务指标往往有多种口径:业务口径、资金口径、财管报口径。并且,项目涉及多个子域(核算域、技术成本域、促销补贴域、商业化域、分析域),覆盖从「计费 → 核算 → 结算 → 财务分析」的端到端业务过程体系。如果要彻底理解核算 OneData 的构建,不仅要懂数仓,还要懂财务,还要熟悉公司财务系统,这个要求非常难做到!主要难点集中在四个方面:

口径溯源极其复杂: 大量逻辑在工程侧实现,绝大多数表缺失业务文档、技术文档、口径文档,口径逻辑需要基于代码猜测,存在错误可能性,溯源工作量巨大。

规范执行不一致: 财务域涉及表命名规范(DIM/DWD/DWS/ADM 各有格式要求)、时间周期规范(1d/7d/30d/wtd/mtd/ytd 等多种)、生命周期规范、刷新周期规范、标准字段英文命名原则({主体}{业务场景}{币种标识}{度量类型}{时间单位})。规范越细,人工遵守率越低。

跨域依赖复杂: 财务是横向域,与各业务域交叉。核算域依赖大量上游表,技术成本域需要从云服务、算法、产研人力、标注人力等多个来源接入数据。

文档输出繁琐: 每个 ADM 表都必须包含 OnePage 文档(OneData 方案最重要内容),加上口径文档、模型使用说明、下游 mapping 文档,文档间大量重复但需各写一遍。

所以,我们更需要通过 AI 的能力,来做一套新时代的建模方法论,以适应 “低投入、大设计” 的智能建模场景。

建模方法论:规范即 Prompt × 迭代收敛法 × 海量文件阅读

第一个方法论:规范沉淀是前提

AI 的输出质量完全取决于输入的规范文档质量。财务核算项目中,我们沉淀了完整的规范体系作为 Prompt 的核心输入,包括:

  • 模型设计规范:表命名、时间周期、生命周期、刷新周期;
  • 标准字段英文命名原则:{主体 /fin}{业务场景 / 费用类型}{币种标识}{度量类型}{时间单位};
  • 财务业务全链路设计理念:计费层 → 核算层 → 结算层 → 财务分析层;
  • 业务过程总线矩阵:多个业务过程与多个维度的交叉关系;
  • 数据质量监控规范:完整性、准确性、一致性、合规性、业务规则等多个大类。

第二个方法论:迭代是常态

不要期望 AI 一次给出完美结果。验证的关键是选择复杂字段进行抽查 —— 在财务场景中,重点验证涉及条件取值的字段(如分摊逻辑、冲销逻辑、多口径指标),对照 SQL 代码验证溯源路径。每次迭代的产物不只是修正后的输出,更重要的是规范文档的完善。因此,针对每次迭代的结果,快速识别要改动的点并修改,这一点就很重要。也就是说,AI 可以显著提升我们的迭代速度!

第三个方法论:海量文件阅读

因为超大的 Context,所以不仅可以把历史上已有的文档一次性灌入进去,也可以把原有设计链路的表和代码交给大模型理解,省去大量阅读和理解的时间。同时,能够帮我们精准地画出业务架构图,辅助数仓工程师理解业务、构建模型。例如财务数仓架构图,很多子模块的逻辑,都是大模型读取代码后输出思路,再由数仓团队整理形成的。

Prompt 和效果

将以上规范作为学习知识输入给模型,再把原始数据表给到模型,模型即可以产出建模建议。

Prompt 示例:

请读取以下规范文档:

  • 数仓规范资产细则(含词根字典、命名规范);
  • 离线数仓开发规范白皮书;
  • 团队 Cursor Rules;

分析目标表(输入对应的表名)的建表语句,按照数仓建模规范(ODS → DWD/DIM → DWS → ADM)的方式,输出重构后的建模建议。

第一次生成的效果展示了初步建模建议,在经过不断的调优和知识输入后,最终版本要丰富很多,形成了完整的财务核算数据 OneData 方案。

收益

经过一段时间的实施,第一版核算数据结构已经落地,效果如下:

  • 效率提升显著: 百张表的口径溯源、文档输出等标准化工作大幅压缩;
  • 规范遵守率大幅提升: 表命名、字段命名、时间周期等规范严格执行,遵守率较人工有明显改善;
  • 可复用性强: 规范文档、工具脚本、Prompt 模板、工作流程 SOP 均可跨子域复用(已在核算域、技术成本域验证);
  • 数据质量监控体系: 基于口径逻辑自动推荐 DQC 规则(完整性、准确性、一致性、合规性、业务规则等多大类)。

AI SQL Coding 实践(财务 UE 表迭代案例)

实践思路

以财务 UE 表某次迭代为代表的案例,主要成果有:

  • 代码结构优化,可读性大幅提升: 指标分段清晰、逻辑分层明确,维护成本明显降低;
  • 代码开发速度提升: 在规范与口径已对齐的前提下,从需求到可上线代码耗时缩短;
  • 性能优化: 整体基线提前完成,为下游留出更多缓冲时间。

那么,我们是如何实现这种成果的?主要靠两点,一是 PRD 快速阅读与理解,二是代码开发效率提升。

如何理解 SQL Coding 核心能力

PRD 阅读与理解方面,AI 能够帮我们实现:

快速将 PRD 中的目标、指标、维度、过滤条件提炼为结构化要点;对「大促期间」、「小仓卖家」、「冲销」等未精确定义的表述,自动生成待确认问题清单;输出「指标口径」「统计周期」「主键与粒度」等需确认条目。

代码开发效率提升方面,AI 能够帮我们实现:

基于词根、分层、命名规范与建表模板,生成符合数仓规范的 DDL 与 SELECT 语句;多维度聚合、归因逻辑、窗口函数、多层嵌套等复杂逻辑,由模型生成初版 SQL,人工校验微调;对存量长 SQL 进行分段、抽取公共逻辑、统一风格与注释。

实践中大模型显著提升点

财务 UE 表迭代需求使用 AI 开发后,具体效果如下:

指标结构分段、编码规范性、注释清晰度:

  • 新表:按数仓分层与命名规范生成 DDL 与 SQL,指标按业务域/统计口径分段组织,注释完整(字段含义、口径说明、KEY 标记等),既符合规范又便于阅读。
  • 旧表改造:在保留业务逻辑正确性的前提下,对历史「屎山」代码进行结构化改写——统一别名、补全注释、拆分过长子查询、显式写出分区过滤等,使后续维护与排查成本明显下降。
  • 代码展示对比:改动前 vs 改动后,可从「可读性、规范遵守度、注释覆盖」等维度做对比分析。

代码撰写速度大幅度提升:

  • AI Coding 的主要步骤:Step 1:整理需求 → 技术文档 将 BI 需求文档中的字段信息整理进技术文档,明确字段范围。
  • Step 2:大模型分析字段来源 提示大模型读取 DWD 源码,分析哪些字段已存在、哪些需要新增关联。
  • Step 3:大模型编写 ETL 代码 由大模型自动在 DWD → DWS → ADM 三层添加字段代码,输出改动代码集合。
  • Step 4:命名规范校准 引入指标字典和 Cursor Rules,让大模型按规范重命名字段(去掉不规范后缀)。
  • Step 5:测试 SQL 生成与跑数验证 大模型生成自测 SQL,逐步验证各层数据一致性,不通过时追问原因并溯源。

性能优化及自动调参:

  • 自动识别性能瓶颈:结合执行计划、大表扫描、数据倾斜等常见问题,由模型分析 SQL 与表结构,指出潜在慢点。
  • 优化建议生成:在分区裁剪、谓词下推、JOIN 顺序、中间结果物化等方面给出具体改写建议。
  • 参数调优方案:针对 Spark/ODPS 等引擎的资源配置、并行度、倾斜处理参数,给出可落地的调优建议,供运维或开发同学选用。

基线优化提升案例:

  • 原链路:多张表串行/并行产出,整体耗时较长。
  • 新链路:经模型辅助做表合并与逻辑下沉,收敛至更少的表,整体耗时明显缩短。
  • 优化效果:在保证口径一致的前提下,表数量与运行时间双降,基线提前完成,资源占用与调度依赖均得到简化。

AI 数据测试(财务 UE 表邮费迭代案例)

财务数据测试的特殊挑战

在数仓开发工作中,数据测试是保障数据质量的关键环节,但也是最复杂、最耗时的环节之一。特别是在财务类指标开发中,数据测试面临着多重挑战:

测试复杂度高,影响面广:

一个指标的改动往往不是孤立的,它会引发连锁反应,影响其他相关计算指标。在复杂的业务场景中,一个字段的修改可能需要同步验证数十个相关字段的正确性。这种复杂的依赖关系使得人工测试很难做到全面覆盖,容易出现遗漏

业务逻辑复杂,公式验证困难:

财务指标通常有明确的数学公式关系:正向 - 冲销 = 冲销之后:需要验证每个字段的正向值、冲销值、冲销之后值之间的计算关系;子项相加 = 汇总项:需要验证各个子项字段相加是否等于汇总字段;

财务的分摊逻辑涉及跨周期问题,难以验证:某些业务场景下,订单时间与收入确认时间不匹配,需要进行跨周期分摊,测试逻辑极其复杂。这些公式关系看似简单,但在实际测试中,需要考虑各种边界情况、精度问题、空值处理等,验证工作量巨大。

测试用例设计困难:

一个需求往往衍生出大量测试点,单纯凭借个人经验和能力,很难做到全面覆盖,容易出现测试盲区,包括:

  • 字段级别的计算逻辑验证;
  • 汇总关系的验证;
  • 冲销逻辑的验证;
  • 边界场景的验证;
  • 精度问题的验证;
  • 业务规则转化的验证。

业务语言到数据语言的转化困难:

业务人员描述的需求往往是自然语言,而数据测试需要将其转化为精确的数据验证逻辑。例如:"退小仓场景下,卖家邮费出资放在第一笔收入冲销,挂在最后一单";"邮费返利抵减技术服务费";"跨周期分摊,商业化订单时间与交易订单时间不匹配"。

AI 在数据测试中的应用实践

那么,我们如何通过 AI,来解决这些复杂问题呢?以某次财务 UE 表邮费迭代项目为例,我们深度应用 AI 进行数据测试,取得了显著效果。

项目背景:

该项目涉及邮费相关字段的全面重构,包括:

  • 迭代字段:修改多个邮费相关字段的计算逻辑;
  • 新增字段:新增大批量邮费细分字段;
  • 删除字段:废弃部分历史字段;
  • 逻辑变更:邮费返利抵减逻辑调整、冲销逻辑优化等。

AI 应用场景:

  1. 测试用例自动生成:向 AI 提出测试要求后,AI 能够自动生成完整的测试 SQL 和说明文档,包括:
  • 正向-冲销=冲销之后的验证逻辑;
  • 子项相加等于汇总项的验证逻辑;
  • 业务规则转化的验证逻辑;
  • 边界场景的验证逻辑。
  1. 规则理解层面的测试补充:AI 能够从规则理解层面补充测试案例,如抽样验证、精度验证等,减少因理解不一致带来的质量问题。特别是在复杂的跨周期分摊场景中,AI 能够识别出人工容易忽略的测试点。

  2. 复杂逻辑的逐步分析:针对复杂的业务逻辑,AI 能够逐步分析不符合预期的环节,帮助找到潜在的代码 Bug。例如在邮费冲销逻辑中,AI 能够分析退小仓场景下的多种分支情况,识别出逻辑漏洞。

  3. 上下游影响分析:AI 能够分析一个字段的改动对上下游的影响,帮助识别需要同步验证的相关字段,避免遗漏。

  4. 公式验证与精度问题诊断:AI 能够自动生成公式验证 SQL,并识别精度问题。在测试过程中,AI 能够区分真正的逻辑错误和可接受的精度误差,避免误报。

实际效果与收益

经过 AI 加持之后,效果和收益明显,包括:

开发效率提升:

测试 SQL 生成效率明显提升:从提出测试要求到生成完整测试 SQL,时间大幅缩短;测试用例覆盖度提升:AI 能够识别出人工容易忽略的测试点,测试覆盖更全面。

交付质量提升:

一次交付通过率显著提升:从规则理解层面补充测试案例,减少理解不一致带来的质量问题;针对复杂逻辑逐步分析,找到潜在代码 Bug;自动生成全面的测试用例,减少测试盲区。

问题发现能力提升:

AI 在测试过程中能够:发现人工难以发现的逻辑错误,识别精度问题并区分可接受的误差,分析复杂的业务规则转化问题,诊断上下游影响关系。

综合收益较高。通过 AI 辅助数据测试,整体交付质量大幅提升,主要体现在:测试覆盖更全面,减少遗漏,问题发现更及时,减少返工,测试效率更高,缩短测试周期,质量保障更可靠,提升交付信心。

AI 需求文档转换(财务 UE 表邮费复杂逻辑解读)

痛点

理解 PRD 和与业务产品反复核对口径,大约占数仓总体工作时间的较大比例。BI 需求文档往往复杂难懂,第一眼看过去看不懂。

实践案例:邮费 UE 迭代技术文档

以邮费 UE 迭代需求为例,BI 需求文档涉及大量字段口径调整、新增字段、废弃字段、冲销逻辑重写等复杂内容。例如通过飞书 MCP 让 Cursor 直接读取 BI 需求文档,大模型自动总结出两张表(DWS 层和 ADS 层)各自需要改什么。大模型输出的结论结构清晰,按表分类列出:

  • 字段含义/口径调整(哪些字段的逻辑需要改);
  • 数据来源与计算点(应收邮费、实收邮费的新口径);
  • 新增字段清单(应收拆分、冲销相关、实收拆分、成本、UE 等);
  • 废弃字段清单(相关历史字段);
  • 冲销逻辑重点(退小仓规则);
  • 两表关系与实现顺序(先改 DWS 再改 ADS)。

Prompt 实例:读取「邮费逻辑梳理」文档内容,分析其文字描述与财务 UE 表的代码,分析要改动的点,帮我生成对应改动代码和改动原因注释。

通过这个分析结果,能够很快地定位要改动的代码,然后一步步理解业务逻辑和具体如何改动。

效果

经过这个过程快速 get 到 PRD 缺失的内容、快速对齐,总体沟通时间有效缩减。虽然在总时间占比上看似不高,但节省的是工程师最头疼的碎片化沟通时间。

四、总结与展望

核心价值

当前市场上,部分头部大厂由于自身产品策略的原因,限制了内部使用最新的大模型和 IDE 工具,导致一线使用大模型的效率受到制约。而我们则能够更灵活地选择最适合的工具组合,在使用技巧和经验积累上具备优势。例如,我们有如下两个方面的优势:

能力层面:

  • 规范化规则遵守:注入规范后生成结果遵守度稳定维持在高位;
  • 业务抽象能力:快速理解 PRD 中的目标、指标与口径,识别模糊点;
  • 实际落地案例丰富:财务 UE 表迭代等项目已有可量化结果。

组织与场景层面:

  • 模型选择灵活,不绑定单一厂商,按任务类型选用最优模型;
  • 组织精简高效,从确定方向到试点上线路径清晰,试错迭代周期短;
  • 离线数仓分层与规范稳定,模型易学易用、效果可预期;
  • 离线任务可重跑、可回溯,模型产出便于充分校验后再上线。

未来展望

使用大模型的能力不仅仅局限在财务、局限在个人,也要向整个团队推广,包括:优先选择 1-2 个痛点明确、规范相对清晰的场景做试点;将有效的 Prompt 设计、上下文组织方式、测试用例模板等经验在团队内分享,形成可复用知识库;从「人做」为主转向「人定规则与口径、模型执行环节」的协作模式,让大模型成为数仓同学的日常助手。未来已来。

往期回顾

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

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

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

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

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

文 /丹克

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

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

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

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

一、背景

在实际迭代开发中,不同需求的代码规模差异很大,有些需求涉及上千行代码,有些则只有一两行。且对于前端的代码验收,主要侧重在界面功能,通过功能验收,没法确保每一行代码都测试到的,以及功能的代码逻辑是否合理,是否健壮、是否规范等问题,都需要通过人工代码 CR 来进一步兜底验收代码的质量,尽量降低业务线上出错的可能。但当面对上千行的代码变更时,人工 CR 也是心有余而力不足。

传统的代码审查依赖人工,面对大规模代码变更时效率有限,而 AI 代码审查能够实现自动化、标准化的质量检查,有效补充人工审查的不足。

二、前端研发 CR 现状与可优化点

CR 现状

目前前端研发同学主要使用的代码质量保障工具有前端 Apex 插件智能体、Uraya 质量分检测。其中 Apex 插件智能体是通过前端研发自助点击或 git hook 自动触发 CR 智能体执行,智能体内定制了 CR 规则以及与 MCP 的结合,利用 Cursor IDE 的 Agent 能力进行本地 AI CR ,找出代码问题、本地解决问题。Uraya 质量分检测是在创建 MR 后,通过流水线自动触发,Uraya 质量分检测代码变更的质量分浮动,产出具体问题的记录,引导研发优化代码。

可优化点

  1. 本地触发 CR 需要研发同学主动点击触发或者通过 Apex git hook 执行 CR 智能体,当开发的需求多、分支多、提交次数多的时候,时长容易漏触发、忘记点。
  2. 对于 MR 评审人员,如果希望通过 Cursor CR 时,需要在本地通过调用 CR 智能体再执行一遍,获取 CR 结果,在目前 Cursor 按量计费的背景下,重复执行 CR 智能体的成本需要及时关注。
  3. 当前流水线 Diff + 大模型 API 的 AI CR 方式,误报率较高,研发使用意愿较低。

三、AI CR 方案对比分析

基于以上现状分析,我们对不同 AI CR 方案进行了深入对比。

Cursor Agent CR 主要优势

流水线集成 CR 与本地 AI CR 差异

四、技术方案设计

结合目前现状与可优化点,我们期望能像 Uraya 质量分检测一样,在 MR 过程中通过流水线自动触发,中途每次代码提交也能自动触发,对于流水线中的 CR 不满意时,可以结合 Apex CR 智能体进行本地 CR 调整代码。

为此我们考虑结合 Cursor Agent CLI 在流水线中增加一个 AI CR 的任务,自动触发 Cursor Agent 代码 CR,并记录 CR 结论,及时展示给研发或者代码评审的同学,辅助代码质量优化。

整体链路设计如下:

  1. 当研发创建 MR 后,流水线配置了 AI CR 检测流水线后,将会自动触发 Cursor Agent CR 任务。
  2. 接收到检测任务后,将会前置将该仓库准备好,并将 MR 的信息以及制定的 CR 规则,一并交给 Cursor Agent CLI 执行,待执行完成,会得到一份 CR 报告。
  3. 接收到检测任务完成后,目前会通过 MR 评论的方式添加到对应的 MR 中,引导用户查看。
  4. 对于开发者视角,打开审查报告,可以根据审查出的问题,进行修改。
  5. 对于 CR 人员视角,打开审查报告,可以根据审查出的问题,一键添加到评论,引导开发者修改。

五、MR 流水线接入与 AI CR 报告

自动触发

以下图 MR 为例,在 MR 流水线中,添加了仓库流水线 AI 检测的检测任务,当创建 MR 时,会自动触发执行一次,在 MR 未合入的过程中,每次代码变更也会自动触发。

添加审查报告评论

检测完成后会自动添加一条 MR 评论,通知研发已完成检测,可以点击查看 CR 报告。评论概览中有审查摘要,显示聚类问题的数量;还有审查总结,即对所有反馈的总结,概览问题。

AI CR 报告

以下为实际 MR 生成的 CR 报告,可以看到,报告主要包括:MR 的基础信息、问题的分类 Tab、问题的具体描述、问题的操作。

具体问题列表

首先报告列表会对问题进行聚类,分为严重问题、警告、建议三类,切换对应 Tab 可以看到问题列表。具体的问题信息,主要有类型、问题代码、修复后代码、描述、文件路径、行号、操作等列。

添加到评论

点击操作列的添加到评论,将会一键将相关问题的信息,生成格式化描述,添加到 MR 的评论中,提醒开发者关注问题、解决问题。

AI 智能解决

点击操作列的 Cursor 解决,将会一键将相关问题的信息,生成解决问题 Prompt,一键打开本地 Cursor ,创建 Agent 对话去解决问题。打开链接后,Cursor 会先接收 Prompt ,你可以简单浏览下,点击 Create Chat ,即可一键创建 Chat,回车执行修复。

Cursor Prompt 预览

Cursor Prompt 预览 确认填入 Chat 执行

复制 Prompt

点击复制 Prompt,支持一键复制修复问题 Prompt,可以放到期望的 IDE 里使用。如下图,就是复制的 Prompt 示例。

六、推荐研发流程实践

尽早创建 MR

当需求分支第一次提交后,就可以创建到 release 或 test 目标分支的 MR 了,后续每次提交代码都将会自动触发检测,产出 AI CR 报告。

研发自主查看与解决

研发收到 AI CR 报告的通知后,可以及时打开 CR 报告查看,确认反馈的疑问点是否需要调整,如果需要调整可以通过 Cursor 一键解决,将问题解决前置到提测以前,这样所有的改动可以尽可能的被测试同学验证到。

人工 CR

发布前最后的人工 CR 可以通过前置的 AI CR 发现与问题前置解决,大幅提升靠最后人工 CR 的反馈、修改等环节效率。特别是当业务需求代码量较大时,人工 CR 浏览的效率和质量也是无法保证的。

七、内置提示词工程

AI CR 其实就像给 AI 一个详细的检查清单。这个清单分两部分:一部分是基本规则,比如"你要扮演什么样的角色"、"按什么流程检查";另一部分是具体的技术要点,比如"注意空指针问题"、"检查React用法是否正确"等。有了这个清单,AI 就能像有经验的程序员一样,系统地检查代码,发现各种潜在问题,让代码质量得到保障。

具体这个规则体系的结构如下:

.cursor/rules
├── 00-role-and-constraints.mdc          # 角色与约束 - 定义AI代码审查助手的角色和基本约束条件
├── 01-workflow-steps.mdc                # 工作流程步骤 - 描述代码审查的工作流程和步骤
├── 02-detection-standards.mdc           # 检测标准 - 定义代码问题的检测标准和准则
├── 03-output-format.mdc                 # 输出格式 - 规定代码审查结果的输出格式和规范
├── 04-best-practices.mdc                # 最佳实践 - 提供代码审查中的最佳实践建议
├── common                               # 通用规则目录 - 包含各种常见的代码问题检测规则
│   ├── 01-null-pointer-defense.md       # 空指针防御 - 防止空指针异常的最佳实践
│   ├── 02-react-hooks-usage.md          # React Hooks 使用 - React Hooks 的正确使用方式
│   ├── 03-data-merge-state.md           # 数据合并状态 - 处理数据合并时的状态管理问题
│   ├── 04-async-programming.md          # 异步编程 - 异步编程模式和常见陷阱
│   ├── 05-memory-leak-performance.md    # 内存泄漏性能 - 检测和防止内存泄漏问题
│   ├── 06-security-coding.md            # 安全编码 - 安全编程实践和漏洞防范
│   ├── 07-compatibility.md              # 兼容性 - 确保代码兼容性的检查点
│   ├── 08-git-conflict-detection.md     # Git 冲突检测 - 检测并解决 Git 合并冲突
│   ├── 09-code-quality.md               # 代码质量 - 代码质量评估和改进规则
│   ├── 10-resource-handling.md          # 资源处理 - 正确处理系统资源的规则
│   ├── 11-url-params.md                 # URL 参数 - URL 参数处理的安全和有效性检查
│   ├── 12-business-logic-consistency.md # 业务逻辑一致性 - 确保业务逻辑一致性的规则
│   └── 13-monorepo-dependency.md        # 大仓依赖 - Monorepo 架构中的依赖管理规则
└── README.md                            # 说明文档 - 规则系统的介绍和使用说明

八、模型选择

在 AI CR 环节,模型的选择需要考虑模型对于代码理解的复杂性、上下文长度需求以及推理准确性、模型的速度、模型的使用成本等考量。在 Cursor 的模型列表中,我们优先使用 Compose 1.5,当额度不足时,我们也会降级使用 Auto 模型。

以下为 Cursor auto 模型与 Composer 1.5 模型对比,可以看出,两个模型都找出了 4 个问题,但在时间上,Composer 1.5 进行需 44 秒即可完成,而 auto 模型需要 91 秒。

九、总结与规划

通过多个迭代实践与数据统计,Cursor Agent CR 挖掘的有效问题数可以达到 50% 左右,研发使用的意愿也相比原来有不少提升。当前我们也在将 AI CR 报告融合到 Cursor IDE 插件中,进一步融合到研发流程里。

随着 AI 生成代码在开发流程中越来越普遍,AI CR 的重要性将进一步凸显。相比传统的人工审查,AI 审查能够自动发现 AI 生成代码中可能存在的逻辑错误、安全性问题和规范性缺陷,提前在开发过程中消除隐患。同时,AI CR 还能确保 AI 生成的代码符合团队的技术规范和最佳实践,保持代码风格的一致性。为 AI 时代的开发流程提供了可靠的质保机制,让开发流程更加顺畅,是现代软件开发的重要保障。

往期回顾

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

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

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

4.得物社区搜推公式融合调参框架-加乘树3.0实战

5.深入剖析Spark UI界面:参数与界面详解|得物技术

文 /大圣

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

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

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

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

一、背景介绍

随着业务规模与流量的持续高速增长,自建 Redis 集群面临着更高地性能与稳定性要求,对平台化、自动化运维能力也提出了新的挑战。为进一步提升资源利用效率、保障服务稳定运行,并更好地支撑业务快速发展,我们对 Redis 平台进行了自动化能力的建设与升级,通过系统化的平台能力优化,降低人工运维费力度,提升整体运维效率与服务质量。

Redis 使用现状

Redis 集群目前基于 ECS 进行部署,采用单机多实例、主从混合部署的架构模式,并将 Proxy 组件与数据节点混合部署,以提升 CPU 资源利用率与整体部署密度。当前集群已达到百 TB 级存储规模、数十万数据节点,支撑超大规模业务场景的稳定运行。

面临的挑战和问题

随着业务规模与流量的持续增长,平台在资源效能与运维效率方面面临着新的优化空间:资源池层面机器资源池的整体利用率仍有提升空间,需进一步优化资源调度与负载均衡策略。运维自动化层面告警自动化处理覆盖度有待提升,部分复杂运维场景仍需人工介入,流程效率可进一步优化。

集群架构

自建 Redis 由 ConfigServer、Redis-Proxy、Redis-Server 等核心组件构成。

自建 Redis 2.0(SDK标准版) 整体架构图如下所示:

一主一从,双区部署

ConfigServer

ConfigServer 是自建 Redis 系统中关键组件之一,跨多可用区多节点部署,采用 raft 协议实现 ConfigServer 组件高可用;ConfigServer 主要负责两方面职责:

  • 负责 Proxy 添加与删除、group 创建与删除、Redis-server 实例添加与删除、Redis-server 实例手动主从切换、水平扩容与数据迁移等功能操作。
  • 负责 Redis-server 实例故障检测与自动故障转移(主节点故障后自动主从切换)。

Redis-Proxy

Redis-Proxy 组件是自建 Redis 系统中的代理服务,负责接受客户端连接,然后转发客户端命令到后端相应的 Redis-server 实例,使得后端 Redis-server 集群部署架构对业务透明,Proxy 支持 Redis RESP 协议,业务访问 Proxy 就像访问一个单点 Redis 服务一样,业务可以把一个自建 Redis 集群当作一个容量无限大的单点 Redis 实例即可。

Redis-Server(Redis-Group)

Redis-server 组件为开源 Redis 版本基础上,增加槽 slot 同步迁移与异步迁移等相关功能;支持原生开源 Redis 的所有特性,比如支持 String、Hash、List、Set、ZSet 等常用数据结构,AOF 持久化、主从复制、Lua脚本等等。默认一主一从,可支持多从部署。

二、自动化运维能力

自动化运维

资源池自动化均衡调度

当前 Redis 资源池支持按内存使用率自动化均衡调度、按内存分配率自动化均衡调度、按 CPU 使用率均衡调度、支持指定机器凌晨迁移调度(隐患机器提前维护、凌晨资源池迁移优化下线等)等功能,核心流程为合理选择迁移节点。现在每天定时生成迁移计划,迁移任务默认每天凌晨定时执行。

资源池均衡任务管理

迁移 server 节点选择算法流程图

Redis 潮汐调度算法示意

选择 Server 节点原则

  1. 机器选择:
  2. 获取内存容量使用率超过指定百分比的机器。
  3. 获取分配率超过指定百分比的机器。
  4. 获取需要维护和迁移优化的机器。
  5. 优先节点数量多的实例节点:这样可以在资源均衡的同时,使得同一集群节点也更均衡,同一集群节点尽可能分散到不同的机器上。
  6. 优先实例等级为非 P0 的实例。
  7. 优先从节点:从节点迁移对大部分业务都没有任何影响。
  8. 分配率和内存容量一样,优先节点规格中等规格(1-4G)实例,再选择 1G-5G 规格实例,最后选择其他规格的节点。
  9. 最后汇总迁移任务节点:
  10. 优先处理需要维护和需要迁移优化的节点。
  11. 去掉同一个集群同一个分组的 master 节点,避免对同一 group 分组进行操作。
  12. 对于需要维护和迁移优化的机器上的 proxy:
  13. 获取原来 proxy 版本,资源标签等信息,判断是否是特殊作用 proxy,部署新 proxy。
  14. 调整旧 proxy:对于 sdk proxy 禁用 proxy,对于 slb 下 proxy,调整权重。

选择 server 迁移任务流程图

  • 节点选择后生成迁移任务,前端可展示、确认、取消;
  • 定时任务执行生成的迁移任务;
  • 添加从节点、同步数据;
  • 同步数据完成后如果迁移节点是从则删除节点;
  • 同步数据完成后如果迁移节点是主则进行主从切换;
  • 如果迁移节点是主进行主从切换后检查新主从关系,检查 proxy 拓扑更新等,如果有异常则告警迁移。

迁移 proxy 节点选择算法流程图

proxy 节点选择流程图

选择 Proxy 节点原则

  1. 优先机器 CPU 负载峰值高的机器上 Proxy 节点;均衡调度阈值支持可配置,后续均衡后继续调整。
  2. 需要先采集到 proxy 24 小时 CPU 峰值,排序后优先迁移机器上 CPU 峰值最高的,直到机器 CPU 峰值降到均衡调度阈值。
  3. 每台机器每天只迁移 1 个 proxy。
  4. 判断 proxy CPU 峰值高的个数(如果只有一个就不处理,如果大于等于 3 个 proxy CPU 峰值高则处理一个(超过配置的均衡调度阈值算高 CPU 使用率))。

Proxy 迁移任务流程图:

  • 节点选择后生成迁移任务,前端可展示、确认、取消;
  • 定时任务执行生成的迁移任务;
  • 获取原来 proxy 版本,资源标签等信息,判断是否是特殊作用 proxy,部署新 proxy;
  • 新 proxy 绑定 LB;
  • 调整旧 proxy:对于 sdk proxy 禁用 proxy,对于 slb 下 proxy,调整权重。

收益

  • 提升资源池内存与 CPU 利用率,优化整体资源使用效率。
  • 合理管控资源超卖率,降低自动扩容失败率与告警发生率。
  • 基于机器维护窗口,在凌晨低峰期执行调度与实例迁移,高效支撑隐患机器前置治理、资源池离线优化及节点下线等运维需求。

资源池分级维护和管理

对 ECS 机器资源和 LB 资源进行打标,根据特殊业务需要做不同资源池的隔离调度。

可对资源进行多维度筛选:比如按资源标签、CPU、可用区、是否重保等维度筛选。

可对机器上部署的节点信息进行迁移操作和查看机器详细监控等。

物理资源隔离:自建 Redis 通过对 ECS 机器资源打标,实现重保集群隔离,支持集群物理隔离,减少集群相互影响,支持资源分级维护和灰度测试验证,减少大面积变更影响,使用相对保守的资源水位阈值来减少重保集群的运维频次和任务调度。

Redis 资源池隔离方案示意

不同资源池资源阈值项设置:

资源池分配阈值

集群生命周期自动化管理

集群自动化部署

当前 Redis 支持自动化集群部署,集群交付时间缩短至分钟级。

当业务提交集群申请工单审批通过后,判断是否支持自建,如符合自建则自动化进行集群部署和部署结果校验,校验集群可用性后自动给业务交付集群信息,整个过程高效快速。集群部署成功或者失败都会发送消息通知。

部署结果成功通知

部署结果失败通知

集群垂直扩缩容自动化

当前 Redis 支持 server 垂直扩缩容,ecs-proxy、docker-proxy 扩容等工单自动化操作。

扩容方案

集群 server 垂直扩缩容,ecs-proxy、docker-proxy 扩容等场景在业务提单时给出扩缩容方案和校验,实现工单自动化操作。

集群水平扩缩容自动化

当前 Redis 支持 server 自动扩容分片,以支持更高的请求和负载。

Server 水平扩缩容任务管理

水平扩缩容执行任务详情

集群下线支持回收和重建

当前 Redis下线回收,支持立即销毁和重建恢复。

集群自动下线流程

  • 工单审批通过后立即下线接入层:检测 proxy(ecs-proxy 和 docker-proxy)连接和 qps 请求,都没有则调整权重,下线接入层(ecs-proxy 和 docker-proxy)。
  • 7 天内如有反馈问题,需要继续访问,则重建恢复集群正常访问。
  • 7 天后无反馈下线集群所有资源(包括数据层数据,这里下线后不再支持回收重建)。

集群回收站管理

大 key 删除支持产品化可回滚

支持自建 Redis 和云 Redis 多 db 大 key 删除可回滚。支持控制台大 key 删除任务管理(立即执行删除、定时删除、回滚等)。

进行中的任务

历史删除任务

版本升级自动化

  • 对有需要的集群支持将指定集群在指定时间进行滚动升级到指定版本。
  • 自动化版本升级收敛,通过自动化任务在凌晨低峰期进行同版型系列滚动升级。
  • 支持升级任务管理、修改时间、查看任务详情、升级进度,取消任务等。

版本升级任务

版本升级记录

工单自动化

当前所有运维工单都已完成工单自动化,如 Biz 申请、创建实例、密码申请、权限申请、实例升降配、实例架构升级、Server 版本升级、Server 水平扩容、删除 key、下线实例等均完成工单自动化。业务提单审批通过后自动校验执行,执行完成后自动发送工单执行结果通知。

总结:除了需求描述性(云 Redis 需求)的工单,其他均实现操作工单化标准化,工单自动化。

查询自动化

集群控制台支持命令查询、Key 模糊查询、Key 随机采样等,查询结果也支持 json 格式化、复制等功能。

支持查询历史缓存,查询耗时记录等。

告警自动化处理

告警入库收敛优化

  • 告警触发后收敛至集群维度入库;
  • 判断告警是否沉默中:如内存容量告警,部分特殊集群可以写满按淘汰策略淘汰,不用扩容,这种告警需要沉默;
  • 判断告警是否超频:因为集群分片很多,同一集群同一指标不同分片每次触发阈值都会触发告警;
  • 将告警信息按集群所属发送到对应的业务域:同一集群可能存在多个业务方使用,根据业务域纬度增加业务域大群告警通知,提高告警业务感知能力。

Server 分片内存容量告警自动扩容

自建 Redis 支持业务配置自动扩容,当集群容量超过预警水位线 80% 时,可自动进行垂直扩容,不需要人工介入运维,对业务无感,自动扩容在夜间无人值守的场景下,大大降低了集群容量激增带来的风险。

Redis 自动扩容开关

Server 自动扩容流程图:

Redis 自动扩容流程图

  • 管控周期性任务获取监控平台 Redis 内存使用率超过 80% 的监控信息。
  • 节点告警信息收敛到集群维度处理。
  • 判断集群是否开启自动扩容:集群申请时会让业务填是否开启自动扩容,页面也可配置开启或者关闭自动扩容。
  • 判断节点是否超过集群设置的 80% 扩容阈值。
  • 判断最近一天是否扩容次数大于 3 次:如果 24 小时内扩容多次,说明可能增长异常,需要让告警发出。
  • 判断扩容后容量是否大于设置的最大阈值(8G):这里单个节点最大值为 8G,方便维护。
  • 预检查扩容后分配是否大于机器内存:自动扩容后分配容量不能大于机器容量。如果大于机器容量则记录扩容失败信息,如果小于则可执行扩容操作,扩容操作后再持久化参数到 Redis 配置文件,然后记录节点扩容成功。

宕机场景告警收敛与自动化处理

机器维度的告警收敛,减少告警。

  • 订阅机器宕机事件入库;
  • Redis server 和 proxy Down 告警信息入库;
  • Redis server 和 proxy Down 告警触发后判断所属机器是否有宕机事件;
  • 如果告警所属机器没有机器宕机事件,则直接发送电话告警和飞书告警消息通知;
  • 如果告警所属机器有机器宕机事件,则判断告警时间是否超过 5 分钟,如果 5 分钟后告警还没恢复则当前节点自动拉起失败,发送电话告警和飞书告警消息通知。如果节点自动拉起成功,则不会再触发告警。

宕机节点自动重启流程图:

针对夜间 Redis 实例机器宕机,引入自动化巡检和自动重启机制,减少夜间运维成本,提高夜间故障集群主备完整性恢复效率。

Redis 宕机自动恢复示意图

  • 订阅机器宕机事件入库;
  • 周期性任务查询宕机信息;
  • 机器宕机加入事件队列,判断是否事件重复,重复则不加;
  • 重启宕机上的节点,如果返回失败加入事件队列,支持重试 3 次;
  • 发送重启结果消息通知。

收益

  • 将告警信息按集群所属发送到对应的业务域,降低了告警后不断找人拉群的运维工作量。告警自动实时同步给业务,提高了业务告警实时性和告警感知能力。
  • 通过告警入库收敛优化、宕机场景告警收敛优化和告警自动化处理,降低告警噪音 90% 以上。
  • 通过 Server 分片内存容量告警自动扩容、机器宕机节点自动重启,极大降低运维成本和提高告警恢复效率。

自动化巡检推送

黑名单管理

对集群大 key、集群热 key、集群混用情况、集群成本等进行巡检,针对特殊场景的 key 支持集群维度、key 维度和 key 前缀维度的黑名单配置。

黑名单管理

大 key 巡检日报

每日按业务域维度巡检集群存量大key,推送巡检信息到对应业务域大群,大 key 巡检支持黑名单管理。点击实例 ID 可跳转查看 key 分析详情。

大 key 巡检日报

key 分析详情

热 key 巡检

实时将集群热 key 信息,推送巡检信息到对应业务域大群,热 key 支持黑名单设置。

集群热 key 实时巡检

实时热 key 分析

三、总结

通过持续构建与完善平台自动化运维体系,我们实现了 Redis 集群全生命周期运维的规范化、标准化与自动化,覆盖集群部署、垂直扩缩容、分片水平扩容、版本升级、集群生命周期管理、资源池多维度智能调度、自动化告警处理及常态化巡检等核心场景。整体运维流程实现少人化、无人化执行,大幅降低运维复杂度和人工运维费力度。依托运维工单化、流程自动化的建设思路,平台整体运维效率得到显著提升,为 Redis 服务长期高稳定、高可靠、高性能运行提供了坚实保障。

往期回顾

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

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

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

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

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

文 /陌叶

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

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

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

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

一、破局: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工作流|得物技术

一、背景

事情是这样的,之前对 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 项目实战|得物技术

一、前言

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.社区推荐重排技术:双阶段框架的实践与演进|得物技术

文 /阳凯

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

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

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

02-Debug调试@网络-Wireshark网络抓包工具:从原理到实践

Wireshark 网络抓包工具:从原理到实践

📋 目录


一、概述与历史演进

1.1 工具简介

Wireshark 是一款开源的网络协议分析器(Network Protocol Analyzer),支持实时抓包(Live Capture)离线分析(Offline Analysis),可对数百种协议进行深度解析(Deep Inspection),运行于 Windows、Linux、macOS 等平台,被业界与教育机构广泛用于网络排障、安全分析、协议学习与性能调优 [1][2]。

与 Charles、Fiddler 等应用层代理不同,Wireshark 工作在网卡/驱动层,可捕获本机及经本机转发的原始报文(含二层以太网帧、IP、TCP/UDP 及各类应用层协议),不依赖应用配置代理,适用于全栈协议分析与非 HTTP(S) 流量 [3]。

1.2 历史与版本脉络

时期 事件
1997 年底 Gerald Combs 为解决工作中的网络问题并学习网络知识,开始编写 Ethereal(Wireshark 前身)[1][4]
1998 年 7 月 Ethereal 0.2.0 首次发布;Gilbert Ramirez、Guy Harris、Richard Sharpe 等贡献底层解析器与协议支持 [4]
2006 年 项目迁移基础设施并更名为 Wireshark [1][4]
2008 年 Wireshark 1.0 发布,标志着「最低可用功能」完成;首届 SharkFest 开发者与用户大会举办 [4]
2015 年 Wireshark 2.0 发布,采用全新 UI [4]
2023 年 项目由 Wireshark Foundation(美国 501(c)(3) 非营利组织)接管,负责基础设施、SharkFest 与网络教育推广 [4]

社区贡献模式以「所需协议驱动」为主:开发者复制现有解析器、实现新协议后回馈上游,使 Wireshark 支持的协议数量持续增长(如 4.x 版本已支持数千种协议、数十万字段)[1][2][5]。

1.3 典型应用场景

  • 网络排障:定位连接超时、丢包、重传、RST、DNS 解析失败等,结合协议栈与时间轴分析根因。
  • 协议学习与逆向:查看真实报文结构、字段含义、状态机行为(如 TCP 握手/挥手、TLS 握手)。
  • 安全与取证:检测异常流量、分析攻击载荷、配合 TLS 密钥日志解密 HTTPS 以审计内容(需合规授权)。
  • 性能分析:统计往返时延、重传率、吞吐量,配合 IO 图形化与专家信息系统(Expert Info)。
  • 嵌入式与物联网:抓取串口/蓝牙/BLE 等经适配器转换后的报文,或配合远程抓包(SSH、rpcapd)分析设备侧流量。

二、核心原理与架构

2.1 抓包在 OS 中的位置

抓包需要网卡驱动或内核模块将流经网卡的报文复制一份交给用户态。在 Unix/Linux/macOS 上,Wireshark 使用 libpcap:应用通过 libpcap 打开设备或文件,由 libpcap 与内核交互(如 Linux 的 PF_PACKET、BPF 过滤器),把满足条件的报文拷贝到用户空间 [6][7]。在 Windows 上,早期依赖 WinPcap(基于 libpcap 1.0.0,支持至 Windows 8,已停止维护);现代 Wireshark(3.0+)默认使用 Npcap:由 Nmap 项目维护,采用 NDIS 6 Light-Weight Filter 驱动,支持环回(loopback)抓包、原始 802.11、x86/x64/ARM,并随 Wireshark 安装包分发;相比 WinPcap 性能与安全性更优 [6][8]。

flowchart TB
    subgraph 用户态
        W[Wireshark / tshark]
        L[libpcap / Npcap]
    end
    subgraph 内核
        K[内核网络栈 / NDIS]
        D[抓包驱动]
    end
    subgraph 硬件
        N[网卡]
    end
    N --> K
    K --> D
    D --> L
    L --> W

2.2 抓包过滤器与显示过滤器的分工

  • 抓包过滤器(Capture Filter):在抓包前由驱动/内核或 libpcap 应用,只将符合条件的报文写入捕获文件或交给 Wireshark,未匹配的报文直接丢弃。语法为 Berkeley Packet Filter (BPF),与 tcpdump、WinDump 等一致;抓包过程中不可更改 [5][9]。
  • 显示过滤器(Display Filter):在已抓取的报文上做二次过滤,仅影响界面展示与统计,不改变捕获文件内容;可随时修改,基于 Wireshark 自有的字段与协议树 [5][10]。

因此:抓包过滤器用于减负与聚焦(如只抓某主机或某端口),在抓包前设置且抓包过程中不可修改,可减少落盘与内存占用;显示过滤器用于分析时的精筛(如只看 HTTP 请求、某状态码、某字段值),不改变捕获文件内容,仅隐藏包列表中的报文,可随时修改。二者语法不同:例如「某主机 Telnet」抓包过滤写 tcp port 23 and host 10.0.0.5,显示过滤写 tcp.port == 23 and ip.addr == 10.0.0.5 [9][17][18]。

2.3 协议解析(Dissection)与协议树

每个报文进入 Wireshark 后,由解析器(Dissector)按协议栈逐层解析:先由 Frame 解析器处理捕获元数据(时间戳、长度等),再依次调用数据链路层(如 Ethernet)、网络层(IP/ARP)、传输层(TCP/UDP)、应用层(HTTP、TLS、DNS 等)解析器,形成协议树。解析器可内置或通过插件加载;支持协议与字段的完整列表可通过「View → Internals → Supported Protocols」查看,显示过滤器可基于任意已注册字段 [5][11]。


三、抓包过滤器(Capture Filter)与 BPF

3.1 BPF 语法概述(官方语法 [9][12])

抓包过滤器采用 libpcap 过滤器语言(即 BPF),与 tcpdump、WinDump 等使用同一语法。形式为若干原语(primitive) 通过 and / or 连接,并可加 not

[not] primitive [and|or [not] primitive ...]

原语限定符(qualifier) + ID 组成。根据 pcap-filter man pageWireshark User's Guide §4.10,常见原语包括:

原语 含义 示例
[src|dst] host 按主机 IP 或主机名过滤 host 10.0.0.5src host 192.168.1.1;不写 src/dst 时表示源或目的任一匹配即可
ether [src|dst] host 按以太网(MAC)地址过滤 ether host aa:bb:cc:dd:ee:ff
gateway host 以 host 为网关的报文(以太网源/目的为 host,但 IP 源/目的不是 host) gateway 192.168.1.1
[src|dst] net [mask|len] 按网络号过滤,可写掩码或 CIDR 长度 net 192.168.0.0/24net 192.168.0.0 mask 255.255.255.0
[tcp|udp] [src|dst] port 按 TCP/UDP 端口过滤;tcp/udp 须在 src/dst 前 tcp port 80udp dst port 53
portrange 端口范围(libpcap 0.9.1+) tcp portrange 1501-1549
less | greater length 按报文长度 ≤ 或 ≥ 某值 greater 128less 64
ip | ether proto 按 IP 或以太网层协议类型过滤 ip proto 6(TCP)、ether proto 0x888e(EAPOL)
ether | ip broadcast | multicast 广播或组播 not broadcast and not multicast
relop 按字节或字节范围选择(复杂表达式) 见 pcap-filter man page

注意:抓包过滤器不是显示过滤器;前者在抓包前应用、语法更受限,后者在已抓包上过滤、可随时修改 [17]。

3.2 常用抓包过滤器示例(官方与 Wiki [9][12][17])

host 172.18.5.4                    # 与某 IP 双向流量
src host 192.168.1.1 / dst host 192.168.1.1   # 仅源或仅目的
net 192.168.0.0/24                 # 某网段;或 net 192.168.0.0 mask 255.255.255.0
src net 192.168.0.0/24             # 源网段
tcp port 23 and host 10.0.0.5      # 发往/来自 10.0.0.5 的 Telnet
tcp port 23 and not src host 10.0.0.5  # Telnet 且源非 10.0.0.5
port 53                            # DNS(TCP+UDP)
port not 53 and not arp             # 排除 DNS 与 ARP
tcp portrange 1501-1549             # TCP 端口区间
ether host aa:bb:cc:dd:ee:ff        # 以太网地址
ether proto 0x888e                  # 仅 EAPOL
ip                                # 仅 IPv4,可排除 ARP/STP 等
not broadcast and not multicast     # 仅单播
host www.example.com and not (port 80 or port 25)  # 排除 HTTP/SMTP
dst host ff02::1                   # IPv6 全节点组播(如 RA)

完整语法见 pcap-filter man pageWireshark Wiki CaptureFilters [9][12][17]。

3.3 抓包前设置与 Capture Options 界面(官方 [9])

  • 入口:菜单 Capture → Options…(或主工具栏对应项),打开 「Capture Options」 对话框 [19]。
  • 抓包过滤器输入位置:在 Input 标签页中,Interface 表格里每块网卡有一列 Capture Filter;可双击该列编辑该接口的 BPF;也可在表格上方「Capture filter for selected interfaces」为多块接口统一设置。设置完成后点击 Start 开始抓包。
  • Input 标签页:除 Capture Filter 外,还可配置每块接口的 Promiscuous(混杂模式)、Snaplen(每包捕获字节数)、Buffer(内核缓冲区大小)、Link-layer header type(链路层类型)、Monitor mode(无线 802.11 原始头,可能断网)等;悬停或展开接口可看到其 IPv4/IPv6 地址。
  • Output 标签页:可设置 Capture to a permanent file(保存路径、pcapng 默认格式)、Create a new file automatically(按时间/时长/大小/包数切换文件)、Ring buffer(多文件循环)。
  • Options 标签页Update list of packets in real-time(实时更新包列表)、Automatically scroll during live capture(自动滚动)、Name Resolution(解析 MAC/网络/传输层名称)、Stop capture automatically after…(按时长/大小/包数自动停止)。
  • Compile Selected BPFs:可查看当前 BPF 编译后的字节码,便于理解与排错。
  • 自动排除远程会话流量:当 Wireshark 在远程环境运行(如 SSH、X11、终端服务器)时,会检测环境变量并自动生成一条抓包过滤器以排除远程连接流量,减少无关包。检测变量包括:SSH_CONNECTIONSSH_CLIENTREMOTEHOSTDISPLAY(X11)、SESSIONNAME(终端服务器);Windows 下会检测是否在 Remote Desktop Services 环境 [9][17]。

Linux 提示:开启 BPF JIT 可加速过滤:echo 1 >/proc/sys/net/core/bpf_jit_enable(需 root);持久化可借助 sysfsutils [9]。


四、显示过滤器(Display Filter)

显示过滤器用于在已抓取的报文上精确控制显示哪些包;与抓包过滤器不同,可随时修改且基于协议树字段。完整语法见 User's Guide §6.4;协议与字段列表见 View → Internals → Supported ProtocolsDisplay Filter Reference [10][18][20]。

4.1 按协议/字段过滤与比较运算符(官方 [10])

  • 最简单:在显示过滤器栏输入协议名(如 tcp)或字段名(如 http.request),只显示包含该协议或该字段的报文。
  • 比较运算符User's Guide Table 6.6):
英文/别名 C 风格 含义 示例
eq / any_eq == 相等(多值字段时任一匹配即成立) ip.src == 10.0.0.5
ne / all_ne != 不相等(多值字段时全部不匹配才成立;Wireshark 3.6+ 语义) ip.src != 10.0.0.5
all_eq === 相等(多值字段时全部匹配才成立) ip.src === 10.0.0.5
any_ne !== 不相等(多值字段时任一不匹配即成立) ip.src !== 10.0.0.5
gt / lt / ge / le > < >= <= 大于/小于/大于等于/小于等于 frame.len > 100frame.len le 0x100
contains 协议、字段或切片包含某值 sip.To contains "a1762"udp contains 81:60:03
matches ~ 协议或文本字段匹配 Perl 兼容正则 http.host matches "acme\\.(org|com|net)"

注意ip.addrtcp.port 等为多值字段(同时含源与目的);== 表示「任一匹配」,要排除某地址应写 !(ip.addr == 10.43.54.65) 而非 ip.addr != 10.43.54.65(后者语义为「至少一个不等于」,易误用)[18]。

示例:

ip.addr == 192.168.0.1
ip.src == 10.0.0.5 and tcp.flags.fin
frame.len > 100
http.request.uri contains "api"
http.host matches "acme\.(org|com|net)"
tcp.flags.syn == 1
tcp.flags & 0x02

4.2 字段类型(官方 [10])

类型 说明与示例
无符号/有符号整数 可 8/16/24/32/64 位;可写十进制、八进制(0)、十六进制(0x)、二进制(0b)。例:ip.len le 1500ip.len le 0x5dc
布尔 1 或 True、0 或 False。字段存在即参与过滤;要匹配 SYN 置位须写 tcp.flags.syn == 1
以太网地址 6 字节,分隔符可为 :.-。例:eth.dst == ff:ff:ff:ff:ff:ff
IPv4 ip.addr == 192.168.0.1;支持 CIDR:ip.addr == 129.111.0.0/16
IPv6 ipv6.addr == ::1,也可匹配子网
字符串 双引号;可用 \xhh\ddd 转义。例:http.request.uri == "https://www.wireshark.org/";原始字符串前缀 rR 使反斜杠按字面处理
日期时间 字符串格式,如 frame.time == "Sep 26, 2004 23:18:04.954975"frame.time < "2022-01-01";小数秒可选,无时区后缀

4.3 逻辑、集合与算术

  • 逻辑Table 6.7):and(&&)、or(||)、not(!)、xor(^^);子序列用 []
  • 集合(Membership)field in { 值1, 值2 } 或范围 field in {443, 4430..4434};等价于多个 == 的 or,但集合对单字段求值,避免多值字段歧义。例:tcp.port in {80, 443, 8080}http.request.method in {"HEAD", "GET"}ip.addr in {10.0.0.5..10.0.0.9, 192.168.1.1..192.168.1.9}
  • 算术+-(减号前需空格)、*/%&(按位与)。例:frame.cap_len < { 14 + ip.hdr_len + tcp.hdr_len } 可找被截断的 TCP 选项。

4.4 切片、层操作符与 @ 操作符(官方 [10])

  • 切片(Slice):在字段或协议名后加 [范围]。范围格式:n:m(从偏移 n 起长度 m)、n-m(从 n 到 m inclusive)、:m(从头到 m)、n:(从 n 到结尾)、单字节 [n];负偏移表示从末尾算起。例:eth.src[0:3] == 00:00:83frame[-4:](最后 4 字节)、frame[-4:4] == 0.1.2.3。字符串切片按 UTF-8 码点边界。
  • 层操作符 #:限定到协议栈某一层。例:ip.addr#2 == 192.168.30.40 只匹配第二层 IP(如隧道内层);tcp.port#[2-4] 表示第 2、3、4 层。
  • @ 操作符:用 @ 前缀表示按原始字节比较,不经过解码。例:@browser.comment == 73:74:72:69:6e:67:... 用于有解码错误时的精确匹配。

4.5 函数(官方 [10])

函数 说明 示例
upper / lower 字符串大小写转换 lower(http.server) contains "apache"
len 字符串或字节长度(字节数) len(http.request.uri) > 100
count 帧中某字段出现次数 count(ip.addr) > 2
string 将字段转为字符串(可与 matches 等配合) string(frame.number) matches "[13579]$"
vals 将字段转为「值字符串」(若有定义) 用于与枚举名比较
dec / hex 整数转十进制/十六进制字符串
float / double 转为浮点;double 可处理时间(自 epoch 秒)
max / min 参数中的最大/最小值 max(tcp.srcport, tcp.dstport) <= 1024
abs 绝对值

4.6 字段引用(Field References)

${proto.field} 表示当前选中报文中该字段的值,用于动态过滤。例:自当前包起前 5 分钟:frame.time_relative >= ${frame.time_relative} - 300;或 HTTP 且目的 IP 等于当前帧 DNS A 记录:http && ip.dst eq ${dns.a} [10]。

4.7 正则与多值字段注意点

  • matches 的字符串会先经 Wireshark 解析再交给 PCRE,转义可能需双重(如括号 \\();用原始字符串 r"..." 可减少问题 [10]。
  • 协议名歧义:如 fc 可能被解析为协议 Fibre Channel 或十六进制 0xFC;用 .fc 强制协议名、:fc 强制字节序列 [10]。
  • 协议更名:如 bootp → dhcp,旧名可能仍可用但会提示 deprecated;新写过滤器建议用新名 [10]。

五、关键概念图示与流程

5.1 从网卡到界面的数据流

flowchart LR
    subgraph 捕获
        A[网卡] --> B[驱动/Npcap]
        B --> C[BPF 抓包过滤]
        C --> D[捕获缓冲区/文件]
    end
    subgraph 解析与展示
        D --> E[Frame 解析器]
        E --> F[各层 Dissector]
        F --> G[协议树]
        G --> H[显示过滤器]
        H --> I[包列表/详情/字节]
    end

5.2 抓包过滤器 vs 显示过滤器

flowchart TD
    subgraph 抓包阶段
        P1[所有经过网卡的报文] --> CF{抓包过滤器 BPF}
        CF -->|匹配| P2[写入捕获]
        CF -->|不匹配| P3[丢弃]
    end
    subgraph 分析阶段
        P2 --> DF{显示过滤器}
        DF -->|匹配| Q1[列表中显示]
        DF -->|不匹配| Q2[隐藏,仍存在于文件]
    end

5.3 协议解析栈(概念)

flowchart TB
    F[Frame] --> E[Ethernet]
    E --> I[IP / ARP]
    I --> T[TCP / UDP / ICMP]
    T --> A[HTTP / TLS / DNS / ...]
    A --> B[应用数据]

六、应用场景与实战

6.1 HTTP/HTTPS 调试

  • HTTP:显示过滤 httphttp.requesthttp.response.code == 404;右键报文 → Follow → HTTP Stream 可查看完整请求/响应体 [13]。
  • HTTPS:默认仅能看到 TLS 握手与加密载荷。若需查看明文,需提供会话密钥:在浏览器或 curl 侧设置 SSLKEYLOGFILE 环境变量导出密钥日志,在 Wireshark 中 Edit → Preferences → Protocols → TLS → (Pre)-Master-Secret log filename 指向该文件,重新抓包或重放后即可解密(依赖 TLS 1.2 等支持密钥导出;PFS 场景下必须用密钥日志,仅私钥不足)[14][15]。

6.2 TLS 握手与证书问题

  • 过滤:tlsip.addr == 1.2.3.4 and tls,查看 Client Hello / Server Hello / Certificate / Alert 等。
  • 典型问题:版本或套件不匹配、证书链不完整、主机名不匹配、Alert 告警等,可在 Expert Info 与 TLS 解析树中定位 [14][16]。

6.3 连接与性能问题

  • TCP:过滤 tcp,关注 SYN/ACK/RST/FIN、重传、窗口;统计 → 往返时延、流图,辅助判断延迟与丢包。
  • DNS:过滤 dns,查看请求与响应、响应码与解析结果,排查解析失败或污染。

6.4 TLS 解密配置步骤(摘要)

  1. 导出密钥日志:在客户端(浏览器/curl)设置环境变量 SSLKEYLOGFILE 指向一可写文件;完成 TLS 会话后,该文件会包含 NSS 格式的会话密钥。
  2. Wireshark 配置:Edit → Preferences → Protocols → TLS → 在「(Pre)-Master-Secret log filename」中指定上述文件路径。
  3. 抓包或重放:重新建立 TLS 连接并抓包,或对已有 pcap 重新打开;若密钥匹配,应用层载荷会以明文显示在 TLS 解析树下。
  4. 限制:仅持有服务器私钥无法解密使用 ECDHE/DHE 的会话(PFS);必须依赖客户端导出的密钥日志 [14][15][16]。

6.5 企业与实践参考

  • Cisco 等厂商文档中常推荐使用 Wireshark 进行 TLS 与通用网络故障排查,并说明如何配合密钥日志解密 HTTPS [16]。
  • 实践中常采用「先抓包过滤缩小范围 + 再显示过滤精查 + Follow Stream / 统计 / 专家信息」的组合流程;大流量环境优先用 BPF 减少落盘与内存占用。

6.6 典型通讯场景抓包与数据包分析 SOP

以下针对 Socket TCP、Socket UDP、音视频直播、WebRTC P2P 等典型通讯场景,给出从抓包配置 → 显示过滤 → 关键字段解读 → 调试与排错的完整 SOP,便于按场景落地使用。


6.6.1 Socket TCP 抓包与分析 SOP

场景说明:基于 TCP 的 Socket 通讯(自定义协议、长连接、游戏/IM 等),需观察连接建立、数据传输、重传、挥手与 RST 等。

阶段 操作 说明
1. 抓包前配置 若已知对端 IP 或端口,在 Capture Options → Capture Filter 中设置 BPF,减少无关流量 例:host 192.168.1.100tcp port 9000tcp portrange 8000-8010;未知时可先不设过滤,抓包后用显示过滤器精查
2. 选择接口 选择实际收发流量的网卡(有线/无线/环回) 本机压测选 loopback;真机/远程选对应物理或虚拟接口
3. 开始抓包 启动抓包后,在客户端/服务端触发 TCP 连接与数据收发 建议在问题复现前开始抓,复现后尽快停止,便于定位时间窗口
4. 显示过滤 在显示过滤器栏输入表达式,精确定位目标流 常用:tcp.port == 9000ip.addr == 192.168.1.100tcp.stream eq 0(按流索引);组合示例:tcp and ip.addr == 192.168.1.100 and tcp.port == 9000
5. 定位单条连接 在包列表中选中该连接任意一包 → 右键 → Follow → TCP Stream 弹出窗口显示该连接重组后的双向数据(可看明文或十六进制);窗口内可切换「仅显示/仅请求/仅响应」与编码方式
6. 分析连接状态 查看 TCP 握手与挥手 握手:过滤 tcp.flags.syn == 1 and tcp.flags.ack == 0 找 SYN,再找对应 SYN+ACK、ACK;挥手:过滤 tcp.flags.fin == 1tcp.flags.rst == 1异常:大量 tcp.analysis.retransmissiontcp.analysis.fast_retransmission 表示重传,需结合 RTT 与丢包排查
7. 统计与 RTT Statistics → Flow GraphStatistics → Round-Trip Time Flow Graph 可看时序;RTT 可看往返时延分布;Statistics → Conversations → TCP 可看每条连接的字节数、包数,辅助判断是否有半开、僵死连接

关键字段与调试要点

  • tcp.flags:syn、ack、fin、rst、push 等;RST 表示连接被重置,需结合前后包分析是哪一端发起。
  • tcp.seq / tcp.ack:序列号与确认号,用于判断丢包、乱序与重传。
  • tcp.len: payload 长度;0 表示纯 ACK 或控制包。
  • tcp.window_size_value:接收窗口,过小可能限制吞吐。
  • Expert InfoAnalyze → Expert Information 可汇总重传、重复 ACK、零窗口等,便于快速定位问题。

常见问题排查

  • 连接超时/建连失败:过滤 SYN,看是否有 SYN 无 SYN+ACK(对端未响应或防火墙拦截),或 SYN+ACK 无 ACK(本机未回 ACK)。
  • 数据丢包/应用收不到:看是否有重传(tcp.analysis.retransmission)、对端 RST(tcp.flags.rst == 1)、或中间设备分片/MTU 问题(看 IP 分片与 ICMP 不可达)。
  • 连接被重置:过滤 tcp.flags.rst == 1,看 RST 来自哪一侧、在哪个 seq 之后,结合应用日志判断是服务端主动关闭、超时还是异常断开。

6.6.2 Socket UDP 抓包与分析 SOP

场景说明:基于 UDP 的 Socket 通讯(DNS、QUIC、游戏、音视频 RTP、自定义协议等),无连接状态,需按五元组或 payload 特征过滤。

阶段 操作 说明
1. 抓包前配置 若已知端口或主机,在 Capture Filter 中设置 BPF 例:udp port 53(DNS)、udp port 5000host 10.0.0.1 and udp;UDP 流量大时可加 udp 避免抓过多 TCP
2. 选择接口 同 TCP,选实际收发流量的接口 本机/容器/远程按需选择
3. 开始抓包 触发 UDP 收发后抓包 UDP 无握手,需在业务触发期间抓取
4. 显示过滤 按端口、IP、长度等过滤 常用:udp.port == 5000udp and ip.addr == 192.168.1.100udp.length > 100;若 Wireshark 解析了上层协议(如 DNS、RTP),可用 dnsrtp
5. 按流重组(若支持) 部分协议支持「Follow → UDP Stream」或按 RTP 重组 对裸 UDP 可右键 → Follow → UDP Stream 看该五元组下双向 payload;RTP 可用 Telephony → RTP → Stream Analysis
6. 分析 payload 查看 Packet Bytes 或解析后的应用层字段 UDP 无重传标识,需结合应用逻辑判断丢包;可统计同一目的端口包数/字节与时间间隔,判断发送频率与是否被丢弃

关键字段与调试要点

  • udp.srcport / udp.dstport:源/目的端口,区分服务与流。
  • udp.length:UDP 段总长度(含 8 字节头);大包需关注是否 IP 分片(ip.fragments)。
  • ip.addr:确认五元组,便于区分多路流。
  • 无连接状态:不能像 TCP 那样用「流」概念直接看握手;需通过时间序、端口、payload 模式关联请求与响应(若协议有请求/响应结构)。

常见问题排查

  • 收不到包:确认抓包接口正确、BPF 未过滤掉目标端口;对端是否真的发送(可在对端或中间设备抓包对比)。
  • 丢包:UDP 本身不保证可靠,Wireshark 只能看到「到达本机网卡」的包;若应用层发现丢包,可对比包序号(若协议带序号)或统计包数。
  • 分片:过滤 ip.fragmentsip.flags.mf,看是否有多片;分片丢失会导致重组失败,应用收不到完整报文。

6.6.3 音视频直播场景抓包与分析 SOP

场景说明:音视频直播涉及多种传输方式——基于 TCP 的 HTTP(HLS、HTTP-FLV、DASH 等)、基于 UDP 的 RTP/RTCP、RTSP 控制 + RTP 承载、以及 WebRTC(见 6.6.4)。此处覆盖 RTP/RTCP、RTSP 及 HTTP 直播拉流。

阶段 操作 说明
1. 抓包前配置 按协议类型选用 BPF,缩小范围 RTP/RTCPudp portrange 5000-6000 或已知端口;RTSPtcp port 554udp port 554HLS/HTTP-FLVtcp port 80 or tcp port 443,或先不过滤在显示层再筛
2. 开始抓包 在播放端开始拉流/播放的同时启动抓包 确保从「起播」或「卡顿/花屏发生前」开始,便于做时序与丢包分析
3. 显示过滤 按协议与端口过滤 RTPrtprtp.payload_type == 96(H.264 常见);RTCPrtcpRTSPrtspHLShttp.request.uri contains ".m3u8"http.request.uri contains ".ts"HTTP-FLVhttp.request.uri contains ".flv"
4. RTP 流分析 Telephony → RTP → RTP StreamsStatistics → Flow Graph RTP Streams 可列出所有 RTP 流,选中某流后可 Analyze;可看丢包数、抖动、 delta 等;Follow → RTP Stream 可看 payload 与解码尝试(若支持)
5. RTCP 分析 过滤 rtcp,查看 SR/RR、丢包率与抖动报告 RTCP 携带接收端统计(丢包、抖动),可与 RTP 侧对比,判断是网络丢包还是对端发送问题
6. RTSP 分析 过滤 rtsp,右键 Follow → TCP Stream(若 RTSP 走 TCP) 看 OPTIONS、DESCRIBE、SETUP、PLAY 等信令与 SDP;可确认媒体端口、编码格式与 URL
7. HTTP 直播(HLS/DASH/FLV) 过滤 http,按 URI 或 Host 筛 看 .m3u8/.mpd 请求与 200 响应、.ts/.m4s 分片请求顺序与状态码;Follow → HTTP Stream 看完整请求/响应;关注 4xx/5xx 与超时

关键字段与调试要点

  • RTPrtp.ssrcrtp.seqrtp.timestamprtp.payload_type;丢包会导致 seq 不连续或 RTCP 报告高丢包率。
  • RTCP:SR(Sender Report)含发送端 NTP/RTP 时间与包数/字节数;RR(Receiver Report)含丢包数、最高接收 seq、抖动。
  • RTSP:CSeq、Session、Transport(含端口与 RTP/RTCP 端口对)。
  • HTTP 直播:状态码、Content-Length、Range 请求;分片请求间隔与响应时间可辅助判断卡顿是否与拉流延迟有关。

常见问题排查

  • 花屏/卡顿:先看 RTP 或 HTTP 分片是否有丢包或重传;再看 RTCP RR 的丢包率与抖动;最后看应用层是否频繁重试或切换码率。
  • 无法起播:RTSP 检查 DESCRIBE/SETUP/PLAY 是否均 200、SDP 与 Transport 端口是否可用;HTTP 检查 m3u8/mpd 与首条分片是否 200、CDN 是否可达。
  • 延迟大:看 RTP 时间戳与接收时间差、HTTP 分片请求间隔;缓冲与 GOP 大小也会影响延迟,需结合播放器与服务器配置。

6.6.4 WebRTC P2P 场景抓包与分析 SOP

场景说明:WebRTC 包含 信令(多通过 HTTP/WebSocket)、媒体(SRTP/SRTCP over UDP)、以及 NAT 穿透用的 STUN/TURN。抓包可分析 ICE 候选、DTLS 握手、SRTP 流与信令交互;媒体内容为加密,解密需密钥(见下)。

阶段 操作 说明
1. 抓包前配置 建议先宽抓再显示过滤;若已知端口可收窄 常用 BPF:udp(STUN/RTP 多为 UDP)或 tcp port 443 or tcp port 80(信令);WebRTC 端口动态,常不事先过滤端口
2. 开始抓包 在浏览器或 App 中完成「加入房间/呼叫」至「建立音视频」全过程 从点击「开始」前即开始抓,便于捕获完整 ICE 与 DTLS
3. 显示过滤(信令) 信令多为 HTTPS/WSS httptls 过滤信令域名;若已配 SSLKEYLOGFILE 并解密 TLS,可看到 WebSocket 或 HTTP 上的 SDP/ICE 等
4. 显示过滤(STUN) STUN 用于 NAT 探测与保活 stunstun.type;可看 Binding Request/Response、XOR-MAPPED-ADDRESS(即 NAT 映射地址)
5. 显示过滤(DTLS) WebRTC 媒体使用 DTLS 协商密钥,再以 SRTP 传媒体 dtls;可看 Client Hello/Server Hello、Certificate、Finished;无法仅凭私钥解密 DTLS,需在端点导出 DTLS/SRTP 密钥(见下)
6. 显示过滤(RTP/媒体) 解密前仅能见 SRTP 密文;解密后可识别为 RTP 解密前:udp.port == 9xxx(媒体端口在 SDP 中);解密后:可用 rtp 过滤并做 RTP 流分析
7. 解密 WebRTC 媒体(可选) 在 Chrome/Chromium 中启用 SSL 日志,导出密钥供 Wireshark 解密 SRTP Chrome 启动参数加 --ssl-key-log-file=<path> 并指定路径;Wireshark:Edit → Preferences → Protocols → TLS,在 (Pre)-Master-Secret log filename 填该路径;部分版本需在 Protocols → RTP 中启用「Decrypt SRTP」并依赖 DTLS 密钥;Chrome 的 NSS 格式密钥日志对 DTLS 有效,解密后可见 RTP 流

关键字段与调试要点

  • STUNstun.type(0x0001 Binding Req、0x0101 Binding Resp);stun.att.xor_mapped_address 为服务器看到的客户端公网地址,用于 ICE 候选。
  • SDP(在信令中)m=video/m=audioc=IN IP4a=rtcp-muxa=ice-ufrag/a=ice-pwda=fingerprint(DTLS);可确认媒体端口、ICE 与 DTLS 参数。
  • ICE:在信令中交换 candidate(host/srflx/relay);抓包可验证 candidate 是否与 STUN 响应一致、是否走 TURN(relay)。
  • DTLS:握手成功后才会有 SRTP;若 DTLS 失败,无媒体流或报错。

常见问题排查

  • P2P 不通、仅 TURN 能通:看 STUN Binding 是否有响应;若只有 relay candidate 可用,说明 NAT 对称或策略限制,需 TURN 中继。
  • 无音频/无视频:看信令中 SDP 是否含对应 m= 与 codec;看 DTLS 是否握手成功;看是否有对应端口的 UDP 包(防火墙/安全组可能拦媒体端口)。
  • 媒体解密失败:确认密钥日志在握手已配置、浏览器确实写入了该文件;Wireshark 需同时支持 TLS 密钥日志与 RTP 的 SRTP 解密(部分版本需在 RTP 偏好中勾选解密选项)。

WebRTC 抓包与解密流程简图

flowchart LR
    subgraph 抓包
        A[抓 UDP/TCP] --> B[显示过滤 STUN/DTLS/TLS]
        B --> C[信令看 SDP/ICE]
    end
    subgraph 解密
        D[浏览器 ssl-key-log] --> E[Wireshark TLS 密钥]
        E --> F[DTLS/SRTP 解密]
    end
    C --> G[分析候选与媒体端口]
    F --> G

6.6.5 场景与过滤器速查表
场景 建议抓包过滤(BPF) 常用显示过滤 分析入口
Socket TCP tcp port 端口host IP tcp.port == 端口tcp.stream eq 流索引 Follow TCP Stream、Expert Info、Flow Graph
Socket UDP udp port 端口host IP and udp udp.port == 端口udp.length > 0 Follow UDP Stream、Packet Bytes
音视频 RTP udp portrange 5000-6000 rtprtcprtp.payload_type == 96 Telephony → RTP Streams、RTP Stream Analysis
RTSP tcp port 554udp port 554 rtsp Follow TCP Stream(信令)、RTP 同音视频
HLS/HTTP 直播 tcp port 80 or tcp port 443 http.request.uri contains ".m3u8"http.request.uri contains ".ts" Follow HTTP Stream、看状态码与顺序
WebRTC 信令 tcp port 443 http/tls(解密后看 WSS/SDP) Follow HTTP Stream、看 SDP/ICE
WebRTC STUN/媒体 udp stundtlsrtp(解密后) STUN 看 XOR-MAPPED;RTP 同音视频

七、高级应用与扩展

7.1 官方文档与界面操作导读

内容 官方入口 说明
抓包 Capture → Options;User's Guide Ch.4 接口选择、Capture Filter、Output/Options 标签
抓包过滤语法 §4.10 Filtering while capturingWiki CaptureFilters BPF 原语、自动远程过滤
显示过滤语法 §6.4 Building Display Filter ExpressionsWiki DisplayFilters 比较/逻辑/切片/函数/字段引用
协议与字段列表 View → Internals → Supported ProtocolsDisplay Filter Reference 各协议可过滤字段名
跟随流 右键包 → Follow → TCP/TLS/HTTP Stream 见下
统计 Statistics 菜单 Conversations、Endpoints、Protocol Hierarchy、RTT、IO Graph
专家信息 Analyze → Expert Information 重传、重复 ACK、错误等汇总
开发/解析器 Developer's Guide 编写 Dissector、插件

7.2 跟随流(Follow Stream)

对 TCP、TLS、HTTP 等协议,右键报文选择 Follow → TCP Stream / TLS Stream / HTTP Stream,可在一个窗口中看到该连接上的重组应用数据(明文或解密后),便于分析单会话内容 [13]。

7.3 统计与 IO 图

  • Statistics:Conversations、Endpoints、Protocol Hierarchy、Round-Trip Time 等,用于宏观把握流量与延迟。
  • IO Graphs:按时间轴绘制报文数、字节数或自定义显示过滤器计数,便于观察突发、重传与趋势。

7.4 命令行 tshark

tshark 为 Wireshark 的命令行版本,使用相同的抓包与显示过滤器,适合脚本化与 CI 环境,例如:

tshark -i eth0 -f "tcp port 80" -w capture.pcapng
tshark -r capture.pcapng -Y "http.request" -T fields -e http.request.uri

7.5 自定义解析器与插件

新协议可通过编写 Dissector(C 或 Lua)注册到 Wireshark,实现 proto_register_XXXproto_reg_handoff_XXX,将协议与字段挂入协议树并参与显示过滤;详见 Wireshark Developer's Guide [11]。


八、伪代码与算法说明

8.1 抓包过滤器(BPF)求值概念

BPF 在内核或用户态对每个报文执行布尔表达式求值,仅当结果为真时交付给上层;原语通常对应「偏移 + 长度 + 掩码 + 比较」,例如「IPv4 且目的端口为 80」会编译为对帧内特定偏移处字节的测试。完整语义见 BPF 论文与 man page [12]。

8.2 显示过滤器求值

对每条已解析的报文,根据当前显示过滤器表达式遍历协议树:若字段存在且满足比较/逻辑/集合条件则保留显示,否则隐藏。字段类型与运算符需匹配(如整数用 ==、字符串用 contains/matches),类型不匹配会导致过滤无效或报错。多值字段(如 ip.addr 同时有源与目的)下,== 表示「任一匹配即成立」(any_eq),若需「全部匹配」可使用 ===(all_eq)[10]。

8.3 协议解析器调用顺序(概念)

对每个捕获的 frame:
  1. Frame dissector 写入时间戳、长度等元数据
  2. 根据链路层类型(如 Ethernet type)选择下一层解析器
  3. 递归:每个解析器解析本层头部,根据「下一层协议」字段(如 IP 的 protocol、TCP 的 port)调用子解析器
  4. 直至无子协议或数据结束,协议树与字段注册完成,供显示过滤器使用

参考文献

[1] Wireshark. About Wireshark. www.wireshark.org/about.html
[2] Wireshark. Wireshark User's Guide. www.wireshark.org/docs/wsug_h…
[3] 与 Charles 等代理工具的差异:Charles 为应用层代理,Wireshark 为底层抓包与协议解析。
[4] Wireshark. 1.4. A Brief History Of Wireshark. www.wireshark.org/docs/wsug_h…
[5] Wireshark. Filtering while capturing / Building Display Filter Expressions. User's Guide.
[6] Wireshark Wiki. libpcap. wiki.wireshark.org/libpcap
[7] Wireshark Wiki. Packet capture. wiki.wireshark.org/CaptureSetu…
[8] Npcap. Npcap: Windows Packet Capture Library & Driver. npcap.org/
[9] Wireshark. 4.10. Filtering while capturing. www.wireshark.org/docs/wsug_h…
[10] Wireshark. 6.4. Building Display Filter Expressions. www.wireshark.org/docs/wsug_h…
[11] Wireshark. Chapter 9. Packet Dissection. Developer's Guide. www.wireshark.org/docs/wsdg_h…
[12] tcpdump. pcap-filter man page. www.tcpdump.org/manpages/pc…
[13] Wireshark. Following Protocol Streams. User's Guide.
[14] Wireshark Wiki. TLS. wiki.wireshark.org/TLS
[15] SSLTrust / 第三方. Wireshark troubleshoot network SSL TLS.
[16] Cisco Community. Troubleshoot TLS using Wireshark. community.cisco.com/t5/security…
[17] Wireshark Wiki. CaptureFilters. wiki.wireshark.org/CaptureFilt…
[18] Wireshark Wiki. DisplayFilters. wiki.wireshark.org/DisplayFilt…
[19] Wireshark. 4.5. The "Capture Options" Dialog Box. User's Guide. www.wireshark.org/docs/wsug_h…
[20] Wireshark. Display Filter Reference. www.wireshark.org/docs/dfref/

01-Debug调试@网络-Charles网络抓包工具:从原理到实践

📋 目录


一、概述与历史演进

1.1 工具简介

Charles 是一款面向 Windows、macOS、LinuxWeb 调试代理(Web Debugging Proxy) 应用,由 Karl von Randow 创建,自 2002 年发布至今,由 XK72 维护 [1][2]。其核心能力包括:拦截、记录、修改与重放 HTTP/HTTPS 流量,支持带宽限速、断点调试、请求/响应重写与本地/远程映射,被广泛用于 Web 与移动端接口调试、前后端联调、弱网与异常场景测试 [1][3][4]。

1.2 历史与版本脉络

时期 事件
2002 Charles 首次发布,以 Java 实现,跨平台运行
3.x 引入 SSL Proxying(HTTPS 中间人解密)、各平台根证书安装流程
3.10+ Charles 根证书改为每台安装独立生成,需重新信任
3.11.4+ 支持 iOS App Transport Security (ATS)
2018 Charles for iOS 上架 App Store,支持在设备端抓包 [2]
2024–2025 4.6.x 稳定版;Charles 5.0 发布,新 UI、Apple Silicon/Windows on ARM、新会话格式 .chlz [2][5]

1.3 典型应用场景

  • 接口调试:查看请求 URL、Method、Header、Body 与响应状态、Body(JSON/XML 等),定位参数与返回错误。
  • HTTPS 明文查看:通过 SSL Proxying 将加密流量解密为明文,便于分析 API 内容。
  • 弱网与限速:Throttling 模拟带宽、延迟、丢包,验证加载、超时与降级逻辑。
  • Mock 与联调:Map Local / Map Remote / Rewrite 用本地或备用环境响应替代线上,或修改请求/响应内容。
  • 断点调试:在请求发出前或响应返回前暂停,修改后再放行或中止,用于测试异常与边界。

二、核心原理

2.1 代理与中间人

Charles 作为 HTTP/HTTPS 代理 运行在本机(默认端口 8888)。客户端(浏览器、App)将代理设置为 127.0.0.1:8888 后,发往目标的 HTTP(S) 请求会先发到 Charles,再由 Charles 转发到真实服务器;响应同样经 Charles 再回到客户端。因此 Charles 处于「客户端 ↔ Charles ↔ 服务端」的中间人位置,可完整查看与修改双向流量 [3][4]。

flowchart LR
    subgraph 客户端
        C[Browser / App]
    end
    subgraph 代理层
        P[Charles :8888]
    end
    subgraph 服务端
        S[Origin Server]
    end
    C -->|1. 请求| P
    P -->|2. 转发请求| S
    S -->|3. 响应| P
    P -->|4. 返回响应| C

2.2 数据流与记录

  • 记录:Charles 在转发前后记录请求与响应的 URL、方法、头、体;对 HTTPS 需开启 SSL Proxying 并安装根证书后才能解密并记录明文。
  • 结构视图:按 Host 或 Path 聚合展示会话,便于按接口查看;支持搜索、过滤与导出会话(.chls/.chlz)。
  • 证书与解密:HTTPS 解密依赖「客户端信任 Charles 根证书 + Charles 对指定 Host 启用 SSL Proxying」,详见第三节。

三、HTTPS 与 SSL 代理

3.1 为何 HTTPS 需要特殊处理

HTTPS 在 TCP 之上建立 TLS/SSL 加密通道,端到端加密后,代理若只做「透传」,无法看到应用层明文。Charles 要查看或修改内容,必须作为 TLS 中间人:与客户端建立一条 TLS 连接,与服务器建立另一条 TLS 连接,在中间以明文处理数据 [4][6]。

3.2 SSL Proxying(中间人)原理

Charles 的 SSL Proxying 本质是受控的「中间人」行为 [6][7]:

  1. 客户端 → Charles:客户端发起 HTTPS 请求到 host:443,因系统代理指向 Charles,TCP 连接实际建到 Charles;TLS 握手时,Charles 转发服务器真实证书,而是用 Charles 根证书签发一张「伪造」的站点证书(Subject 等与目标 host 匹配),下发给客户端。
  2. 客户端验证:客户端校验证书链。若未安装/信任 Charles 根证书,会报「不受信任的 CA」;安装并信任 Charles 根证书后,客户端认为该站点证书合法,与 Charles 完成 TLS 握手,后续应用层数据以 Charles 与客户端协商的密钥加密。
  3. Charles → 服务端:Charles 再以真实客户端身份向目标服务器发起 HTTPS,使用服务器真实证书完成 TLS,获得与服务器的明文通信。
  4. 结果:Charles 同时拥有「客户端 ↔ Charles」与「Charles ↔ 服务端」的解密能力,可记录、修改请求与响应后再转发。
    简要对应关系 [16]:客户端向服务器发起 HTTPS 请求 → Charles 拦截并伪装成客户端向服务器请求 → 服务器返回 CA 证书给「客户端」(实为 Charles)→ Charles 用本地根证书签发一张与目标站点匹配的证书,替换后发给客户端 → 客户端用 Charles 公钥加密对称密钥发给 Charles → Charles 用私钥解密得到对称密钥,再用服务器公钥加密发给服务器 → 此后 Charles 同时持有两端密钥,可解密、修改后再转发。关键前提:客户端必须信任 Charles 根证书,否则会报证书不受信任。
sequenceDiagram
    participant C as 客户端
    participant P as Charles
    participant S as 服务器

    C->>P: 建立连接 (代理)
    P->>C: 返回 Charles 签发的站点证书
    Note over C: 校验证书(需信任 Charles 根证书)
    C->>P: 加密请求 (客户端↔Charles 密钥)
    P->>S: 建立 TLS,获取服务器证书
    P->>S: 加密请求 (Charles↔服务器 密钥)
    S->>P: 加密响应
    P->>P: 解密并可选修改
    P->>C: 用客户端密钥加密后返回

3.3 配置要点(官方建议 [6][7][8])

  • 启用 SSL Proxying:Proxy → SSL Proxying Settings,勾选 Enable SSL Proxying,并在列表中加入要解密的主机(Host + Port,如 *:443api.example.com:443)。不在此列表中的 Host,Charles 对 HTTPS 只做透传,不解密。
  • 按地址启用 SSL Proxying(重要):若只做了全局「Enable SSL Proxying」却未把具体要抓的域名加入列表,该域名的 HTTPS 仍会以密文显示。操作方式二选一即可 [15][16]:
    • 方式一:在 Charles 会话列表(Structure/Sequence)中,右键目标 Host 或该域名下的某条请求 → SSL Proxying → Enable SSL Proxying,Charles 会自动将该 Host:443 加入 SSL Proxying 列表。
    • 方式二:Proxy → SSL Proxying Settings → Add,手动填写 Host(如 api.example.com)与 Port(如 443)。
      因此:具体的 HTTPS 抓包,必须在「被抓包的那个地址」上启用 SSL Proxying,否则无法看到明文。
  • 安装并信任根证书:Help → SSL Proxying → Install Charles Root Certificate(或 Save 后手动导入)。安装后需在系统/浏览器中将该证书设为受信任的根 CA(如 macOS 钥匙串中设为「始终信任」),否则客户端仍会报错。
  • 关闭解密:若不需要查看 HTTPS 明文,可在 Proxy Preferences 中关闭 SSL Proxying,Charles 将直接转发 TLS 流量,不进行解密与记录明文。

3.4 HTTPS 解密流程(算法级描述)

算法概念:Charles 作为 TLS 中间人

1. 客户端向 host:443 发起 TLS ClientHello(因系统代理,连接至 Charles)。
2. Charles 向真实服务器发起 TLS 连接,完成与服务器的握手,获得服务器证书与会话密钥 K2。
3. Charles 用本地 Charles 根证书的私钥,为「host」签发一张新证书 cert_fake,Subject 等与服务器证书一致或兼容。
4. Charles 向客户端返回 cert_fake,客户端用已信任的 Charles 根证书验证 cert_fake,通过则与 Charles 完成握手,得到客户端与 Charles 的会话密钥 K1。
5. 客户端发送的 HTTPS 请求用 K1 加密,Charles 用 K1 解密得到明文请求;Charles 用 K2 加密后转发给服务器。
6. 服务器响应用 K2 加密,Charles 用 K2 解密得到明文响应;Charles 可修改后再用 K1 加密返回客户端。
7. 因此 Charles 在「请求」与「响应」两段均具备明文读写能力,用于记录、Breakpoint 修改、Rewrite、Map Local 等。

3.5 证书与安全注意

  • Charles 根证书拥有对任意域签发证书的能力,一旦被信任,可被用于窃听或篡改 HTTPS。因此仅应在本机调试环境安装,不要在生产或个人敏感环境中长期信任。
  • 从 Charles 3.10 起,根证书为每台机器/每次安装独立生成,旧设备导出的根证书不能直接用于新环境,需在新环境重新安装并信任 [8]。

3.6 HTTPS 抓包配置处理(操作清单)

要成功对 HTTPS 流量进行抓包并看到明文,必须同时满足 Charles 端客户端/本机 两处配置;缺一不可。下面给出统一的操作清单与排查要点。

3.6.1 Charles 端必须完成的配置

顺序 操作 说明
打开 Proxy → SSL Proxying Settings 若未打开过,先进入该窗口
勾选 Enable SSL Proxying 不勾选则所有 HTTPS 仅透传,不解密
SSL Proxying Locations 列表中为要抓的域名添加条目 Host:填域名或 *(如 * 表示任意;api.example.com 表示仅该域名);Port:一般为 443。未在列表中的 Host 不会被解密,界面中仍显示为密文

按地址启用的两种方式(任选其一即可):

  • 方式 A(推荐):抓包时在会话列表(Structure / Sequence)中,右键目标 Host 或该域名下任意一条请求 → SSL Proxying → Enable SSL Proxying,Charles 会自动把该 Host:443 加入上述列表。
  • 方式 B:在 SSL Proxying Settings 窗口点击 Add,手动填写 HostPort(443);可用 * 表示任意主机。

3.6.2 客户端/本机必须完成的配置

抓包对象是,就要在的系统或环境中安装并信任 Charles 根证书:

抓包对象 证书安装与信任位置
本机浏览器 本机:Help → SSL Proxying → Install Charles Root Certificate;安装后在系统钥匙串/证书存储中将该证书设为受信任的根 CA(如 macOS 钥匙串访问 → 找到 Charles Proxy CA → 展开「信任」→ 使用此证书时:始终信任
iOS 真机 App/浏览器 手机:Safari 打开 chls.pro/ssl 安装描述文件;设置 → 通用 → 关于本机 → 证书信任设置 中对该 Charles 证书启用「完全信任
Android / HarmonyOS 设备 设备浏览器打开 chls.pro/ssl 安装证书;Android 7+ 自研 App 还需在工程中配置 Network Security Configuration 信任用户证书(见 §6.3)
iOS 模拟器 Charles:Help → SSL Proxying → Install Charles Root Certificate in iOS Simulators(需先关闭模拟器再执行)

未安装或未信任根证书时,客户端会报「证书不受信任」「连接不是私密连接」等错误,HTTPS 握手失败,无法抓包。

3.6.3 配置自检与常见问题

  • Charles 里能看到请求,但 Response 是乱码或显示为加密数据
    → 说明代理已生效,但未对该 Host 启用 SSL Proxying。按 3.6.1 在 SSL Proxying Locations 中添加该 Host:443,或右键该请求/Host → Enable SSL Proxying。

  • 客户端报证书错误、无法打开页面或 App 请求失败
    → 说明未在该客户端环境安装或信任 Charles 根证书。按 3.6.2 在对应设备/本机完成安装并在「证书信任设置」或系统凭据中设为信任。

  • *已添加 :443 仍有个别域名看不到明文
    → 少数情况下需确认该请求确实走了 Charles 代理(系统/App 代理指向 Charles);若为自研 App,检查是否开启了证书锁定(Certificate Pinning),若开启则需在调试版本中关闭或信任 Charles。

  • 换电脑或重装 Charles 后,手机/本机之前装的证书报错
    → Charles 3.10+ 根证书每台机器独立生成,需在当前运行 Charles 的电脑上重新执行「Install Charles Root Certificate on a Mobile Device」,并在设备上重新访问 chls.pro/ssl 安装新证书并信任。

3.6.4 配置处理流程简图

flowchart LR
    subgraph Charles端
        A1[Enable SSL Proxying]
        A2[Add Host:443 或 右键启用]
    end
    subgraph 客户端
        B1[安装 Charles 根证书]
        B2[信任该证书]
    end
    A1 --> A2
    B1 --> B2
    A2 --> C[HTTPS 可解密]
    B2 --> C

总结:HTTPS 抓包 = Charles 端对目标 Host 启用 SSL Proxying + 在抓包对象所在环境安装并信任 Charles 根证书;两者都做对后,即可在 Charles 中看到该域名的请求/响应明文并进行修改、断点等操作。


四、功能体系与工具链

4.1 功能总览

功能 说明 典型用途
Proxy 记录 自动记录经 Charles 的 HTTP(S) 请求与响应 日常抓包、接口排查
SSL Proxying 对指定 Host 解密 HTTPS,以明文展示与修改 查看/改写 API 内容
Breakpoints 按 URL 匹配在请求/响应前后暂停,可编辑后放行或中止 改参数、改响应、模拟失败
Map Local 将匹配的请求的响应替换为本地文件内容 用本地 JSON/HTML 做 Mock
Map Remote 将匹配的请求重定向到另一 Host/Path 将线上接口指到测试/预发
Rewrite 按规则修改请求/响应头或体(如替换字符串) 改 Host、Token、部分 JSON
Throttling 限制带宽、延迟、丢包、MTU 等 弱网、高延迟、不稳定网络
Compose / Repeat 手动编辑请求并发送、重放已有请求 接口重放、压力与回归

4.2 Breakpoints(断点)[9]

  • 作用:在请求发出前或响应返回前拦截,在 Charles 中查看并编辑内容,再选择 Execute(应用修改并继续)、Abort(中止并返回错误)或 Cancel(放弃修改并原样通过)。
  • 配置:Proxy → Breakpoint Settings,添加 Location,用协议、Host、端口、路径模式匹配 URL,支持通配符;每个断点可单独勾选「Request」「Response」或两者。
  • 流程概念
请求发出 → 若匹配 Request 断点 → 暂停 → 编辑 → Execute/Abort/Cancel
         → 若未匹配或已放行 → 转发到服务器
响应返回 → 若匹配 Response 断点 → 暂停 → 编辑 → Execute/Abort/Cancel
         → 若未匹配或已放行 → 返回客户端

4.3 Map Local 与 Map Remote [10][11][15]

  • Map Local:当请求的 URL 与设定规则匹配时,Charles 向服务器发请求,而是用本地文件内容作为响应体返回。适用于静态资源或 JSON 等;服务端动态逻辑不会执行。
    典型用法 [15]:① 用本地 JSON 文件充当某接口的返回值(如难以复现的首充、活动接口);② 用本地 JS 调试线上页面:将线上站点的 https://www.example.com/js/main.js 映射到本机 /Users/xxx/project/js/main.js,在浏览器直接访问线上 URL 即可看到本地修改在「线上环境」下的效果,适合本地环境不完整、必须依赖线上环境联调时。
  • Map Remote:将匹配的请求重定向到另一地址(可不同 Host/Path),例如把 https://api.prod.com/v1/* 映射到 https://api.test.com/v1/*,便于用测试环境替代生产。
    典型用法 [15]:本地开发时接口写为带域名的 https://www.example.com/api/getData(避免跨域),在 Charles 中配置「将 https://localhost/api/* 或本机某路径映射到 https://www.example.com/」,这样本地请求会实际转发到线上或测试环境;配合 Rewrite 注入登录 Cookie 后,可带登录态访问测试/线上接口。

4.4 Rewrite [11][15]

  • 按规则对请求或响应的 Header / Body 做字符串级替换(如键名、域名、Token)。与 Map Local/Remote 相比,不替换整份内容,只做局部修改;规则可基于 URL 匹配与通配符。
    典型用法 [15]:
    • 模拟登录态:在 Tools → Rewrite 中添加规则,对指定 URL 集合做 Add Header,将已登录环境下的 Cookie 填入请求头,即可在本地或无登录环境访问需登录的接口(Cookie 有过期时间,需定期更新)。
    • 解决响应乱码:部分响应使用 Brotli(br) 编码时,Charles 可能无法正确解码导致 Body 乱码;可在 Rewrite 中修改请求头 Accept-Encoding,去掉 br,让服务端返回 gzip/deflate,Charles 即可正常显示 JSON 等内容。
    • 其他:添加/修改请求参数、修改响应状态码或部分 JSON 字段等。

4.5 Throttling(带宽与弱网模拟)[4][12]

  • 作用:模拟慢速、高延迟、丢包等,使客户端「以为」处于弱网环境,用于验证加载、超时、错误提示与降级策略。
  • 启用:Proxy → Start Throttling(或快捷键);Proxy → Throttle Settings 配置。
  • 常见参数
    • Bandwidth:上行/下行带宽上限(如 256 kbps)。
    • Latency:往返延迟(如 500 ms)。
    • Reliability:丢包率。
    • MTU:最大传输单元。
  • 仅限部分 Host:在 Throttle Settings 中勾选「Only for selected hosts」并添加 Host,可只对指定接口限速,避免影响其他操作。

五、配置与使用场景

5.1 本机浏览器抓包(macOS / Windows)

  1. 启动 Charles,默认监听 8888。
  2. 系统代理:Charles 可自动设置系统 HTTP/HTTPS 代理为 127.0.0.1:8888(Proxy → macOS Proxy / Windows Proxy);关闭 Charles 时通常可恢复原设置。请求路径如下:
flowchart LR
    A[浏览器] -->|系统代理 127.0.0.1:8888| B[Charles]
    B --> C[目标服务器]
    C --> B
    B --> A
  1. HTTPS:按第三节安装并信任根证书,在 SSL Proxying Settings 中添加需解密的主机(如 *:443)。
  2. 浏览器访问任意 HTTP(S) 站点,在 Charles 的 Structure 或 Sequence 视图中查看会话。

5.2 仅抓部分域名或接口

  • SSL Proxying Settings:只添加需要解密的 Host,其他 HTTPS 不解密。
  • Proxy → Recording Settings:Include 中只填需要记录的 Host/Path,或 Exclude 排除无关域名,减少噪音。

5.3 Mock 与联调流程(概念)

1. 在 Map Local 中添加规则:例如 Host=api.example.com, Path=/v1/config → 本地文件 config.json
2. 客户端请求 https://api.example.com/v1/config → Charles 匹配规则 → 直接返回 config.json 内容
3. 或使用 Map Remote:将 api.example.com 映射到 api.test.com,请求被转发到测试环境
4. 或使用 Rewrite:将响应体中的 "env":"prod" 替换为 "env":"test"

5.4 弱网测试流程(概念)

1. Proxy → Throttle Settings,设置 Bandwidth / Latency / Reliability 等
2. 可选:Only for selected hosts,添加待测接口的 Host
3. Proxy → Start Throttling
4. 在 App 或页面中触发请求,观察加载时间、超时与错误处理
5. 测试结束后 Stop Throttling

六、各平台网络抓包配置 SOP

以下按 iOS、AOS(Android)、HOS(HarmonyOS)、WebAPP(浏览器/Web 端) 四类平台,给出 Charles 抓包的标准操作步骤(SOP),便于按平台查阅与排错。

6.1 通用前提与平台对照

项目 说明
网络 终端设备与运行 Charles 的电脑处于同一局域网(同一 Wi‑Fi 或同网段)。
端口 电脑防火墙放行 8888 入站,或临时关闭防火墙测试。
Charles 已启动并监听 8888;需抓 HTTPS 时在 Charles 内对目标 Host 启用 SSL Proxying(见 §3.3)。
平台 代理配置位置 证书安装方式 HTTPS 特别说明
iOS 设置 → Wi‑Fi → 当前网络 → 配置代理 浏览器打开 chls.pro/ssl → 安装描述文件 → 证书信任设置 需在「证书信任设置」中勾选 Charles
AOS (Android) 设置 → WLAN → 当前网络 → 代理 浏览器打开 chls.pro/ssl 安装;Android 7+ 自研 App 需 NSC 信任用户证书 见 §6.3
HOS (HarmonyOS) 设置 → WLAN → 当前网络 → 代理 同 AOS,浏览器 chls.pro/ssl;自研应用可能需网络安全配置 与 Android 类似,新系统可能需应用内代理/证书配置
WebAPP 系统代理或浏览器代理指向本机 127.0.0.1:8888 本机安装 Charles 根证书并信任(Help → Install Charles Root Certificate) 依赖系统/浏览器信任 Charles 根证书

6.2 iOS 抓包配置 SOP [8][13]

适用于 iPhone / iPad 真机iOS 模拟器

6.2.1 iOS 真机

步骤 操作 说明
1 电脑:Charles 已启动 → Help → SSL Proxying → Install Charles Root Certificate on a Mobile Device 弹出框内会显示代理地址(如 192.168.x.x:8888)与证书下载页 chls.pro/ssl,记下电脑 IP 与 8888 端口
2 手机:设置 → Wi‑Fi → 点击当前已连接网络右侧 (i) → 配置代理 → 选择 手动 服务器:填电脑 IP;端口:8888;保存
3 手机:用 Safari 打开 chls.pro/ssl 按提示下载并安装「Charles Proxy CA」描述文件,若提示需在设置中确认则前往「设置 → 已下载描述文件」安装
4 手机:设置 → 通用关于本机证书信任设置 找到 Charles Proxy CA,打开「完全信任」开关;未信任则 HTTPS 会报证书错误
5 Charles:Proxy → SSL Proxying Settings → 勾选 Enable,在列表中 Add 需解密的 Host(如 *:443api.xxx.com:443);或抓包时在会话列表右键目标 Host/请求 → SSL Proxying → Enable SSL Proxying 不在此列表的域名 HTTPS 仍为密文 [15][16]
6 在手机中打开要抓的 App 或 Safari,正常发起请求 Charles 的 Structure / Sequence 中应出现对应会话;HTTPS 需完成步骤 4、5 才能看到明文

注意:若 App 启用 ATS 且不信任用户安装的 CA,需在自研 App 的 Info.plist 中配置 ATS 例外或使用已信任 Charles 的调试包。

6.2.2 iOS 模拟器

步骤 操作 说明
1 关闭所有 iOS 模拟器实例 确保证书安装到当前模拟器运行时
2 Charles:Help → SSL Proxying → Install Charles Root Certificate in iOS Simulators 证书会安装到当前已安装的模拟器系统中
3 启动模拟器;在 macOS 上勾选 Proxy → macOS Proxy(或 Windows Proxy) 模拟器继承系统代理,流量走本机 Charles
4 在 Charles 的 SSL Proxying Settings 中为需抓取的 Host 启用 SSL Proxying 同真机步骤 5
5 在模拟器内打开 Safari 或目标 App 发起请求 抓包与真机一致

6.3 AOS(Android)抓包配置 SOP [8]

适用于 Android 手机 / 平板(含 Android 7+ 自研 App 的证书信任配置)。

步骤 操作 说明
1 电脑:Charles 已启动;Help → SSL Proxying → Install Charles Root Certificate on a Mobile Device,记下 电脑 IP8888 同 iOS
2 手机:设置 → WLAN(或 网络和互联网 → Wi‑Fi)→ 长按当前连接网络 → 修改网络 / 高级选项代理手动 主机名:电脑 IP;端口:8888;保存
3 手机:用系统浏览器打开 **chls.pro/ssl**,下载并安装 Charles 根证书 按系统提示完成「安装到凭据存储」等步骤
4 Android 7.0+ (N):系统默认不信任用户安装的 CA。若抓的是自研 App,需在工程中增加 Network Security Configuration,在 debug 下信任用户证书: 仅影响调试包,正式包可不引用或仅 debug 引用

res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <debug-overrides>
    <trust-anchors>
      <certificates src="user" />
      <certificates src="system" />
    </trust-anchors>
  </debug-overrides>
</network-security-config>

AndroidManifest.xml<application> 中增加:

android:networkSecurityConfig="@xml/network_security_config"

| 5 | Charles:Proxy → SSL Proxying Settings → 为需抓取的 Host 添加 *:443 或具体域名:443;或右键会话中的 Host → Enable SSL Proxying | 同 iOS | | 6 | 在手机中打开目标 App 或浏览器发起请求 | 若仍报证书错误,检查步骤 3、4 是否完成;第三方 App 无法改 NSC 时可能无法抓其 HTTPS |


6.4 HOS(HarmonyOS)抓包配置 SOP

适用于 华为 / 荣耀等搭载 HarmonyOS 的设备;代理与证书流程与 Android 类似,部分机型路径可能为「设置 → WLAN → 当前网络 → 代理」 [17]。

步骤 操作 说明
1 电脑:Charles 已启动;记下电脑 IP 与 8888 端口(Help → Install Charles Root Certificate on a Mobile Device 可查看) 同 iOS / AOS
2 手机:设置 → WLAN → 当前连接网络 → 代理(或 高级 / 更多)→ 选 手动 主机/服务器:电脑 IP;端口:8888
3 手机:浏览器打开 **chls.pro/ssl**,下载并安装 Charles 根证书 按系统提示安装到「凭据存储」等;部分 HarmonyOS 版本需在「设置 → 安全 → 加密与凭据」中确认用户证书已安装
4 自研 HarmonyOS 应用:若抓包时 HTTPS 仍报证书错误,需在应用内配置信任用户证书(视 SDK/API 版本而定;API 10+ 支持 usingProxycaPath 等)或使用系统提供的网络安全配置能力 与 AOS 的 NSC 思路类似,具体以华为开发者文档为准
5 Charles:SSL Proxying Settings 中为需解密的 Host 添加条目,或右键会话 → Enable SSL Proxying 同其他平台
6 在设备上打开目标 App 或浏览器发起请求 确认代理与证书均生效

6.5 WebAPP(浏览器 / Web 端)抓包配置 SOP

适用于 桌面浏览器(Chrome / Edge / Safari / Firefox) 以及 移动端浏览器 访问的 Web 页面;核心是「本机或当前设备使用 Charles 作为代理 + 信任 Charles 根证书」。

6.5.1 桌面端(本机浏览器)

步骤 操作 说明
1 电脑:启动 Charles,确认监听 8888 默认 Proxy → macOS Proxy / Windows Proxy 会设置系统代理为 127.0.0.1:8888
2 本机证书:Help → SSL Proxying → Install Charles Root Certificate;安装后在系统钥匙串(macOS)或证书管理(Windows)中将 Charles 根证书设为受信任的根 CA 否则浏览器访问 HTTPS 会报不安全
3 Charles:Proxy → SSL Proxying Settings → Enable SSL Proxying,Add 需解密的 Host(如 *:443)或抓包时右键目标 Host → Enable SSL Proxying 同移动端
4 在浏览器中访问目标 Web 或 WebAPP 流量经 Charles,Structure / Sequence 中可查看与修改请求/响应

仅对当前浏览器走代理(不改系统代理)时:安装浏览器代理扩展(如 SwitchyOmega),将 HTTP/HTTPS 代理指向 127.0.0.1:8888,并确保该浏览器信任本机已安装的 Charles 根证书。

6.5.2 移动端浏览器(手机/平板访问 Web)

  • iOS:按 §6.2.1 配置代理与证书后,在 Safari 或其他浏览器中访问的 H5/Web 请求会经 Charles。
  • AOS / HOS:按 §6.3 / §6.4 配置代理与证书后,在系统浏览器或 Chrome 等中访问的页面请求会经 Charles;若仅浏览器抓包、不涉及 App,通常只需系统代理 + 安装并信任 Charles 证书即可。

6.6 流程小结

flowchart TD
    A[设备与电脑同网 + Charles 已启动] --> B[设备端配置代理: 电脑IP:8888]
    B --> C[设备/本机安装并信任 Charles 根证书]
    C --> D[Charles 内对目标 Host 启用 SSL Proxying]
    D --> E[发起请求]
    E --> F[Charles 记录并可选解密/修改]

七、最佳实践与注意事项

  • 仅调试环境使用:Charles 根证书权限极大,只在开发/测试机器上安装并信任,用毕可关闭系统代理或停用 Charles。
  • 最小化 SSL Proxying 范围:只对需要查看的 Host 开启 SSL Proxying,避免不必要的解密与隐私风险。
  • 弱网:优先使用「Only for selected hosts」限速,减少对整机其他请求的影响。
  • 敏感数据:会话中可能包含 Token、Cookie、账号信息,保存 .chls/.chlz 或截图时注意脱敏与保管。
  • 合规:仅对自有或已授权的应用与接口抓包,勿用于未授权的第三方服务或用户数据。

延伸阅读(掘金系列)

以下文章从 iOS/Android 抓包、前端联调、HTTPS 原理与 Charles 功能教程等角度做了补充说明,可按需查阅。

序号 标题 链接 内容概要
01 iOS Charles 抓包 掘金 iOS 端 Charles 抓包配置与证书安装
02 Android 端 Charles 抓包 掘金 Android 代理与证书配置、高版本信任用户 CA
03 Charles 前端应用 掘金 Rewrite 模拟登录 Cookie、Map Remote/Local、去掉 br 解决乱码
04 史上最强 Charles 抓包 掘金 Charles 功能与抓包场景综合介绍
05 Charles 从入门到精通 掘金 入门到进阶功能与操作教程
06 Charles 功能介绍和使用教程 掘金 功能说明与使用步骤
07 HTTPS 与 Charles 掘金 HTTP/HTTPS 安全、TLS 握手与 Charles 中间人原理
08 为了学会 Charles,我拼命了 掘金 简介、iPhone/Chrome 配置、Repeat/Compose/Rewrite/Map 简介
09 最明白的 Charles 教程(一) 掘金 Charles 基础与界面说明
10 最明白的 Charles 教程(二) 掘金 抓包与过滤操作
11 最明白的 Charles 教程(三) 掘金 进阶功能与场景
12 最明白的 Charles 教程(四) 掘金 综合实战与排错

参考文献

[1] Charles Proxy. Overview / Features. www.charlesproxy.com/overview/fe…
[2] Wikipedia. Charles (software). en.wikipedia.org/wiki/Charle…
[3] Charles Proxy. Documentation – Welcome. www.charlesproxy.com/documentati…
[4] XK72. Charles Proxy. www.charlesproxy.com/
[5] Charles Proxy. Version History. www.charlesproxy.com/documentati…
[6] Charles Proxy. SSL Proxying. www.charlesproxy.com/documentati…
[7] Charles Proxy. SSL Certificates. www.charlesproxy.com/documentati…
[8] Charles Proxy. SSL Certificates – iOS / Android / Java / Chrome. 官方文档 Install Charles Root Certificate 各平台说明.
[9] Charles Proxy. Breakpoints Tool. www.charlesproxy.com/documentati…
[10] Charles Proxy. Map Remote. www.charlesproxy.com/documentati…
[11] Charles Proxy. Map Local;Stack Overflow. Charles Proxy Rewrite vs Map Local.
[12] Charles Proxy. Throttling;Donny Wals. Throttle network speeds for a specific host in Charles;Mobot. Charles Proxy for Network Throttling.
[13] Detroit Labs. A Guide To Charles Proxy for Mobile Development;Medium. Setting Up Charles Proxy with iOS Devices and Emulators;Charles. iOS Getting Started.
[14] CSDN / 技术博客. 使用 Charles 抓取 HTTPS 数据及原理分析(中间人、证书链).
[15] 掘金. charles 前端应用. juejin.cn/post/684490… Remote、Map Local 实战).
[16] 掘金. HTTPS 与 Charles为了学会 Charles,我拼命了. juejin.cn/post/684490… 握手与 Charles 证书替换、按地址启用 SSL Proxying).
[17] HarmonyOS 网络抓包与 Charles 代理证书配置(代理 + chls.pro/ssl + 证书信任);华为开发者文档 @ohos.net.http(API 10+ 代理与证书参数).

其它参考

❌