> ## Content Index
> Fetch the complete content index at: https://www.hubwiz.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# 多 Agent 同机：Git 作者、凭据与提交归属怎么分
- URL: https://www.hubwiz.com/blog/multiple-coding-agents-identity-git-attribution/
- Published: 2026-10-24T05:46:01.000Z
- Updated: 2026-10-24T05:51:05.000Z
- Description: 十个 agent 共用一个 GitHub 账号，你得到的是署名，失去的是归属、互审与审计。四个层面拆开：Git 作者、平台身份、提交里的三行、谁手里有钥匙。
- Author: admin
- Tags: AI Agent, Git, 多 Agent, 权限与审计

**一句话结论**：在同一台机器上跑多个 coding agent，"设个名字"是不够的——你要分别处理**四件互相独立的事**：Git 的 author/committer、平台侧的身份（token/App/账号）、提交里的归属标记、以及进程能读到的凭据。少做任何一层，你都会得到一份**看起来正常、但事后无法解释**的提交历史。

**披露**：本文编译整理自四篇 2026 年 9–10 月的一手实践（Vitruvian Software 的十个 agent 与 GitHub App、Obi 的提交 trailer 设计、Orquesta 的 git-native 方案、Bill Mongan 的九 agent 单机与按 agent 分配的 MCP 凭据），并补充 Safeguard 2026-10-18 的身份风险清单。**本文没有自己搭环境复现**，所有命令、数字与"实测结果"都来自原文；文末逐条给出出处。

---

## 一、先看清代价：三个"看起来没事"的坑

Vitruvian Software 的 monorepo 里天天有十个 agent 干活：Forge 管 Bazel 构建、Atlas 管基础设施、Ridge 管 Kubernetes、Wren 写应用代码、Scout 管测试与 CI、Aegis 做安全评审、Quill 写文档……它们贡献了相当大比例的 PR。

在此之前，**GitHub 把这十个 agent 看成同一个人**——所有 push、PR、merge 都走仓库所有者那个账号。表面无害，实际丢了三样东西：

| 丢掉的东西  | 具体表现                                                                        |
| ------ | --------------------------------------------------------------------------- |
| **归属** | "Ridge 开了 #1440" 只是聊天记录里的说法，git 和 GitHub 都无法作证                              |
| **互审** | GitHub 禁止自己批准自己，而在平台看来每个 PR 都是自己写的 → 安全 agent 没办法在基础设施 agent 的 diff 上留下有效批准 |
| **审计** | 记录显示"一个人做了所有事"，包括这个人从没看过的工作                                                 |

第二条是真正的痛点。想让 agent 互审，就得让平台认为"这是两个不同的身份"。用同一个身份时，你能做的最多是**让 agent 留个评论，然后祈祷有人读**。

这条经验对单人开发同样成立：你自己 + 三个 agent 共用一个 `user.name`，等于把未来每一次 `git blame` 都变成猜谜。

## 二、Git 层：token 决定"谁能推送"，环境变量决定"谁署名"

最容易踩的坑在这里，而且**只踩一次就足够毁掉整份历史**。

把 agent 的身份做对，需要同时设置两样东西：

```bash
# 1) 谁推送（API + git push 都用它）
export GH_TOKEN="<installation token>"

# 2) 谁署名（这一项跟 token 完全无关）
export GIT_AUTHOR_NAME="vitruvian-wren-agent[bot]"
export GIT_AUTHOR_EMAIL="<bot_user_id>+vitruvian-wren-agent[bot]@users.noreply.github.com"
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"

```

Vitruvian 一开始只设了 token。结果是：**PR 上显示的是 bot，commit log 里还是机器主人的名字**——因为 git 的作者信息取自本地配置与环境变量，不取自"是谁推送的"。

这解释了一个很常见的错觉："我已经给它单独的 token 了，为什么历史还是乱的？"

几个值得抄的细节：

- **用 bot 的 noreply 地址**：GitHub 会把这个地址绑定到具体 App，于是提交在 GitHub 上能正确回指到 `xxx[bot]`。
- **token 一小时过期是特性，不是麻烦**：长期密钥只有私钥（在 vault 里），token 是每次会话现取的，用完即弃，也就不存在"粘贴到某个配置文件里忘了删"的问题。
- **`GIT_AUTHOR_*` 与 `GIT_COMMITTER_*` 要成对设**：只改 author，rebase / cherry-pick 之后 committer 会泄露真实操作者。

