Vibecoding 进阶教程总集篇——从能用到可控
- 内容介绍
- 文章标签
- 相关推荐
Vibecoding 进阶教程总集篇——从能用到可控
Vibecoding 系列教程第二部分进阶篇完整版,包含原进阶(一)(二)(三)全部内容。适合想一口气看完的佬
- 基础篇(环境搭建 + 基础闭环):Vibecoding基础教程
GitHub - 1EchA/how-to-vibecoding: Vibecoding 系列教程:从环境搭建到多智能体协作,涵盖 MCP、Skills、Agent...
Vibecoding 系列教程:从环境搭建到多智能体协作,涵盖 MCP、Skills、Agent 分工治理
下一篇帖子发布的时候我随着抽10个team无质保车位
感谢佬们一直以来的支持
目录总览
本篇共 8 个任务,分为三大模块:
模块一:MCP + Skills(原进阶篇一)
- 任务 1:MCP 入门——先接入安全的工具试试
- 任务 2:实现一个 MCP Server
- 任务 3:Skills 流程卡片
模块二:多智能体 + 长任务治理(原进阶篇二)
- 任务 4:多智能体分权
- 任务 5:长任务治理 ULW 循环
模块三:安全、评测与流水线(原进阶篇三)
- 任务 6:安全加固
- 任务 7:评测与可观测
- 任务 8:团队协作与流水线
模块一:MCP + Skills——让 coding agent 有自己的工具
写在前面
上一篇我们搞定了开发环境、对很多概念都已经有了一个基础的了解。
但你可能已经发现了一个问题:AI 只能看到你在输入框里告诉他的信息,该怎么让它自己去检索项目代码?怎么让它按固定格式交付修 Bug 的证据?怎么给它接上它可以调用的工具呢?这些就是这一篇想要解决的问题。
本篇包含 3 个任务:
- 任务 1:MCP 入门——先接入只读工具试一试
- 任务 2:亲手实现一个 MCP Server——自己动手丰衣足食
- 任务 3:Skills 固化——把"修 Bug"变成可复用的标准流程卡片
术语介绍在这
- MCP(Model Context Protocol):一个标准的"工具插槽"协议,让 AI 客户端能统一发现和调用外部工具。
- STDIO:MCP 最常见的本地传输方式,通过进程的标准输入输出通信。(不要往 stdout 写日志。)
- schema:工具的输入和输出格式。越明确、越规范,你的工作流就越稳定。
- Skills:把高频的业务动作固化成"流程卡片",让 AI 每次都按同一套流程做并产出交付。
任务 1:MCP 入门:先接入安全的工具试试
目标:把一个 MCP 工具接进来,先简单感受一下mcp。
如果你对 MCP(Model Context Protocol)还不熟悉,可以把它理解成一个 “标准的工具插槽”。以前你得往提示词里写很多上下文;现在只要用统一的协议把外部工具接进来,你的客户端(CLI、IDE、Agent )就能用同一套约定去发现工具、调用能力。
补充说明:
MCP 不只是"调用工具"。它定义了三种能力:
- Tools(工具):AI 可以主动调用的函数,比如搜索代码、读文件。
- Resources(资源):只读的上下文数据源,比如项目文件列表、数据库 schema。AI 可以读取但不能修改。
- Prompts(提示词模板):预设的交互模板,比如代码审查流程。
本篇主要聚焦在Tools,但理解这三者的区别有助于佬友们后面设计更完善的工具链。
1.1 挑一个没什么改动风险的 MCP 工具
这一部分我推荐大家选只读的工具。比如:
- 只提供读取权限的文件系统接口(Filesystem)
- 查文档用的检索工具(比如 context7)
这两个工具都比较老牌并且用的比较多,大家可以根据自己的情况选择。
1.2 把工具接到你的开发环境(CLI/IDE)
我目前最喜欢的使用方法就是用antigravity(ultra)右边是agent窗口,然后开一个终端在下面,然后也分享一个小技巧,如果想一个项目开多个窗口的话可以存一个工作区,这样就可以左右开弓了。
mcp底层原理都一样:读mcp配置后,帮你在后台起一个进程,本质就是执行 command + args。
下面直接给出上面提到的两个工具的mcpserver配置:
这步其实可以直接告诉你使用的coding agent我要配置什么mcp就可以了,然后有的mcp需要你自己去到对应的网站上注册然后拿一个key,拿到之后再给你的coding agent来配置就可以了
Filesystem(只读文件系统):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/ABSOLUTE/PATH/TO/YOUR/PROJECT"]
}
}
}
注意把路径换成你项目的绝对路径。这个工具只给 AI 读取指定目录的能力,不会写文件。
context7(文档检索):
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@latest"]
}
}
}
context7 可以帮 AI 直接查阅各种开源库的最新文档,不用你手动复制粘贴。
验证标准:
可以直接让你的coding agent检查mcp启用状态,或者用命令来看,mcp list或者/mcp之类的指令,可以根据你自己用的coding agent的文档来查一下怎么看mcp的启动状态,ccswitch也是一个不错的mcp管理工具。
image2008×1000 103 KB
- mcp list 之后工具名能看到,你可以手动指定去调用它。
- 就算读取失败了,也能在终端日志里看到具体报错,对得上路径和参数。
延伸阅读:
如果你对 MCP 的概念还比较模糊,建议先看一遍官方介绍,搞清楚 Tools、Resources、Prompts 这三者的区别,然后跟着 Server Quickstart 走一遍,感受一下客户端和工具之间怎么配合的。
- MCP Introduction — What is the Model Context Protocol (MCP)? - Model Context Protocol
- MCP Quickstart: Build a server — Build an MCP server - Model Context Protocol
- MCP 推荐 ——
https://www.bilibili.com/video/BV1ZJsBznEt3/?spm_id_from=333.337.search-card.all.click
任务 2:实现一个 MCP server
这部分我们的目标是从零写一个最小可用的 MCP server,然后把它注册到你的开发环境里。
这一步的意义不在于写出一个 Hello World 工具,而是自己动手实践搭了一个可复制的模板。以后想让 AI 检索公司的 Jira、内部日志或者发版系统,该怎么起步、怎么验证、怎么排错心里就有数了。
这部分演示一条按官方思路、跨平台兼容且确保能跑通的轻量路径。
2.1 环境准备(Python + uv)
官方建议 Python 3.10 以上,搭配最新的 MCP SDK。客户端拉起你的 Server 时,需要找到你配好的那个 Python 解释器。
2.2 STDIO 日志别用 stdout
为什么?因为 MCP 用 STDIO 模式通信时,stdout 是专门给协议消息走的通道。你往里面混了别的东西(比如一句 print("hello")),客户端收到的 JSON 就乱了,可能会导致直接断连。
用代码来说就是这样:
错误写法(会导致连接断开):
print("Server 启动中...") # 这行会写到 stdout,把协议搞坏
正确写法(日志走 stderr,不影响协议):
import sys
print("Server 启动中...", file=sys.stderr) # 日志走 stderr,协议不受影响
Node.js 也一样:用 console.error(...) 代替 console.log(...)。
简单记住一条规则就行:
stdout→ 只给 MCP 协议用,你的代码里不要往这里写任何东西stderr→ 你的调试日志全走这边
所以碰到连接断开就可以排查一下是不是写错了
2.3 建一个干净的项目
找一个你放 Demo 的文件夹:
uv init code-search
cd code-search
uv venv
激活虚拟环境(挑你用的终端):
# macOS/Linux
source .venv/bin/activate
# Windows PowerShell
.venv\Scripts\Activate.ps1
# Windows cmd
.venv\Scripts\activate.bat
装上 SDK 依赖:
uv add "mcp[cli]"
image-11490×1270 125 KB
创建脚本文件:
# macOS/Linux/WSL
touch code_search_server.py
# Windows PowerShell
ni code_search_server.py
# 你也可以用 Python 方式创建
python -c "open('code_search_server.py','w').close()"
验证:
uv --version能正常返回。- 激活环境后
python -V是你预期的版本。 python -c "import mcp"不报错。
2.4 写一个只读的检索工具(rg / ast-grep)
与其写一个只会返回 Hello 的玩具,不如直接上手写一个好用的纯读取检索工具:用 rg 做文本搜索,或者用 ast-grep 做语法树级别的代码检索。
前置准备:
- 全局安装
rg(ripgrep) - (可选,但建议体验)全局安装
ast-grep
把下面这段代码存到 code_search_server.py 里:
import os
import shutil
import subprocess
import sys
from pathlib import Path
from typing import Any, Optional
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("code-search")
# 确保 Homebrew / Linuxbrew 等常见路径在 PATH 里
# (uv run 的子进程可能丢失这些路径,导致 rg 找不到)
_EXTRA_PATHS = ["/opt/homebrew/bin", "/usr/local/bin", "/home/linuxbrew/.linuxbrew/bin"]
_ENV = os.environ.copy()
_ENV["PATH"] = os.pathsep.join(_EXTRA_PATHS + [_ENV.get("PATH", "")])
def _find_bin(name: str) -> str:
"""查找可执行文件的绝对路径,找不到就原样返回让后面报 FileNotFoundError。"""
return shutil.which(name, path=_ENV["PATH"]) or name
def _run(cmd: list[str], cwd: str, timeout_s: int = 30) -> tuple[int, str, str]:
"""安全地执行子进程,带超时保护。"""
p = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=timeout_s,
shell=False,
cwd=cwd,
env=_ENV,
stdin=subprocess.DEVNULL, # 防止子进程继承 MCP 的 stdin 管道
)
return p.returncode, p.stdout, p.stderr
@mcp.tool()
def rg_search(target_dir: str, query: str, globs: Optional[list[str]] = None, max_lines: int = 200) -> dict[str, Any]:
"""用 ripgrep 搜索文本,返回结构化结果。"""
if not target_dir.strip():
return {"ok": False, "error": "target_dir required"}
if not Path(target_dir).is_dir():
return {"ok": False, "error": "target_dir not a directory"}
if not query.strip():
return {"ok": False, "error": "empty query"}
# 注意:--glob 必须放在 "--" 之前,"--" 之后的参数会被当作搜索词和路径
cmd = [_find_bin("rg"), "--line-number", "--no-heading", "--color", "never"]
for g in (globs or []):
cmd += ["--glob", g]
cmd += ["--", query, "."]
try:
code, out, err = _run(cmd, cwd=target_dir)
except FileNotFoundError:
return {"ok": False, "error": "rg not installed"}
except subprocess.TimeoutExpired:
return {"ok": False, "error": "rg timeout"}
# rg 退出码:0=有匹配, 1=无匹配, 2=出错
if code == 2:
print(err.strip(), file=sys.stderr)
return {"ok": False, "error": "rg error", "details": err.strip()}
lines = [ln for ln in out.splitlines() if ln.strip()]
if len(lines) > max_lines:
lines = lines[:max_lines] + ["... truncated ..."]
return {"ok": True, "matches": lines, "rc": code}
@mcp.tool()
def ast_search(target_dir: str, pattern: str, lang: str, globs: Optional[list[str]] = None, max_lines: int = 200) -> dict[str, Any]:
"""AST 级别的代码搜索,需要本地安装 ast-grep。"""
if not target_dir.strip():
return {"ok": False, "error": "target_dir required"}
if not Path(target_dir).is_dir():
return {"ok": False, "error": "target_dir not a directory"}
if not pattern.strip() or not lang.strip():
return {"ok": False, "error": "pattern/lang required"}
if not lang.isalnum():
return {"ok": False, "error": "invalid lang"}
cmd = [_find_bin("ast-grep"), "run", "--pattern", pattern, "--lang", lang]
for g in (globs or []):
cmd += ["--globs", g]
cmd += ["."]
try:
code, out, err = _run(cmd, cwd=target_dir)
except FileNotFoundError:
return {"ok": False, "error": "ast-grep not installed"}
except subprocess.TimeoutExpired:
return {"ok": False, "error": "ast-grep timeout"}
if code != 0:
print(err.strip(), file=sys.stderr)
return {"ok": False, "error": "ast-grep error", "details": err.strip()}
lines = [ln for ln in out.splitlines() if ln.strip()]
if len(lines) > max_lines:
lines = lines[:max_lines] + ["... truncated ..."]
return {"ok": True, "matches": lines}
if __name__ == "__main__":
mcp.run(transport="stdio")
划重点:
- 纯读取,只负责找东西,不会动你的文件。
- 输入输出很规整,方便大模型解析,也方便后面做审查和重构。
- 调试日志只走
stderr,不污染 stdout。 - 两个工具都捕获了
FileNotFoundError,如果系统没装rg或ast-grep,会返错误而不是崩溃。
2.5 先用终端看看活了没有
uv run code_search_server.py
跑起来之后终端会挂住而没有任何输出,这说明它正在等客户端发指令过来,而不是寄了。
2.6 对接客户端
Server 跑通之后,可以告诉你的 coding agent:“我本地有一个 MCP server,你去给我连接上。”
第一步:找到你工具的 MCP 配置文件
不同工具的配置文件位置不一样,这里我举一下反重力和codex的例子,如果是直接配置到cc/codex这种,就直接在配置文件里面改,codex在toml,cc在json,也可以直接在ccswitch里面管理或者改配置:
| 工具 | 配置文件位置 |
|---|---|
| Antigravity | ~/.gemini/antigravity/mcp_config.json |
| Codex | ~/.codex/config.toml |
第二步:把配置写进去
打开对应的配置文件,把下面的配置加进去(注意把路径换成你自己的):
Antigravity / Cursor / Claude Desktop(JSON 格式):
{
"mcpServers": {
"code-search": {
"command": "uv",
"args": [
"--directory",
"/你的绝对路径/code-search",
"run",
"code_search_server.py"
]
}
}
}
Codex(TOML 格式,加到 ~/.codex/config.toml 末尾):
[mcp_servers.code-search]
type = "stdio"
command = "uv"
args = ["--directory", "/你的绝对路径/code-search", "run", "code_search_server.py"]
第三步:重启你的 coding agent,验证连接
重启之后,用你工具里的 MCP 检查命令看一下 code-search 是不是已经连上了。然后试着让 AI 调用一下,比如跟它说:“用 rg_search 在我的项目目录里搜一下 TODO”,看看它能不能正常返回结果。
Tips:
- 路径必须是绝对路径,不能用
~或相对路径。- Windows 用户请用
where uv把command的完整路径填上。- 如果连不上,先在终端手动跑一遍
uv --directory /你的路径/code-search run code_search_server.py,能跑通说明配置没问题,问题出在 agent 那边。
示例:codex /mcp检查链接
image1458×366 23.7 KB
示例:codex 调用测试
image2028×838 114 KB
延伸阅读:
如果打算把 MCP 长期用下去,建议抽空看一遍 Python 和 TypeScript 两个 SDK 的 README,搞清楚 SDK 的生命周期、安全策略和进阶配置。
image711×170 21.2 KB
任务 3:Skills,制作流程卡片,减少重复工作
不管模型多强,它的发挥总是有波动,有可能不是降智,只是佬的提示词没有上一次写的用心或者这次有点不耐烦了,所以把流程写死,让它按照格式交付。 通过写好流程规范来提高模型输出的稳定性。
3.1 减少重复提示词工作
不把流程固化(Skills)很快就会陷入这种循环:
- 每次都得重新解释"你该怎么查日志"、“怎么证明你修好了”、“别忘了补回归测试”。
- AI 每次给你的输出格式都不一样,有时候连它自己上一步说了啥都忘了。
Skills 的价值就是把这些正确做法固定下来,一次梳理,长期复用。
3.2 写一张修bug的流程卡(模板见本文末尾附录)
一张合格的卡片,至少覆盖这几个方面:
- 输入要求:Bug的现象、关键报错日志、重现步骤、可能涉及的文件路径。
- 输出交付:最小化复现代码、修复 diff、跑通的验证输出,以及回归测试(有条件的话)。
- 失败预案:信息不够或者死活查不出来怎么办(比如:让coding agent列一份"需要我补充的信息清单",而不是让他闷头苦干,最后活没干好账单还要你结)。
建议:
别凭空想象理想流程。回忆一下你最近真实碰到过的几个恶心 Bug,从实战经验里总结张卡片,我觉得时刻有这个思想是好事,每次跟觉和coding agent协作效率比较高的时候回看一下你们的沟通过程以及工作流程,和coding agent一起写一张skill,把这份高效的模式留存下来方便后面复用。
3.3 Skills卡放在哪?怎么让 AI 每次自动加载?
写出来的卡片不能只是一段复制粘贴的文本,它需要一个稳定的位置:
- 推荐做法:存为独立文件(如
skills/bugfix.md),然后在AGENTS.md中引用它:请在每次排障时,严格遵循 skills/bugfix.md 中定义的流程卡片。 - 次选做法:直接写在
AGENTS.md的对应章节里,方便 AI 工具自动读取。(真的是次选,直接写在这会加很多input token
不同工具的引用机制不同,但是ccswitch依旧有一套管理系统(歌颂ccs
image-71954×1214 179 KB
3.4 像验收外包一样,强制coding agent按卡片交付
跟它沟通时,直接规定好他需要交付的内容:
请你严格按照以下清单进行交付,并且每一项都必须附上证明:
1) 提取出最小规模的复现逻辑(提供可执行的命令或步骤)。
2) 确诊根因所在(必须引用具体的代码行号或日志证据)。
3) 提出修复方案,并解释你为什么要这样改。
4) 给出修复后的对比 diff。
5) 执行自动化测试并直接贴上输出日志。
6) 补充一段回归测试代码(如果客观上没法写,请写明技术原因)。
什么时候可以确定这是一张可以复用且质量不错的卡?
- AI 回答的结构稳定了,不再东拉西扯。
- 这张卡片在不同的排障场景下都能套用。
- 你能一眼扫出它有没有漏掉哪一步。
用词就该是"必须交付的硬性证据",而不是"建议"或者"最好",这样才能保证输出质量。
在这里推荐一个skills集合网站:https://skillsmp.com/zh
延伸阅读:
如果你想了解"卡片"这套理念是怎么被做成通用标准的,可以看看 Anthropic 团队的思路和 Agent Skills Standard。
附录:修 bug 的 Skills 卡片模板
image587×333 19.6 KB
模块二:多智能体 + 长任务治理——拒绝 coding agent 既当裁判又当运动员
让同一个 AI 既写代码又审代码,它往往对自己写的 Bug 视而不见。本模块解决两件事:多智能体分权(任务 4)和长任务治理(任务 5)。
能并行的只读工作就并行。能分权的执行审查任务就分权。每个环节都要交证据,而不是听你的cc告诉你已经到达了“顶会level”
任务 4:多智能体:不让你的coding agent既当运动员又当裁判
目标:把"写代码"和"审查代码"拆给不同的角色
推荐两种做法:
-
比较简单的实现方法:你来当调度员,把 Scout、Builder、Verifier 的输出按固定格式手动传递。具体操作:在 Chat A 中以 Scout 身份让 AI 搜索,复制它的输出 JSON,再在 Chat B 中以 Builder 身份粘贴进去开始实现,最后在 Chat C 中以 Verifier 身份审查。
-
比较进阶高效的方法:用脚本或工作流引擎做自动编排。本文末尾附录 C 给了一个比较小的参考骨架。
从单 Agent 到多 Agent 的拐点:
你可能会问——“我用一个 coding agent 加上 Skills 卡片不就够了吗?” 我的回答是:如果这个任务节点比较少并且简单你的思路是没问题的,但是如果任务比较复杂的话,让同一个 Agent 既写实现又审代码,它往往对自己写的 Bug 视而不见。就像你让同一个人写代码又做 Code Review,这种模式的效果注定是不好的。把"写"和"审"拆给不同角色才能够提高质量,维持每一次决策的可靠性。
ps:最简单的方法就是你开一个codex再开一个claudecode,让claudecode出plan,然后给codex做check,没问题了之后让claude开始工作,然后拿工作结果给codex做double check,这种方法简单高效又好用。
1.1 核心分工(这里拿三个来举例子)
-
Scout:只找线索,不改代码。
-
Builder:只做实现,按约束最小改动。
-
Verifier:只做审查,负责找问题和跑验证。
只要职责不重叠或混合,稳定性就会上一个台阶。
1.2 一套用来参考的提示词约束模版
下面这三段约束,重点在于如何把输入、输出、禁止事项写的清楚。
Scout
你当前的角色是 Scout。你只负责收集证据,不允许改代码。
你必须交付:
1) 直接相关的文件路径清单,按重要性排序。
2) 仓库中相似实现或现有模式,尽量精确到函数、类、模块。
3) 你判断出的约束条件:构建、平台、安全、依赖、权限。
4) 你建议的最小改动范围。
禁止事项:
- 不写代码草案
- 不提出大范围重构
- 不替 Builder 做实现决策
Builder:
你当前的角色是 Builder。你的原则是:改动的时候尽量保持最小改动。
你不可违背的红线:
1) 动手之前,先亮出你需要跑的 3-7 步执行计划和验证预期。
2) 编码结束后交出 diff。
3) 提供实际执行过的测试、构建或验证输出。
4) 如果碰到了必须要加新库或者要一次动超过 5 个文件,停下来,先给我解释清楚非改不可的原因。
5) 你的修改方案应当竭尽所能做到"幂等"。无论跑几次都不该搞出重复追加、文本反复插入导致的破相。
6) 不要过分迷信 unified diff 的通用性:如果工具执行失败,立刻切换降维方案——给出"整个函数/模块的完整替换"或采用"查找且批量替换"式的方案协助落盘。
Verifier:
你当前的角色是 Verifier。你不负责写实现,你只负责审查和验收。
你必须交付:
1) 按严重程度排序的风险清单。
2) 决策没覆盖到的测试点和边界条件。
3) 基于 diff 的逐项审查结论。
4) 最低成本的补救建议。
你的判断必须基于:
- diff
- 实际执行结果
- 测试覆盖情况
- 已知约束条件
禁止事项:
- 凭感觉输出
- 在没有验证结果时宣称"应该没问题"
- 越过风险直接建议合并
最小流转路径:
-
scout.pass -> builder -
builder.pass -> verifier -
verifier.fail -> builder(打回原因直接发还给 Builder) -
needs-human→ 交给你来仲裁。
这么做最大的好处是:不管你以后换什么框架(LangGraph、AutoGen / AG2、原生 SDK),甚至手动复制粘贴排障的链路都是熟悉且清楚的。
1.2.1 大仓库的上下文管理:别让模型把你仓库全读一遍
真实项目里最常翻车的原因不是模型写不出代码而是无关信息太多,把上下文窗口塞爆了,这不仅对项目上下文不友好,对你的钱包也不太友好。
可以参考的底线策略:
-
用
rg先快速锁定一小批候选文件(按报错名或接口名来搜)。 -
再用 AST 级别的工具(IDE 的 Go to Definition 或
ast-grep)精确定位函数调用链。 -
喂给 Builder 时,只给裁剪后的代码片段 + 必要上下文 + 报错信息,避免填入多余噪声。
image719×149 14.8 KB
如果你的库很硕大:
-
第一轮: 只侦察,摸清模块和接口,不写代码。
-
第二轮: 做最小化修复。
-
第三轮: 跑全量验证,抓漏掉的边界。
或者在代码库中做一个目录索引,避免模型真的一个一个代码去读,由索引先提供给模型一个候选区域而不是让它瞎猜。
当Verifier 能准确指出 Builder 的遗漏,而且最终代码确实比第一版更稳的时候就起效果了。
多智能体协作不是"给几个机器人喂同样的 Prompt 让它们抢答"。核心在于:职责分离 + 信息隔离
延伸阅读:
想深入了解多 Agent 协作的设计思路:
image707×311 32.1 KB
任务 5:长任务治理:ULW 循环式推进
不管是用单 Agent 还是多智能体,只要任务开始跨越多个步骤和文件都可以使用这套方法
做过长周期复杂任务的佬都知道,最要命的不是Coding agent无从下手,Coding agent不会无从下手,怕的是它到处下手,越做越发散,屎山越来越高,最后甚至找不到一个能回滚的位置。
ULW(循环式推进 / Ultrawork)不是让 AI 无限循环。它的核心是:把大任务切成一段段可以验收的小结果,每段都有明确的目标、证据、可回滚的存档点和一键喊停的开关。
ulw我觉得omo做的很好
GitHub - code-yeongyu/oh-my-openagent: omo; the best agent harness - previously...
omo; the best agent harness - previously oh-my-opencode
感兴趣的佬可以试一试
你也可以直接把这份约定喂给你的coding agent:
你现在接手的任务按"循环推进"制度,规则如下:
1) 每轮只盯一个改动点,动手前先说清楚验证标准。
2) 每轮结束必须交证据:改动概要 + diff + 通过验证的日志。
3) 硬性上限:最多试 N 轮或花 T 分钟。超了就停下汇报,不许硬撑。
4) 碰到红线(拉大依赖、改大批文件、完全查不出原因的报错),立刻停手汇报。
5) 高危操作(删库、改根目录配置等)必须等我批准。
6) 交接时自己精简上下文:只把"做了什么、结论是什么"压缩成 3 句话带到下一轮,不许把大段日志原封不动搬过去。
当能够随时抽查它,它能说出"现在第几轮、这轮修什么、成功标准是什么",而且能退回到上一轮的存档点,就算有效果了
参考:
image710×221 22.9 KB
附录 C:现在怎么做多智能体—时代变了,现在已经不用自己写调度代码了
任务 1 里讲的 Scout/Builder/Verifier 分工,现在主流工具已经内置了不同程度的支持。你不需要很麻烦的自己写,很多主流工具你写一段提示词存起来在需要的时候用自然语言调用一下就可以了。
C.1 最简单:AGENTS.md 分角色
把角色约束写进 AGENTS.md,工具启动时自动加载,对所有对话生效。
## 角色约束
当前角色:Builder
- 职责:只做实现,最小改动
- 禁止:自行修改测试基线、重构无关代码
- 交付:diff + 通过验证的输出
当前角色:Verifier
- 职责:只做审查,不写实现
- 必须交付:风险清单、未覆盖边界、逐条 diff 结论
- 禁止:在没有验证结果时宣称"应该没问题"
支持 AGENTS.md 的工具:Codex、Claude Code 等。
C.2 Codex 并行 Agent(worktree 模式)
Codex 原生支持同时跑多个 Agent,每个 Agent 在独立的 git worktree 里工作,互不干扰、不产生合并冲突。
实际用法:
-
打开 Codex,发起一个任务
-
点击"创建新的工作分支",可以同时跑多个互不影响的子任务
-
Codex 自动管理 worktree 隔离,你只需要审查每个 Agent 的 diff
比较适合同一个 feature 里,UI 改动和 API 改动可以并行交给两个 Agent 分别做。
参考文档:https://openai.com/codex
C.3 Claude Code 子智能体(subagent)
Claude Code 支持在一个主 Agent 里,通过 Task tool 发起并行子任务。主 Agent 做 Scout 和调度,子 Agent 做 Builder 或局部验证。
小示例:在 Claude Code 的对话里直接跟它说:
你现在作为 Scout,先把相关代码范围摸清楚,
然后启动两个子 Agent 分别实现方案 A 和方案 B,
最后你来对比两个结果选出更好的。
Claude Code 会自动调用 Task tool 并行跑子任务,你只需要最后审查主 Agent 给你的汇总。
参考文档:https://www.anthropic.com/engineering/multi-agent-research-system
C.4 :LangGraph 图编排(需要写代码)
如果你的团队需要把多 Agent 流程做成自动化 pipeline(比如接进 CI/CD),可以用 LangGraph 做图调度。核心结构是:
START → scout → builder → verifier → [pass: END | fail: summarize → builder]
用 summarize 节点在每次打回时裁剪上下文,避免 Builder 重试时带着一堆没用的历史日志。
官方文档:Redirecting to LangGraph Documentation
模块三:安全、评测与流水线
本模块解决最后三个问题:安全加固(任务 6)、评测与可观测(任务 7)、团队协作与流水线(任务 8)。
任务 6:安全加固——第三方 MCP 不只是普通插件,更代表着权限
目标:建立一套接入前的安全审查习惯。不管是用别人的 MCP server 还是自己开发,都要先排查一下隐患。
你把第三方 MCP 接到你的开发环境里,本质上就是给了一个外部程序跟你一样的系统权限。它能碰到的网络、文件系统,基本等于你能碰到的,这是很夸张的。
1.1 接入前需要考虑的 7 个问题
- 读写边界:它到底需要读什么,需不需要写权限。
- 权限范围:默认权限是不是给太大了,能不能把权限缩到最小目录。
- 网络行为:它在工作时会访问哪些网络,请求会发到哪些域名。
- 敏感距离:它离你的环境变量、数据库凭据留有多少距离。
- 审计日志:它跑的时候,有没有留下可追溯的日志。
- 重试风险:超时或报错后的重试,会不会产生副作用。
- 供应链:作者靠谱吗,是长期维护的项目还是可能有后门随时有跑路风险的项目。
1.2 给已接入的 MCP 做一次安全审查
可以拿出我们之前做好的 MCP 出来,也可以拿一个比较常用的 MCP 来进行一次审查。
MCP 审查表
Server 名称:
1. 读写边界:只读/读写
2. 权限范围:已限制到子目录/全盘访问
3. 网络行为:网络请求流向
4. 敏感距离:无法访问 .env/数据库/可访问
5. 审计日志:有日志/无
6. 重试风险:操作幂等/有副作用风险
7. 供应链:官方/知名维护者/个人项目
1.3 需要确认的底线
- 最小权限:只给特定子目录的访问,只开必要的端口。
- 写入限制:如果必须能写文件,至少限制在
src或tmp下,避免碰到配置文件。 - 可追溯:最起码你得能看到它调了什么、改了哪几行。
- 重试克制:别让重试变成死循环。
1.4 用 HTTP MCP 时的安全注意事项
大部分人用的是本地 STDIO 模式(就是在 config 里配 command + args 那种),这种模式 MCP 跑在你自己机器上,安全风险相对可控。
但如果你用的是 HTTP 模式(MCP Server 在远程通过网络调用),那安全要求就会变高,这里说几个推荐大家注意的点:
- 认证:必须用 OAuth 做身份验证,裸跑的 HTTP MCP 等于把开发环境暴露在公网上。
- Token:API Token 只能放在请求的 Header 里(
Authorization: Bearer xxx),不要拼在 URL 后面,URL 会被日志和浏览器历史记录泄露。 - 回调:OAuth 回调只允许
localhost或https://开头的地址,防止 Token 被中间人截获。
image713×270 36.3 KB
任务 7:评测与可观测——不再凭直觉对项目进行迭代
这部分主要为了回答一个问题:“改了工作流换了模型之后,效果到底是真的变好了,还是运气呢?”
没有认真的评测量化,日常开发最容易陷入这种情况:
- 今天一切顺利:“天才程序员诞生了”
- 明天觉得模型降智:“天才程序员陨落”
其实多半是上下文膨胀了、工具链卡了、或者纯粹运气不好。我们需要一些量化后的证据来看看到底是为什么。
2.1 自己做一套回归测试集
跑和自己业务项目关系不大的 Benchmark 意义不大,有时间的话自己搭一套质检题库是个不错的选择:
- 3 个有代表性的 Bugfix
- 3 次 Feature 增量
- 2 次重构
- 2 次补核心链路测试
每道题需要写清楚的是:
- 输入:原始任务描述。
- 预期:通过条件。
- 验证:验证命令。
存成 JSONL,方便即拿即用(附录 A 有最小 Schema)
2.2 先用最朴实无华的方式做 Tracing
用 JSONL 把每次操作录下来:
trace_id(任务标识)- 操作时间
- 调用的 Tool 名
- 输入摘要(注意脱敏,去掉 API Key、密码等)
- 输出摘要
- 耗时
- 报错信息
有了这种记录表,才方便在问题出现的时候,快速定位问题到底在哪。
建议:
每条日志一定要带trace_id。一旦多个 Agent 并行跑或者长任务反复重试,没有 trace_id 的日志直接就乱套了,根本分不清上下游。
2.3 往标准化靠拢
如果打算把这套推给团队用,建议字段命名向 OpenTelemetry (OTel) 的 GenAI semconv 标准看齐。哪怕现在没接 OTel 的全套体系也可以先统一命名,以后迁移成本就会降低很多。
参考:OpenTelemetry GenAI Semantic Conventions — Semantic conventions for generative AI systems | OpenTelemetry
2.4 进阶:从日志到可视化看板
纯看 JSONL 几十次调用确实难受。可以考虑加一层可视化:
- 底层还是存 JSONL(这是保底的原始日志)。
- 上面接一个可视化平台(Langfuse / Phoenix / LangSmith……)。
- 需要注意的有 4 个关键指标:
- 各类任务的通过率
- 单次 Bug 修复的端到端耗时
- 每个环节的 Token 消耗
- 失败时卡在哪一环
之后就可以比较方便地拉出某次失败任务的完整链路了。
改完prompt后也可以用数据来对比前后的通过率和耗时差异。
延伸阅读:
想深入了解评测和追踪的实践:
- Inspect AI (UK AISI) docs — https://inspect.aisi.org.uk/
任务 8:团队协作与流水线
第一次让两个 Agent 同时去修同一个文件的人,通常会收获一份完美的合并冲突。
本节适用于有 CI/CD 环境、多人协作的团队项目。如果你目前是单人本地开发,可以直接跳过。
3.1 沙盒(Sandbox)
有一个现实是必须接受的:幻觉导致的抽风瞎写发散是不可能完全消除的。所以我们能做的就是考虑怎么降低在幻觉出现时可能造成的负面影响。
做法:
- 所有试运行、构建、测试都扔到无状态容器或临时沙盒里跑。
- 只有测试全部通过之后,才允许把 diff 补丁合回主干。
- 高危操作(删包、重建根目录、大规模推改)要求 coding agent 申请人工审批。
3.2 固定流水线中的关卡
这里面举三个例子:
- 静态检查:lint + 类型检查,语法级别的低级错误直接拦掉。
- 业务逻辑:跑一遍本次改动涉及的单测或集成测试,确认功能没被改坏。
- 安全扫描:有没有硬编码密钥、有没有引入高危依赖,发现了就打断。
如果有关卡没过就退回重来。
对修复主导权本篇也给出两套参考方案:
- 让 CI job 本身带修复能力,跑挂了直接读 stderr 开始纠错循环,修好了打一个 patch commit。
- CI 只负责跑测试和报告结果,出了问题通过 Webhook 把错误现场发给远端的 Agent 服务,Agent 打好补丁后 Push 分支等人来审。
3.3 多 Agent 并发时的保护机制
如果你有多个 Agent 同时干活需要注意这两个问题:
- 同一时刻只允许一个 Builder 有写权限,其他角色(Scout / Verifier)在同一时刻只读。
- 写入前必须同步最新的上游状态,避免两个 Agent 各写各的然后互相覆盖。
常见的实现方式:
- 文件锁:在写入和跑测试的入口用
flock之类的工具加锁,另一个 Agent 过来发现被占了就直接排队或报错。 - Git 保护:每次写入前强制
git pull --rebase,有冲突就中断当前轮次。
如果你用的是 Codex 的 worktree 模式,它已经帮你做了隔离,每个 Agent 在独立的 worktree 里工作,基本不会冲突。这节主要是给自己搭框架的团队看的。
延伸阅读:
- Codex Security(沙箱 / 审批 / 网络策略)— Codex Security
- Dagger Docs(容器化可复现流水线)— https://docs.dagger.io/
- The Harness Problem — I Improved 15 LLMs at Coding in One Afternoon. Only the Harness Changed. | Can.ac
附录 A:模版案例参考
A.1 项目规则模板(放在根目录的 AGENTS.md)
image686×311 19 KB
A.2 需求描述模板
image685×341 14.1 KB
A.3 MCP Server 开发 checklist(STDIO 模式)
- 不要在 stdout 写日志(调试信息走 stderr)。
- 先在本地跑通,再对接远端或外部 API。
- 每个 tool 都要定义清楚:入参类型、返回结构、错误处理、超时限制。
- 明确读写范围:它能触及的目录有哪些,是否有被限制在子目录中。
- 写操作尽量做到多次调用不产生副作用。
A.4 HTTP MCP 的授权 checklist
- 通讯走 HTTPS
- redirect URI 严格校验
- Token 走 Authorization header(不放 query string)
- 配置 PKCE
- 按标准走 metadata discovery(
.well-known/oauth-authorization-server)
A.5 多智能体角色模板
见前一篇
Vibecoding进阶教程-从能用到可控(二):拒绝coding agent既当裁判又当运动员
A.6 评测回归库的 JSONL 模板
记录好输入和验收标准
{"id":"bugfix-001","title":"修复计算模块的单测崩溃","input":"...","acceptance":["npm test 全部通过"],"verify":["npm test"],"tags":["bugfix","tests"]}
A.7 Tracing 的 JSONL 模板
每条带时间戳、耗时和 trace_id
{"trace_id":"bugfix-123-run-1","ts":"2026-03-03T10:00:00Z","tool":"bash","input_summary":"npm test","output_summary":"passed","duration_ms":12345,"error":null}
附录 B:延伸阅读与官方参考资料
image704×690 91.4 KB
image735×784 102 KB
image722×570 72.6 KB
image736×463 58 KB
网友解答:--【壹】--:
收到,感谢佬的建议,最近也有想做这个的想法
--【贰】--:
感谢佬友分享,我怎么好像昨天见过?穿越了吗
--【叁】--:
前排支持!
--【肆】--:
前来支持
--【伍】--:
感谢喵佬又来捧场了
--【陆】--:
mark就完事了,感谢佬友的分享
--【柒】--:
先赞后看,感谢大佬
--【捌】--:
先赞后看,感谢大佬~
--【玖】--:
重新整理优化了一遍总集篇
--【拾】--:
太良心了bro,这玩意在外头我看至少值999
--【拾壹】--:
先赞后看
--【拾贰】--:
先赞后看,给力
--【拾叁】--:
感谢佬辛苦整理!
--【拾肆】--:
感谢整理汇总,非常有用
--【拾伍】--:
太牛逼了
--【拾陆】--:
狠狠收藏了,感谢大佬码字分享~
--【拾柒】--:
太良心了 必须收藏住
--【拾捌】--:
建议增加上下文控制的部分
MCP SKILLS用多了也会增加上下文开销
控制上下文不仅是为了节省tokens 也能增强模型专注力
1m上下文并不意味着1m空间内专注力都是一致的 所以还是要学会控制上下文 尽可能的在专注力空间内解决问题
--【拾玖】--:
感谢佬,标记一下
Vibecoding 进阶教程总集篇——从能用到可控
Vibecoding 系列教程第二部分进阶篇完整版,包含原进阶(一)(二)(三)全部内容。适合想一口气看完的佬
- 基础篇(环境搭建 + 基础闭环):Vibecoding基础教程
GitHub - 1EchA/how-to-vibecoding: Vibecoding 系列教程:从环境搭建到多智能体协作,涵盖 MCP、Skills、Agent...
Vibecoding 系列教程:从环境搭建到多智能体协作,涵盖 MCP、Skills、Agent 分工治理
下一篇帖子发布的时候我随着抽10个team无质保车位
感谢佬们一直以来的支持
目录总览
本篇共 8 个任务,分为三大模块:
模块一:MCP + Skills(原进阶篇一)
- 任务 1:MCP 入门——先接入安全的工具试试
- 任务 2:实现一个 MCP Server
- 任务 3:Skills 流程卡片
模块二:多智能体 + 长任务治理(原进阶篇二)
- 任务 4:多智能体分权
- 任务 5:长任务治理 ULW 循环
模块三:安全、评测与流水线(原进阶篇三)
- 任务 6:安全加固
- 任务 7:评测与可观测
- 任务 8:团队协作与流水线
模块一:MCP + Skills——让 coding agent 有自己的工具
写在前面
上一篇我们搞定了开发环境、对很多概念都已经有了一个基础的了解。
但你可能已经发现了一个问题:AI 只能看到你在输入框里告诉他的信息,该怎么让它自己去检索项目代码?怎么让它按固定格式交付修 Bug 的证据?怎么给它接上它可以调用的工具呢?这些就是这一篇想要解决的问题。
本篇包含 3 个任务:
- 任务 1:MCP 入门——先接入只读工具试一试
- 任务 2:亲手实现一个 MCP Server——自己动手丰衣足食
- 任务 3:Skills 固化——把"修 Bug"变成可复用的标准流程卡片
术语介绍在这
- MCP(Model Context Protocol):一个标准的"工具插槽"协议,让 AI 客户端能统一发现和调用外部工具。
- STDIO:MCP 最常见的本地传输方式,通过进程的标准输入输出通信。(不要往 stdout 写日志。)
- schema:工具的输入和输出格式。越明确、越规范,你的工作流就越稳定。
- Skills:把高频的业务动作固化成"流程卡片",让 AI 每次都按同一套流程做并产出交付。
任务 1:MCP 入门:先接入安全的工具试试
目标:把一个 MCP 工具接进来,先简单感受一下mcp。
如果你对 MCP(Model Context Protocol)还不熟悉,可以把它理解成一个 “标准的工具插槽”。以前你得往提示词里写很多上下文;现在只要用统一的协议把外部工具接进来,你的客户端(CLI、IDE、Agent )就能用同一套约定去发现工具、调用能力。
补充说明:
MCP 不只是"调用工具"。它定义了三种能力:
- Tools(工具):AI 可以主动调用的函数,比如搜索代码、读文件。
- Resources(资源):只读的上下文数据源,比如项目文件列表、数据库 schema。AI 可以读取但不能修改。
- Prompts(提示词模板):预设的交互模板,比如代码审查流程。
本篇主要聚焦在Tools,但理解这三者的区别有助于佬友们后面设计更完善的工具链。
1.1 挑一个没什么改动风险的 MCP 工具
这一部分我推荐大家选只读的工具。比如:
- 只提供读取权限的文件系统接口(Filesystem)
- 查文档用的检索工具(比如 context7)
这两个工具都比较老牌并且用的比较多,大家可以根据自己的情况选择。
1.2 把工具接到你的开发环境(CLI/IDE)
我目前最喜欢的使用方法就是用antigravity(ultra)右边是agent窗口,然后开一个终端在下面,然后也分享一个小技巧,如果想一个项目开多个窗口的话可以存一个工作区,这样就可以左右开弓了。
mcp底层原理都一样:读mcp配置后,帮你在后台起一个进程,本质就是执行 command + args。
下面直接给出上面提到的两个工具的mcpserver配置:
这步其实可以直接告诉你使用的coding agent我要配置什么mcp就可以了,然后有的mcp需要你自己去到对应的网站上注册然后拿一个key,拿到之后再给你的coding agent来配置就可以了
Filesystem(只读文件系统):
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/ABSOLUTE/PATH/TO/YOUR/PROJECT"]
}
}
}
注意把路径换成你项目的绝对路径。这个工具只给 AI 读取指定目录的能力,不会写文件。
context7(文档检索):
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@latest"]
}
}
}
context7 可以帮 AI 直接查阅各种开源库的最新文档,不用你手动复制粘贴。
验证标准:
可以直接让你的coding agent检查mcp启用状态,或者用命令来看,mcp list或者/mcp之类的指令,可以根据你自己用的coding agent的文档来查一下怎么看mcp的启动状态,ccswitch也是一个不错的mcp管理工具。
image2008×1000 103 KB
- mcp list 之后工具名能看到,你可以手动指定去调用它。
- 就算读取失败了,也能在终端日志里看到具体报错,对得上路径和参数。
延伸阅读:
如果你对 MCP 的概念还比较模糊,建议先看一遍官方介绍,搞清楚 Tools、Resources、Prompts 这三者的区别,然后跟着 Server Quickstart 走一遍,感受一下客户端和工具之间怎么配合的。
- MCP Introduction — What is the Model Context Protocol (MCP)? - Model Context Protocol
- MCP Quickstart: Build a server — Build an MCP server - Model Context Protocol
- MCP 推荐 ——
https://www.bilibili.com/video/BV1ZJsBznEt3/?spm_id_from=333.337.search-card.all.click
任务 2:实现一个 MCP server
这部分我们的目标是从零写一个最小可用的 MCP server,然后把它注册到你的开发环境里。
这一步的意义不在于写出一个 Hello World 工具,而是自己动手实践搭了一个可复制的模板。以后想让 AI 检索公司的 Jira、内部日志或者发版系统,该怎么起步、怎么验证、怎么排错心里就有数了。
这部分演示一条按官方思路、跨平台兼容且确保能跑通的轻量路径。
2.1 环境准备(Python + uv)
官方建议 Python 3.10 以上,搭配最新的 MCP SDK。客户端拉起你的 Server 时,需要找到你配好的那个 Python 解释器。
2.2 STDIO 日志别用 stdout
为什么?因为 MCP 用 STDIO 模式通信时,stdout 是专门给协议消息走的通道。你往里面混了别的东西(比如一句 print("hello")),客户端收到的 JSON 就乱了,可能会导致直接断连。
用代码来说就是这样:
错误写法(会导致连接断开):
print("Server 启动中...") # 这行会写到 stdout,把协议搞坏
正确写法(日志走 stderr,不影响协议):
import sys
print("Server 启动中...", file=sys.stderr) # 日志走 stderr,协议不受影响
Node.js 也一样:用 console.error(...) 代替 console.log(...)。
简单记住一条规则就行:
stdout→ 只给 MCP 协议用,你的代码里不要往这里写任何东西stderr→ 你的调试日志全走这边
所以碰到连接断开就可以排查一下是不是写错了
2.3 建一个干净的项目
找一个你放 Demo 的文件夹:
uv init code-search
cd code-search
uv venv
激活虚拟环境(挑你用的终端):
# macOS/Linux
source .venv/bin/activate
# Windows PowerShell
.venv\Scripts\Activate.ps1
# Windows cmd
.venv\Scripts\activate.bat
装上 SDK 依赖:
uv add "mcp[cli]"
image-11490×1270 125 KB
创建脚本文件:
# macOS/Linux/WSL
touch code_search_server.py
# Windows PowerShell
ni code_search_server.py
# 你也可以用 Python 方式创建
python -c "open('code_search_server.py','w').close()"
验证:
uv --version能正常返回。- 激活环境后
python -V是你预期的版本。 python -c "import mcp"不报错。
2.4 写一个只读的检索工具(rg / ast-grep)
与其写一个只会返回 Hello 的玩具,不如直接上手写一个好用的纯读取检索工具:用 rg 做文本搜索,或者用 ast-grep 做语法树级别的代码检索。
前置准备:
- 全局安装
rg(ripgrep) - (可选,但建议体验)全局安装
ast-grep
把下面这段代码存到 code_search_server.py 里:
import os
import shutil
import subprocess
import sys
from pathlib import Path
from typing import Any, Optional
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("code-search")
# 确保 Homebrew / Linuxbrew 等常见路径在 PATH 里
# (uv run 的子进程可能丢失这些路径,导致 rg 找不到)
_EXTRA_PATHS = ["/opt/homebrew/bin", "/usr/local/bin", "/home/linuxbrew/.linuxbrew/bin"]
_ENV = os.environ.copy()
_ENV["PATH"] = os.pathsep.join(_EXTRA_PATHS + [_ENV.get("PATH", "")])
def _find_bin(name: str) -> str:
"""查找可执行文件的绝对路径,找不到就原样返回让后面报 FileNotFoundError。"""
return shutil.which(name, path=_ENV["PATH"]) or name
def _run(cmd: list[str], cwd: str, timeout_s: int = 30) -> tuple[int, str, str]:
"""安全地执行子进程,带超时保护。"""
p = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=timeout_s,
shell=False,
cwd=cwd,
env=_ENV,
stdin=subprocess.DEVNULL, # 防止子进程继承 MCP 的 stdin 管道
)
return p.returncode, p.stdout, p.stderr
@mcp.tool()
def rg_search(target_dir: str, query: str, globs: Optional[list[str]] = None, max_lines: int = 200) -> dict[str, Any]:
"""用 ripgrep 搜索文本,返回结构化结果。"""
if not target_dir.strip():
return {"ok": False, "error": "target_dir required"}
if not Path(target_dir).is_dir():
return {"ok": False, "error": "target_dir not a directory"}
if not query.strip():
return {"ok": False, "error": "empty query"}
# 注意:--glob 必须放在 "--" 之前,"--" 之后的参数会被当作搜索词和路径
cmd = [_find_bin("rg"), "--line-number", "--no-heading", "--color", "never"]
for g in (globs or []):
cmd += ["--glob", g]
cmd += ["--", query, "."]
try:
code, out, err = _run(cmd, cwd=target_dir)
except FileNotFoundError:
return {"ok": False, "error": "rg not installed"}
except subprocess.TimeoutExpired:
return {"ok": False, "error": "rg timeout"}
# rg 退出码:0=有匹配, 1=无匹配, 2=出错
if code == 2:
print(err.strip(), file=sys.stderr)
return {"ok": False, "error": "rg error", "details": err.strip()}
lines = [ln for ln in out.splitlines() if ln.strip()]
if len(lines) > max_lines:
lines = lines[:max_lines] + ["... truncated ..."]
return {"ok": True, "matches": lines, "rc": code}
@mcp.tool()
def ast_search(target_dir: str, pattern: str, lang: str, globs: Optional[list[str]] = None, max_lines: int = 200) -> dict[str, Any]:
"""AST 级别的代码搜索,需要本地安装 ast-grep。"""
if not target_dir.strip():
return {"ok": False, "error": "target_dir required"}
if not Path(target_dir).is_dir():
return {"ok": False, "error": "target_dir not a directory"}
if not pattern.strip() or not lang.strip():
return {"ok": False, "error": "pattern/lang required"}
if not lang.isalnum():
return {"ok": False, "error": "invalid lang"}
cmd = [_find_bin("ast-grep"), "run", "--pattern", pattern, "--lang", lang]
for g in (globs or []):
cmd += ["--globs", g]
cmd += ["."]
try:
code, out, err = _run(cmd, cwd=target_dir)
except FileNotFoundError:
return {"ok": False, "error": "ast-grep not installed"}
except subprocess.TimeoutExpired:
return {"ok": False, "error": "ast-grep timeout"}
if code != 0:
print(err.strip(), file=sys.stderr)
return {"ok": False, "error": "ast-grep error", "details": err.strip()}
lines = [ln for ln in out.splitlines() if ln.strip()]
if len(lines) > max_lines:
lines = lines[:max_lines] + ["... truncated ..."]
return {"ok": True, "matches": lines}
if __name__ == "__main__":
mcp.run(transport="stdio")
划重点:
- 纯读取,只负责找东西,不会动你的文件。
- 输入输出很规整,方便大模型解析,也方便后面做审查和重构。
- 调试日志只走
stderr,不污染 stdout。 - 两个工具都捕获了
FileNotFoundError,如果系统没装rg或ast-grep,会返错误而不是崩溃。
2.5 先用终端看看活了没有
uv run code_search_server.py
跑起来之后终端会挂住而没有任何输出,这说明它正在等客户端发指令过来,而不是寄了。
2.6 对接客户端
Server 跑通之后,可以告诉你的 coding agent:“我本地有一个 MCP server,你去给我连接上。”
第一步:找到你工具的 MCP 配置文件
不同工具的配置文件位置不一样,这里我举一下反重力和codex的例子,如果是直接配置到cc/codex这种,就直接在配置文件里面改,codex在toml,cc在json,也可以直接在ccswitch里面管理或者改配置:
| 工具 | 配置文件位置 |
|---|---|
| Antigravity | ~/.gemini/antigravity/mcp_config.json |
| Codex | ~/.codex/config.toml |
第二步:把配置写进去
打开对应的配置文件,把下面的配置加进去(注意把路径换成你自己的):
Antigravity / Cursor / Claude Desktop(JSON 格式):
{
"mcpServers": {
"code-search": {
"command": "uv",
"args": [
"--directory",
"/你的绝对路径/code-search",
"run",
"code_search_server.py"
]
}
}
}
Codex(TOML 格式,加到 ~/.codex/config.toml 末尾):
[mcp_servers.code-search]
type = "stdio"
command = "uv"
args = ["--directory", "/你的绝对路径/code-search", "run", "code_search_server.py"]
第三步:重启你的 coding agent,验证连接
重启之后,用你工具里的 MCP 检查命令看一下 code-search 是不是已经连上了。然后试着让 AI 调用一下,比如跟它说:“用 rg_search 在我的项目目录里搜一下 TODO”,看看它能不能正常返回结果。
Tips:
- 路径必须是绝对路径,不能用
~或相对路径。- Windows 用户请用
where uv把command的完整路径填上。- 如果连不上,先在终端手动跑一遍
uv --directory /你的路径/code-search run code_search_server.py,能跑通说明配置没问题,问题出在 agent 那边。
示例:codex /mcp检查链接
image1458×366 23.7 KB
示例:codex 调用测试
image2028×838 114 KB
延伸阅读:
如果打算把 MCP 长期用下去,建议抽空看一遍 Python 和 TypeScript 两个 SDK 的 README,搞清楚 SDK 的生命周期、安全策略和进阶配置。
image711×170 21.2 KB
任务 3:Skills,制作流程卡片,减少重复工作
不管模型多强,它的发挥总是有波动,有可能不是降智,只是佬的提示词没有上一次写的用心或者这次有点不耐烦了,所以把流程写死,让它按照格式交付。 通过写好流程规范来提高模型输出的稳定性。
3.1 减少重复提示词工作
不把流程固化(Skills)很快就会陷入这种循环:
- 每次都得重新解释"你该怎么查日志"、“怎么证明你修好了”、“别忘了补回归测试”。
- AI 每次给你的输出格式都不一样,有时候连它自己上一步说了啥都忘了。
Skills 的价值就是把这些正确做法固定下来,一次梳理,长期复用。
3.2 写一张修bug的流程卡(模板见本文末尾附录)
一张合格的卡片,至少覆盖这几个方面:
- 输入要求:Bug的现象、关键报错日志、重现步骤、可能涉及的文件路径。
- 输出交付:最小化复现代码、修复 diff、跑通的验证输出,以及回归测试(有条件的话)。
- 失败预案:信息不够或者死活查不出来怎么办(比如:让coding agent列一份"需要我补充的信息清单",而不是让他闷头苦干,最后活没干好账单还要你结)。
建议:
别凭空想象理想流程。回忆一下你最近真实碰到过的几个恶心 Bug,从实战经验里总结张卡片,我觉得时刻有这个思想是好事,每次跟觉和coding agent协作效率比较高的时候回看一下你们的沟通过程以及工作流程,和coding agent一起写一张skill,把这份高效的模式留存下来方便后面复用。
3.3 Skills卡放在哪?怎么让 AI 每次自动加载?
写出来的卡片不能只是一段复制粘贴的文本,它需要一个稳定的位置:
- 推荐做法:存为独立文件(如
skills/bugfix.md),然后在AGENTS.md中引用它:请在每次排障时,严格遵循 skills/bugfix.md 中定义的流程卡片。 - 次选做法:直接写在
AGENTS.md的对应章节里,方便 AI 工具自动读取。(真的是次选,直接写在这会加很多input token
不同工具的引用机制不同,但是ccswitch依旧有一套管理系统(歌颂ccs
image-71954×1214 179 KB
3.4 像验收外包一样,强制coding agent按卡片交付
跟它沟通时,直接规定好他需要交付的内容:
请你严格按照以下清单进行交付,并且每一项都必须附上证明:
1) 提取出最小规模的复现逻辑(提供可执行的命令或步骤)。
2) 确诊根因所在(必须引用具体的代码行号或日志证据)。
3) 提出修复方案,并解释你为什么要这样改。
4) 给出修复后的对比 diff。
5) 执行自动化测试并直接贴上输出日志。
6) 补充一段回归测试代码(如果客观上没法写,请写明技术原因)。
什么时候可以确定这是一张可以复用且质量不错的卡?
- AI 回答的结构稳定了,不再东拉西扯。
- 这张卡片在不同的排障场景下都能套用。
- 你能一眼扫出它有没有漏掉哪一步。
用词就该是"必须交付的硬性证据",而不是"建议"或者"最好",这样才能保证输出质量。
在这里推荐一个skills集合网站:https://skillsmp.com/zh
延伸阅读:
如果你想了解"卡片"这套理念是怎么被做成通用标准的,可以看看 Anthropic 团队的思路和 Agent Skills Standard。
附录:修 bug 的 Skills 卡片模板
image587×333 19.6 KB
模块二:多智能体 + 长任务治理——拒绝 coding agent 既当裁判又当运动员
让同一个 AI 既写代码又审代码,它往往对自己写的 Bug 视而不见。本模块解决两件事:多智能体分权(任务 4)和长任务治理(任务 5)。
能并行的只读工作就并行。能分权的执行审查任务就分权。每个环节都要交证据,而不是听你的cc告诉你已经到达了“顶会level”
任务 4:多智能体:不让你的coding agent既当运动员又当裁判
目标:把"写代码"和"审查代码"拆给不同的角色
推荐两种做法:
-
比较简单的实现方法:你来当调度员,把 Scout、Builder、Verifier 的输出按固定格式手动传递。具体操作:在 Chat A 中以 Scout 身份让 AI 搜索,复制它的输出 JSON,再在 Chat B 中以 Builder 身份粘贴进去开始实现,最后在 Chat C 中以 Verifier 身份审查。
-
比较进阶高效的方法:用脚本或工作流引擎做自动编排。本文末尾附录 C 给了一个比较小的参考骨架。
从单 Agent 到多 Agent 的拐点:
你可能会问——“我用一个 coding agent 加上 Skills 卡片不就够了吗?” 我的回答是:如果这个任务节点比较少并且简单你的思路是没问题的,但是如果任务比较复杂的话,让同一个 Agent 既写实现又审代码,它往往对自己写的 Bug 视而不见。就像你让同一个人写代码又做 Code Review,这种模式的效果注定是不好的。把"写"和"审"拆给不同角色才能够提高质量,维持每一次决策的可靠性。
ps:最简单的方法就是你开一个codex再开一个claudecode,让claudecode出plan,然后给codex做check,没问题了之后让claude开始工作,然后拿工作结果给codex做double check,这种方法简单高效又好用。
1.1 核心分工(这里拿三个来举例子)
-
Scout:只找线索,不改代码。
-
Builder:只做实现,按约束最小改动。
-
Verifier:只做审查,负责找问题和跑验证。
只要职责不重叠或混合,稳定性就会上一个台阶。
1.2 一套用来参考的提示词约束模版
下面这三段约束,重点在于如何把输入、输出、禁止事项写的清楚。
Scout
你当前的角色是 Scout。你只负责收集证据,不允许改代码。
你必须交付:
1) 直接相关的文件路径清单,按重要性排序。
2) 仓库中相似实现或现有模式,尽量精确到函数、类、模块。
3) 你判断出的约束条件:构建、平台、安全、依赖、权限。
4) 你建议的最小改动范围。
禁止事项:
- 不写代码草案
- 不提出大范围重构
- 不替 Builder 做实现决策
Builder:
你当前的角色是 Builder。你的原则是:改动的时候尽量保持最小改动。
你不可违背的红线:
1) 动手之前,先亮出你需要跑的 3-7 步执行计划和验证预期。
2) 编码结束后交出 diff。
3) 提供实际执行过的测试、构建或验证输出。
4) 如果碰到了必须要加新库或者要一次动超过 5 个文件,停下来,先给我解释清楚非改不可的原因。
5) 你的修改方案应当竭尽所能做到"幂等"。无论跑几次都不该搞出重复追加、文本反复插入导致的破相。
6) 不要过分迷信 unified diff 的通用性:如果工具执行失败,立刻切换降维方案——给出"整个函数/模块的完整替换"或采用"查找且批量替换"式的方案协助落盘。
Verifier:
你当前的角色是 Verifier。你不负责写实现,你只负责审查和验收。
你必须交付:
1) 按严重程度排序的风险清单。
2) 决策没覆盖到的测试点和边界条件。
3) 基于 diff 的逐项审查结论。
4) 最低成本的补救建议。
你的判断必须基于:
- diff
- 实际执行结果
- 测试覆盖情况
- 已知约束条件
禁止事项:
- 凭感觉输出
- 在没有验证结果时宣称"应该没问题"
- 越过风险直接建议合并
最小流转路径:
-
scout.pass -> builder -
builder.pass -> verifier -
verifier.fail -> builder(打回原因直接发还给 Builder) -
needs-human→ 交给你来仲裁。
这么做最大的好处是:不管你以后换什么框架(LangGraph、AutoGen / AG2、原生 SDK),甚至手动复制粘贴排障的链路都是熟悉且清楚的。
1.2.1 大仓库的上下文管理:别让模型把你仓库全读一遍
真实项目里最常翻车的原因不是模型写不出代码而是无关信息太多,把上下文窗口塞爆了,这不仅对项目上下文不友好,对你的钱包也不太友好。
可以参考的底线策略:
-
用
rg先快速锁定一小批候选文件(按报错名或接口名来搜)。 -
再用 AST 级别的工具(IDE 的 Go to Definition 或
ast-grep)精确定位函数调用链。 -
喂给 Builder 时,只给裁剪后的代码片段 + 必要上下文 + 报错信息,避免填入多余噪声。
image719×149 14.8 KB
如果你的库很硕大:
-
第一轮: 只侦察,摸清模块和接口,不写代码。
-
第二轮: 做最小化修复。
-
第三轮: 跑全量验证,抓漏掉的边界。
或者在代码库中做一个目录索引,避免模型真的一个一个代码去读,由索引先提供给模型一个候选区域而不是让它瞎猜。
当Verifier 能准确指出 Builder 的遗漏,而且最终代码确实比第一版更稳的时候就起效果了。
多智能体协作不是"给几个机器人喂同样的 Prompt 让它们抢答"。核心在于:职责分离 + 信息隔离
延伸阅读:
想深入了解多 Agent 协作的设计思路:
image707×311 32.1 KB
任务 5:长任务治理:ULW 循环式推进
不管是用单 Agent 还是多智能体,只要任务开始跨越多个步骤和文件都可以使用这套方法
做过长周期复杂任务的佬都知道,最要命的不是Coding agent无从下手,Coding agent不会无从下手,怕的是它到处下手,越做越发散,屎山越来越高,最后甚至找不到一个能回滚的位置。
ULW(循环式推进 / Ultrawork)不是让 AI 无限循环。它的核心是:把大任务切成一段段可以验收的小结果,每段都有明确的目标、证据、可回滚的存档点和一键喊停的开关。
ulw我觉得omo做的很好
GitHub - code-yeongyu/oh-my-openagent: omo; the best agent harness - previously...
omo; the best agent harness - previously oh-my-opencode
感兴趣的佬可以试一试
你也可以直接把这份约定喂给你的coding agent:
你现在接手的任务按"循环推进"制度,规则如下:
1) 每轮只盯一个改动点,动手前先说清楚验证标准。
2) 每轮结束必须交证据:改动概要 + diff + 通过验证的日志。
3) 硬性上限:最多试 N 轮或花 T 分钟。超了就停下汇报,不许硬撑。
4) 碰到红线(拉大依赖、改大批文件、完全查不出原因的报错),立刻停手汇报。
5) 高危操作(删库、改根目录配置等)必须等我批准。
6) 交接时自己精简上下文:只把"做了什么、结论是什么"压缩成 3 句话带到下一轮,不许把大段日志原封不动搬过去。
当能够随时抽查它,它能说出"现在第几轮、这轮修什么、成功标准是什么",而且能退回到上一轮的存档点,就算有效果了
参考:
image710×221 22.9 KB
附录 C:现在怎么做多智能体—时代变了,现在已经不用自己写调度代码了
任务 1 里讲的 Scout/Builder/Verifier 分工,现在主流工具已经内置了不同程度的支持。你不需要很麻烦的自己写,很多主流工具你写一段提示词存起来在需要的时候用自然语言调用一下就可以了。
C.1 最简单:AGENTS.md 分角色
把角色约束写进 AGENTS.md,工具启动时自动加载,对所有对话生效。
## 角色约束
当前角色:Builder
- 职责:只做实现,最小改动
- 禁止:自行修改测试基线、重构无关代码
- 交付:diff + 通过验证的输出
当前角色:Verifier
- 职责:只做审查,不写实现
- 必须交付:风险清单、未覆盖边界、逐条 diff 结论
- 禁止:在没有验证结果时宣称"应该没问题"
支持 AGENTS.md 的工具:Codex、Claude Code 等。
C.2 Codex 并行 Agent(worktree 模式)
Codex 原生支持同时跑多个 Agent,每个 Agent 在独立的 git worktree 里工作,互不干扰、不产生合并冲突。
实际用法:
-
打开 Codex,发起一个任务
-
点击"创建新的工作分支",可以同时跑多个互不影响的子任务
-
Codex 自动管理 worktree 隔离,你只需要审查每个 Agent 的 diff
比较适合同一个 feature 里,UI 改动和 API 改动可以并行交给两个 Agent 分别做。
参考文档:https://openai.com/codex
C.3 Claude Code 子智能体(subagent)
Claude Code 支持在一个主 Agent 里,通过 Task tool 发起并行子任务。主 Agent 做 Scout 和调度,子 Agent 做 Builder 或局部验证。
小示例:在 Claude Code 的对话里直接跟它说:
你现在作为 Scout,先把相关代码范围摸清楚,
然后启动两个子 Agent 分别实现方案 A 和方案 B,
最后你来对比两个结果选出更好的。
Claude Code 会自动调用 Task tool 并行跑子任务,你只需要最后审查主 Agent 给你的汇总。
参考文档:https://www.anthropic.com/engineering/multi-agent-research-system
C.4 :LangGraph 图编排(需要写代码)
如果你的团队需要把多 Agent 流程做成自动化 pipeline(比如接进 CI/CD),可以用 LangGraph 做图调度。核心结构是:
START → scout → builder → verifier → [pass: END | fail: summarize → builder]
用 summarize 节点在每次打回时裁剪上下文,避免 Builder 重试时带着一堆没用的历史日志。
官方文档:Redirecting to LangGraph Documentation
模块三:安全、评测与流水线
本模块解决最后三个问题:安全加固(任务 6)、评测与可观测(任务 7)、团队协作与流水线(任务 8)。
任务 6:安全加固——第三方 MCP 不只是普通插件,更代表着权限
目标:建立一套接入前的安全审查习惯。不管是用别人的 MCP server 还是自己开发,都要先排查一下隐患。
你把第三方 MCP 接到你的开发环境里,本质上就是给了一个外部程序跟你一样的系统权限。它能碰到的网络、文件系统,基本等于你能碰到的,这是很夸张的。
1.1 接入前需要考虑的 7 个问题
- 读写边界:它到底需要读什么,需不需要写权限。
- 权限范围:默认权限是不是给太大了,能不能把权限缩到最小目录。
- 网络行为:它在工作时会访问哪些网络,请求会发到哪些域名。
- 敏感距离:它离你的环境变量、数据库凭据留有多少距离。
- 审计日志:它跑的时候,有没有留下可追溯的日志。
- 重试风险:超时或报错后的重试,会不会产生副作用。
- 供应链:作者靠谱吗,是长期维护的项目还是可能有后门随时有跑路风险的项目。
1.2 给已接入的 MCP 做一次安全审查
可以拿出我们之前做好的 MCP 出来,也可以拿一个比较常用的 MCP 来进行一次审查。
MCP 审查表
Server 名称:
1. 读写边界:只读/读写
2. 权限范围:已限制到子目录/全盘访问
3. 网络行为:网络请求流向
4. 敏感距离:无法访问 .env/数据库/可访问
5. 审计日志:有日志/无
6. 重试风险:操作幂等/有副作用风险
7. 供应链:官方/知名维护者/个人项目
1.3 需要确认的底线
- 最小权限:只给特定子目录的访问,只开必要的端口。
- 写入限制:如果必须能写文件,至少限制在
src或tmp下,避免碰到配置文件。 - 可追溯:最起码你得能看到它调了什么、改了哪几行。
- 重试克制:别让重试变成死循环。
1.4 用 HTTP MCP 时的安全注意事项
大部分人用的是本地 STDIO 模式(就是在 config 里配 command + args 那种),这种模式 MCP 跑在你自己机器上,安全风险相对可控。
但如果你用的是 HTTP 模式(MCP Server 在远程通过网络调用),那安全要求就会变高,这里说几个推荐大家注意的点:
- 认证:必须用 OAuth 做身份验证,裸跑的 HTTP MCP 等于把开发环境暴露在公网上。
- Token:API Token 只能放在请求的 Header 里(
Authorization: Bearer xxx),不要拼在 URL 后面,URL 会被日志和浏览器历史记录泄露。 - 回调:OAuth 回调只允许
localhost或https://开头的地址,防止 Token 被中间人截获。
image713×270 36.3 KB
任务 7:评测与可观测——不再凭直觉对项目进行迭代
这部分主要为了回答一个问题:“改了工作流换了模型之后,效果到底是真的变好了,还是运气呢?”
没有认真的评测量化,日常开发最容易陷入这种情况:
- 今天一切顺利:“天才程序员诞生了”
- 明天觉得模型降智:“天才程序员陨落”
其实多半是上下文膨胀了、工具链卡了、或者纯粹运气不好。我们需要一些量化后的证据来看看到底是为什么。
2.1 自己做一套回归测试集
跑和自己业务项目关系不大的 Benchmark 意义不大,有时间的话自己搭一套质检题库是个不错的选择:
- 3 个有代表性的 Bugfix
- 3 次 Feature 增量
- 2 次重构
- 2 次补核心链路测试
每道题需要写清楚的是:
- 输入:原始任务描述。
- 预期:通过条件。
- 验证:验证命令。
存成 JSONL,方便即拿即用(附录 A 有最小 Schema)
2.2 先用最朴实无华的方式做 Tracing
用 JSONL 把每次操作录下来:
trace_id(任务标识)- 操作时间
- 调用的 Tool 名
- 输入摘要(注意脱敏,去掉 API Key、密码等)
- 输出摘要
- 耗时
- 报错信息
有了这种记录表,才方便在问题出现的时候,快速定位问题到底在哪。
建议:
每条日志一定要带trace_id。一旦多个 Agent 并行跑或者长任务反复重试,没有 trace_id 的日志直接就乱套了,根本分不清上下游。
2.3 往标准化靠拢
如果打算把这套推给团队用,建议字段命名向 OpenTelemetry (OTel) 的 GenAI semconv 标准看齐。哪怕现在没接 OTel 的全套体系也可以先统一命名,以后迁移成本就会降低很多。
参考:OpenTelemetry GenAI Semantic Conventions — Semantic conventions for generative AI systems | OpenTelemetry
2.4 进阶:从日志到可视化看板
纯看 JSONL 几十次调用确实难受。可以考虑加一层可视化:
- 底层还是存 JSONL(这是保底的原始日志)。
- 上面接一个可视化平台(Langfuse / Phoenix / LangSmith……)。
- 需要注意的有 4 个关键指标:
- 各类任务的通过率
- 单次 Bug 修复的端到端耗时
- 每个环节的 Token 消耗
- 失败时卡在哪一环
之后就可以比较方便地拉出某次失败任务的完整链路了。
改完prompt后也可以用数据来对比前后的通过率和耗时差异。
延伸阅读:
想深入了解评测和追踪的实践:
- Inspect AI (UK AISI) docs — https://inspect.aisi.org.uk/
任务 8:团队协作与流水线
第一次让两个 Agent 同时去修同一个文件的人,通常会收获一份完美的合并冲突。
本节适用于有 CI/CD 环境、多人协作的团队项目。如果你目前是单人本地开发,可以直接跳过。
3.1 沙盒(Sandbox)
有一个现实是必须接受的:幻觉导致的抽风瞎写发散是不可能完全消除的。所以我们能做的就是考虑怎么降低在幻觉出现时可能造成的负面影响。
做法:
- 所有试运行、构建、测试都扔到无状态容器或临时沙盒里跑。
- 只有测试全部通过之后,才允许把 diff 补丁合回主干。
- 高危操作(删包、重建根目录、大规模推改)要求 coding agent 申请人工审批。
3.2 固定流水线中的关卡
这里面举三个例子:
- 静态检查:lint + 类型检查,语法级别的低级错误直接拦掉。
- 业务逻辑:跑一遍本次改动涉及的单测或集成测试,确认功能没被改坏。
- 安全扫描:有没有硬编码密钥、有没有引入高危依赖,发现了就打断。
如果有关卡没过就退回重来。
对修复主导权本篇也给出两套参考方案:
- 让 CI job 本身带修复能力,跑挂了直接读 stderr 开始纠错循环,修好了打一个 patch commit。
- CI 只负责跑测试和报告结果,出了问题通过 Webhook 把错误现场发给远端的 Agent 服务,Agent 打好补丁后 Push 分支等人来审。
3.3 多 Agent 并发时的保护机制
如果你有多个 Agent 同时干活需要注意这两个问题:
- 同一时刻只允许一个 Builder 有写权限,其他角色(Scout / Verifier)在同一时刻只读。
- 写入前必须同步最新的上游状态,避免两个 Agent 各写各的然后互相覆盖。
常见的实现方式:
- 文件锁:在写入和跑测试的入口用
flock之类的工具加锁,另一个 Agent 过来发现被占了就直接排队或报错。 - Git 保护:每次写入前强制
git pull --rebase,有冲突就中断当前轮次。
如果你用的是 Codex 的 worktree 模式,它已经帮你做了隔离,每个 Agent 在独立的 worktree 里工作,基本不会冲突。这节主要是给自己搭框架的团队看的。
延伸阅读:
- Codex Security(沙箱 / 审批 / 网络策略)— Codex Security
- Dagger Docs(容器化可复现流水线)— https://docs.dagger.io/
- The Harness Problem — I Improved 15 LLMs at Coding in One Afternoon. Only the Harness Changed. | Can.ac
附录 A:模版案例参考
A.1 项目规则模板(放在根目录的 AGENTS.md)
image686×311 19 KB
A.2 需求描述模板
image685×341 14.1 KB
A.3 MCP Server 开发 checklist(STDIO 模式)
- 不要在 stdout 写日志(调试信息走 stderr)。
- 先在本地跑通,再对接远端或外部 API。
- 每个 tool 都要定义清楚:入参类型、返回结构、错误处理、超时限制。
- 明确读写范围:它能触及的目录有哪些,是否有被限制在子目录中。
- 写操作尽量做到多次调用不产生副作用。
A.4 HTTP MCP 的授权 checklist
- 通讯走 HTTPS
- redirect URI 严格校验
- Token 走 Authorization header(不放 query string)
- 配置 PKCE
- 按标准走 metadata discovery(
.well-known/oauth-authorization-server)
A.5 多智能体角色模板
见前一篇
Vibecoding进阶教程-从能用到可控(二):拒绝coding agent既当裁判又当运动员
A.6 评测回归库的 JSONL 模板
记录好输入和验收标准
{"id":"bugfix-001","title":"修复计算模块的单测崩溃","input":"...","acceptance":["npm test 全部通过"],"verify":["npm test"],"tags":["bugfix","tests"]}
A.7 Tracing 的 JSONL 模板
每条带时间戳、耗时和 trace_id
{"trace_id":"bugfix-123-run-1","ts":"2026-03-03T10:00:00Z","tool":"bash","input_summary":"npm test","output_summary":"passed","duration_ms":12345,"error":null}
附录 B:延伸阅读与官方参考资料
image704×690 91.4 KB
image735×784 102 KB
image722×570 72.6 KB
image736×463 58 KB
网友解答:--【壹】--:
收到,感谢佬的建议,最近也有想做这个的想法
--【贰】--:
感谢佬友分享,我怎么好像昨天见过?穿越了吗
--【叁】--:
前排支持!
--【肆】--:
前来支持
--【伍】--:
感谢喵佬又来捧场了
--【陆】--:
mark就完事了,感谢佬友的分享
--【柒】--:
先赞后看,感谢大佬
--【捌】--:
先赞后看,感谢大佬~
--【玖】--:
重新整理优化了一遍总集篇
--【拾】--:
太良心了bro,这玩意在外头我看至少值999
--【拾壹】--:
先赞后看
--【拾贰】--:
先赞后看,给力
--【拾叁】--:
感谢佬辛苦整理!
--【拾肆】--:
感谢整理汇总,非常有用
--【拾伍】--:
太牛逼了
--【拾陆】--:
狠狠收藏了,感谢大佬码字分享~
--【拾柒】--:
太良心了 必须收藏住
--【拾捌】--:
建议增加上下文控制的部分
MCP SKILLS用多了也会增加上下文开销
控制上下文不仅是为了节省tokens 也能增强模型专注力
1m上下文并不意味着1m空间内专注力都是一致的 所以还是要学会控制上下文 尽可能的在专注力空间内解决问题
--【拾玖】--:
感谢佬,标记一下