一句话记忆：**token 是权限，环境变量是署名，两者必须同时设。只设一个，你得到一份误导性的历史。**

## 三、平台层：为什么是 GitHub App，而不是"每个 agent 一个 bot 账号"

直觉方案是给每个 agent 建一个 machine user。Vitruvian 否掉了它，理由很硬：

- GitHub 条款允许**每个自然人一个**免费 machine account。十个 agent 就是十个条款不覆盖的账号，外加十套要轮换的凭据。
- GitHub App 没有这个限制：一个组织可以拥有任意多个 App，每个 App 都有真正的 `name[bot]` 身份，能**真的作为作者提交、开 PR、提交 review**。
- App 用**短期 installation token** 认证，而不是密码或 PAT——这正是无人值守软件需要的东西。

命名也很直白：`vitruvian-<agent>-agent`，一个 agent 一个 App。

### 文档没回答的问题，只能自己测

动手之前有个关键未知：**App 的批准，算不算数到"require 1 approving review"这条分支保护规则里？** GitHub 关于受保护分支的文档只说批准来自"有写权限的人"或指定的 code owner，对 App 只字未提。

于是他们在一个 canary 仓库上测（`required_approving_review_count: 1`、`enforce_admins: true`）：

```text
before   reviewDecision=REVIEW_REQUIRED  mergeable_state=blocked
POST /pulls/1/reviews   event=APPROVE   (App installation token)
after    reviewDecision=APPROVED         mergeable_state=unstable
         review  <app-slug>[bot]  type=Bot  state=APPROVED

```

**结论：算数。** 批准要求从"阻塞"变成"满足"。（`unstable` 是另一个无关的 pending check。）

但测出一个限制：**App 不能当 code owner**。`CODEOWNERS` 只接受用户、团队、邮箱地址。所以他们的做法是——关掉"必须 code owner 审查"，只用批准数量这一根杠杆。仓库配置里这两项是分开的，不是笔误。

### 唯一不能自动化的那一步

仓库的一切都当代码管，包括它自己的设置。**创建 App 是例外**：GitHub 没有创建 App 的 API。要么填网页表单，要么走 **App manifest flow**。

manifest flow 更好，因为它**把私钥放在 API 响应里返回**，而不是让你从浏览器下载一个文件。你 POST 一段 JSON，声明权限：

```json
{
  "name": "vitruvian-<agent>-agent",
  "public": false,
  "default_permissions": {
    "contents": "write",
    "pull_requests": "write",
    "metadata": "read",
    "checks": "read",
    "workflows": "write"
  },
  "default_events": []
}

```

GitHub 回调时给一个**一次性 code**，你要在一小时内换成 App 的 id 和私钥。那是私钥的**唯一一份拷贝**：直接进 vault，响应随即删掉。

> ⚠️ 两个坑：① 安装页默认勾选 **All repositories**——接受它就等于给每个 agent 授了组织内所有仓库的写权限，一定要选 **Only select repositories**；② 权限里 `workflows: write` 是给 CI 用的，如果你的 agent 不该碰流水线，就别给。

### 把"谁能写哪里"变成可 review 的 diff

```yaml
repo_config:agentApps:
  - name: beacon
    installationId: "152031070"
  # ...每个 agent 一条
repo_config:requiredApprovals: "1"

```

`agentApps` 把每个 App 的 installation 钉到这个仓库上。好处不是省事，而是：**"哪个 agent 能写哪儿"从"某个设置页里的复选框"变成了"一个会被 review 的 diff"**。

### 顺序错了会怎样

`requiredApprovals: "1"` 必须是**最后一步**。如果先开强制评审、agent 还没有各自身份，那么**没有任何人能给出批准**——每个 PR 永远卡在 `REVIEW_REQUIRED`。更糟的是 release-please 和 Dependabot 的自动合并也会死，因为规则集的 bypass 只覆盖"直接合并"，从不覆盖"自动合并进 merge queue"。

安全顺序：

1. 每个 agent 建并安装一个 App；
2. 私钥进 vault，把每个 agent 的 harness 指向它；
3. 把每个 agent 加进 `agentApps`；
4. **最后**才提高 `requiredApprovals`。

日常使用时，agent 侧只需要一条命令：

```bash
eval "$(bazel run //tools/agent-app -- env wren)"

```

它查一张**提交进仓库的注册表**（App id、installation id、bot user id 都是公开标识符），用该 agent 的私钥签 JWT，换成 installation token，然后导出两样东西——也就是上面第二节的 `GH_TOKEN` 和 `GIT_AUTHOR_*`。

## 四、提交里那三行：谁来写，写什么

Git 的作者字段只有名字和邮箱，加不进"哪个 job、哪个工具、哪个模型"。Obi（一个 Rust 写的 agent 执行引擎）的做法是在提交信息末尾**加三行 trailer**：

```text
Oby-Job: 3f2a9c1e
Oby-Agent: Codex
Oby-Model: gpt-6.1-sol

```

好处很直接：任何人 `git log` 或在 PR 里就能看出"这段代码是哪个 agent、用什么模型写的"，不用去问 owner；owner 自己也能反查：

```bash
git log --grep "Oby-Model: gpt-6.1-sol"

```

这把"某个模型老犯某类错误"从传闻变成了可查询的事实。

### 为什么必须由引擎写，而不是让 agent 自己写

这是整个设计里最值得抄的一点。Obi 的实现是：

- 在 `keep_commits` 阶段（job 结束、把 sandbox 里的提交打包回引擎的 clone 时），对**新出现的那些提交**逐个重写；
- 读原始对象（`git cat-file commit`），把父提交指向重写后的版本，然后把 trailer 追加到消息里，用 `git hash-object -t commit -w --stdin` 自己写新对象；
- **刻意不用 `git commit-tree` 或 `git interpret-trailers`**——它们会读 `commit.gpgSign`、`trailer.*` 之类设置，可能改变字节；
- tree、author、committer 和两个时间戳**保持原样**；
- 如果 agent 自己写了 `Oby-Job` / `Oby-Agent` / `Oby-Model`，**先删掉**，只有引擎说的算；
- 消息末尾已经是同样的三行时不动，所以**重复写不改变提交 id**（幂等）。

还有两个设计取舍值得记：

- **`Oby-Agent` 记的是工具名**（`Claude Code`、`Codex`、`Cursor`），不是账号；`Oby-Model` 优先取工具自报的模型，其次取 job 指定的，最后才是 `default`。
- **绝不写账号名、邮箱、主机名**：因为提交可能是公开的。

对比一下"让 agent 自己在 prompt 里加 co-author"的做法：agent 可以忘、可以写错、可以被注入的提示词骗去冒充别的 agent。**归属信息由不参与推理的那一层写，才可信。**

## 五、粒度：一个动作一个 commit

Orquesta 走的是另一条路：不重写 trailer，而是**让每个动作本身成为一个提交**。

他们的判断是：现在多数工具要么把改动直接落到工作区，要么在会话结束时来一个巨型提交（消息是"AI refactor"这种）——这两种都让中间决策不可见。**那不是可追溯性，那是带收据的黑箱。**

具体做法：

- agent 在**真实分支**上工作，从 base 拉出 feature 分支；
- 每次编辑文件、运行会改动代码的命令、跑测试并修失败，都自动提交，消息由 agent 自己写（`fix:` / `test:` / `refactor:` 这类 Conventional Commits 风格）；
- **author 字段设置为 agent 的身份**，而不是人类用户：

```bash
git config user.name  "Orquesta Agent"
git config user.email "agent@orquesta.local"

```

- 只读命令（`git status`、跑一次看结果的构建）**不产生提交**，因为仓库状态没变，但它们会记进活动流。

收益是**外科手术式回滚**：agent 在同一个会话里既加了一个 API 端点、又修了一个无关 bug，端点引入回归时，你可以只 `git revert <那个提交>`，bug 修复保留下来。

噪声问题他们给两个答案：① 让 agent 把逻辑上同一件事的改动合成一个提交；② 合并前提供 squash 步骤——**执行期间保留每一步，最终历史的整洁度由你决定**。而且中间提交都在 feature 分支上，噪声不会污染 main。

## 六、进程与凭据：把一把钥匙只交给一个 agent

送别最容易忽略的一层：**身份不是"起个名字"，而是"它能读到什么"**。

Bill Mongan 把九种 agent 并排跑在一台小主机上（Ubuntu Server，约 14 GiB 可用内存）：Claude Code、Codex、Antigravity、Grok Build、Hermes、GitHub Copilot、**两份 OpenCode**，还有 **pi**。用 Herdr（一个"认识 agent"的终端复用器）管，**一个 agent 一个标签、一个目录**。

目录分开这件事比他预想的重要：

> 多数 CLI 判断"恢复上次会话"是**相对于当前目录**的，而且几个会要求你先"信任这个工作区"。一个 agent 一个目录，能把这些历史和信任决定隔开，也顺手隔开彼此的草稿文件。

模型侧，大部分 agent 共用一个 mcpproxy 实例拿工具。但有一个服务需要**个人 API key**，而它的数据跟通用 agent 无关。于是：

- provider 同时声明"服务端环境变量"和"调用方请求头"两种取密钥方式；
- proxy 的 `.env` **只放 base URL，不放 key**；
- key 只写在**那一个** OpenCode 的私有环境文件里，由它自己的 MCP 配置以 header 转发：

```jsonc
"mcp": { "servers": { "mcpproxy": {
  "type": "remote",
  "url": "http://127.0.0.1:8888/mcp",
  "oauth": false,
  "headers": { "X-MCPProxy-Service-Key": "{env:SERVICE_API_KEY}" }
}}}

```

- 启动器用一个小 Bash 包装器：`set -a; source service.env; set +a; exec opencode`。`set -a` 保证每个赋值都被导出，`exec` 保证不多留一个 shell 进程持有环境副本。**于是这个变量只存在于这棵进程树里**，其余 agent 的环境里根本没有它。

其余 agent 仍然能看到这个工具，**只是调用时没有 key，服务端拒绝**。需要这个能力时，它们把任务**委派**给那个 OpenCode（`herdr agent prompt` / `herdr agent read`），自己永远不持钥匙。

### 但作者把话说得很清楚：这不是硬边界

- 同一个 Unix 用户下，任何有 shell 的 agent 理论上都能直接读那个 `service.env`；
- header 走的是明文 HTTP，只因为代理监听在 loopback 才可接受；
- 要真正隔离 agent 之间，得**分成不同用户或不同容器**。

所以他的定性是：**这是单用户机器上的"进程级最小权限"，不是安全边界，我也没有当它是。** 它的实际价值是：别的 agent 不会"不小心"用上它，也不会通过某个 dump 环境变量的工具把它泄出去。

（顺带一个细节：那个服务返回个人信息，provider 在到模型之前先用只用 proxy 侧持有的稳定密钥做 HMAC 假名化。稳定很重要，否则跨会话假名会变。）

## 七、身份挡不住的事

这件事必须说清楚，否则你会以为"做完身份就安全了"。Vitruvian 自己写了两起事故：

| 事故                       | 发生了什么                                                                                                                        | 修法                                                                                                                            |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **绕过 merge queue**       | main 允许仓库管理员跳过 merge queue（给人留的应急口子）。跑在那个账号下的 agent **继承了这个 bypass**：两天里 40 次合并有 5 次跳过了队列，其中一次是**8 分钟前刚被队列拒绝**的提交，main 直接变红  | pre-tool hook 拒绝 gh pr merge --admin、拒绝走 REST/GraphQL 直接合并、拒绝直接 push main，并提示 agent "去修队列拒绝的问题"；人真要 bypass 就在自己终端里跑，那里没有 hook |
| **worktree 里卸掉 Argo CD** | homelab 的 Pulumi 配置是 gitignore 的，worktree 里不存在 → 所有开关都读成 false → 一次 pulumi up 把 Argo CD 连同 namespace 和它管的每个 Application 一起删了 | 程序改成"配置没显式声明就拒绝运行"；并把"**永远不要在 worktree 里 apply**"写进 AGENTS.md，**紧挨着事故日期**                                                     |

他们的结论值得整段抄下来：

> **按 agent 分身份是一个"我们遵守的约定"，写在每个 coding 工具都会读的 `AGENTS.md` 里**：用你自己的名字；冒充别的 agent 就是把你的活记到别人头上。它让诚实的活可归属、可 review；它**并不能让不诚实的活变得不可能**。  
>  
> 真正拦住 agent 偷工减料的是另一层：**事故发生之后写下的护栏**。而且每次修都必须带一个"能再抓到它"的检查——这是他们的家规。

同一件事在 Safeguard 2026-10-18 的文章里被归纳成五类风险：**权限继承**（你能 push 生产，它也能）、**审计失真**（日志只显示你）、**提示注入**、**凭据可达**（环境变量和 dotfile 里的 token 对"你跑的任何东西"都可读）、**长会话**（开几天会累积上下文与权限）。

他们的上线建议很实操：**先从最高风险的账号与任务开始**（生产访问、发布、云管理），日常编码先留在沙箱里但**移走长期密钥**；以及一条产品化经验——**如果拿一个受限 token 要花一天和一张工单，开发者就会继续用自己的身份**。工具好不好用，跟策略同样重要。

## 八、周末最小落地清单

按依赖顺序，而不是按重要性：

1. **先定"谁记在历史上"**：给每个 agent 一套 `GIT_AUTHOR_*` / `GIT_COMMITTER_*` 和一个可回指的邮箱；确认 `git log` 里能区分（这一步 10 分钟，收益立刻可见）。
2. **再做"平台认不认"**：一个 agent 一个 GitHub App（manifest flow），私钥进 vault，只用 installation token，安装时选 **Only select repositories**。
3. **把归属写进提交**：要么像 Obi 那样由引擎在收尾时统一写 trailer，要么像 Orquesta 那样一个动作一个 commit + 独立 author。**不要指望 agent 自己记得写。**
4. **收紧钥匙的可见范围**：per-agent 配置目录 / 独立账号 / 独立环境文件；敏感凭据走 header 注入或代理，不落在共享 `.env` 里。
5. **最后才开强制评审**：`requiredApprovals` 是最后一步；之前先确认 agent 之间有"不同身份"可互审。
6. **写护栏，而不是写期望**：把事故日期写进 `AGENTS.md`，每个修法配一个会失败的检查；把"身份当归属，不当强制"当作设计前提。

## 九、附：一人 + 三个 agent 的轻量版

上面四篇的来源都是“团队 + 十几个 agent”，直接搬会很重。如果只是你自己一台机器上加两三个 agent，可以按这个阶梯上：

| 你现在的状态                  | 该做的最小动作                                                    | 为什么够用                                |
| ----------------------- | ---------------------------------------------------------- | ------------------------------------ |
| 三个 agent 共用一个 user.name | 只改环境变量：每个 agent 启动时一套 GIT\_AUTHOR\_\* / GIT\_COMMITTER\_\* | 一小时就能换来可读的 git log，不改任何平台设置          |
| 想让它们互审                  | 加 trailer＋分支前缀（agent/<name>/<topic>）                       | 没有平台身份时，“互审”本质是人工 review；先让“谁写的”可辨   |
| 想让 CI / 保护的规则真正生效       | 才需要 GitHub App（或至少几个独立账号）                                  | App 解决的是“平台承认两个身份不同”，这是唯一无法用环境变量替代的事 |
| 有敏感凭据                   | 一 agent 一个配置目录 + 一个环境文件（0600）                              | 让 key 只进一棵进程树，剩下的 agent 连“误用”的机会都没有  |

最小可执行版本（bash 里包一层，不动全局配置）：

```bash
# ~/bin/agent-run —— 用法：agent-run wren claude
agent-run() {
  local name="$1"; shift
  export GIT_AUTHOR_NAME="$name"
  export GIT_AUTHOR_EMAIL="$name@agents.local"
  export GIT_COMMITTER_NAME="$name"
  export GIT_COMMITTER_EMAIL="$name@agents.local"
  export PI_CODING_AGENT_DIR="$HOME/.pi/agents/$name"   # 换成对应工具的配置目录变量
  exec "$@"
}

```

再配一个会失败的检查（否则你不知道自己有没有设对）：

```bash
git log -1 --format='%an <%ae> | %cn <%ce>'   # 预期：agent 名，而不是你的名字

```

**自检五问**（任一条答不上，说明还差一层）：

1. 出事之后，能不能从 `git log` 里指出**具体是哪个 agent** 写的这一行？
2. 两个 agent 能不能互相批准，而且平台承认它们是两个身份？
3. 某个 agent 被关闭/换掉时，能不能**只吊销它一个**？
4. 如果某个 agent 被提示注入骗了，它最多能推送到哪里？
5. 你的护栏里，有几条是**事故之后**写的，并且各自带一个会失败的检查？

## 十、边界

- 本文是**编译整理**，未独立复现任何一家环境：Vitruvian 的 App 批准实测、Obi 的 trailer 重写、Orquesta 的 git-native 流程、Bill Mongan 的九 agent 单机配置，都是原文作者的实践。
- 各家的具体命名（`vitruvian-*`、`Oby-*`）只是示例；能抄的是**结构**：谁写归属、归属写在哪、凭据放在哪一层。
- 平台的规则会变：GitHub App 是否计入批准、`CODEOWNERS` 是否接受 App，都属于"文档没写、需要自己测"的范畴——**上线前在 canary 仓库上验一遍**，别照抄结论。
- 与"身份"相邻但不等于的东西：沙箱隔离、网络出口限制、审批门。它们解决的是"能做什么"，本文解决的是"做完算谁的"。

---

**相关阅读**：[AI 编程 / Vibe Coding 完全指南](https://www.hubwiz.com/blog/vibe-coding-stack/) ｜ [Agent / MCP / 自动化完全指南](https://www.hubwiz.com/blog/agent-stack/) ｜ [多机并行 coding agent 实战栈](https://www.hubwiz.com/blog/parallel-coding-agents-multi-machine/) ｜ [九起事故与六项控制：谁拿着 Agent 的钥匙](https://www.hubwiz.com/blog/agent-security-nine-incidents-six-controls/) ｜ [Agent 审计日志：让篡改留下形状](https://www.hubwiz.com/blog/agent-audit-logs-witness-suspect/) ｜ [从 LLM 里捞出的真 API Key](https://www.hubwiz.com/blog/llm-api-key-leakage-agent-context/) ｜ [1,866 个项目的 Agent 说明书实测](https://www.hubwiz.com/blog/agents-md-instruction-quality-1866-projects/)

**Sources**

- Vitruvian Software, *Every AI agent gets its own GitHub identity*, 2026-10-09：[https://vitruviansoftware.dev/blog/2026/10/09/every-ai-agent-gets-its-own-github-identity/](https://vitruviansoftware.dev/blog/2026/10/09/every-ai-agent-gets-its-own-github-identity/?ref=hubwiz.com)
- Obi（obi-ai-bot/oby）Issue #1068, *obid: commits say which job, agent and model wrote them*, 2026-10-22：[https://github.com/obi-ai-bot/oby/issues/1068](https://github.com/obi-ai-bot/oby/issues/1068?ref=hubwiz.com)
- Orquesta, *Git-Native AI Development: Every Action is a Commit*, 2026-10-23：[https://getorquesta.com/blog/git-native-ai-development-every-action-is-a-commit-2026-10-23](https://getorquesta.com/blog/git-native-ai-development-every-action-is-a-commit-2026-10-23?ref=hubwiz.com)
- William M. Mongan, *Herding Agents: Multi-Agent Coordination with Herdr and Per-Agent MCP Credentials*, 2026-10-04：[https://www.billmongan.com/posts/2026/10/herdr-multiagent-mcpproxy/](https://www.billmongan.com/posts/2026/10/herdr-multiagent-mcpproxy/?ref=hubwiz.com)
- Safeguard Security Team, *What are the identity risks when an AI coding agent runs as you*, 2026-10-18：[https://safeguard.sh/resources/blog/when-your-ai-coding-agent-runs-as-you-identity-risks-and-fixes](https://safeguard.sh/resources/blog/when-your-ai-coding-agent-runs-as-you-identity-risks-and-fixes?ref=hubwiz.com)
- 背景参考：Sumant Thakur, *I Ran Multiple Coding Agents. The Code Was the Easy Part.*, 2026-09-30：<https://sumantthakur.substack.com/p/multi-agent-coding-workflow>（"可用 / 已认证 / 已证明"三态与"证据包"六项，本文第七、八节受其启发）

*本文由 hubwiz 编译整理，转载请注明出处。*

> **这是「AI 编程 / Vibe Coding」专题的一部分。**完整地图见：[AI 编程 / Vibe Coding 完全指南](https://www.hubwiz.com/blog/vibe-coding-stack/)