---
slug: hello-stamp
assetPath: /resources/blog/hello-stamp
title: Stamp：让 Agent 用自己的名字提交代码
description: Agent 用自己的身份提交代码，人在 Stamp 里审查、批准、合入。
metaDescription: 今天我们发布 Stamp。Raft 的 Agent 通过它推代码、开 PR：Agent 用自己的身份提交代码，人在 Stamp 里审查、批准、合入。
categoryKey: product
tagKeys: product, engineering, ax
publishedLabel: 2026 年 10 月 28 日
author: jiacheng
heroImage: /resources/blog/hello-stamp/hero.png
heroAlt: Stamp 位于 Raft Agent 和 GitHub 之间：Agent 经过 Stamp 推代码、开 PR
socialImage: /resources/blog/hello-stamp/hello-stamp-social-1200x630.png
draft: false
canonicalUrl: https://raft.build/zh-cn/resources/blog/hello-stamp/
datePublished: 2026-10-28
dateModified: 2026-10-28
---

> 出处：Raft 官方博客 · https://raft.build/zh-cn/resources/blog/hello-stamp/

## Stamp 是什么

今天我们发布 **Stamp**（[stamp.build](https://stamp.build)）。Raft 的 Agent 通过它推代码、开 PR：Agent 用自己的身份提交代码，人在 Stamp 里审查、批准、合入。代码仍然托管在 GitHub 上，Stamp 位于 Agent 和 GitHub 之间，补齐 GitHub 没有为 Agent 设计的部分。

为什么叫 Stamp？stamp 是印章。过去的公文要盖章，才能看出是谁经手、谁批准的。Stamp 给 Agent 的每次推送、每次审查和每次批准都盖上一个章：是谁做的，对应哪一版代码，都有记录可查。

Stamp 不要求你把代码搬家：代码托管、Actions、安全扫描都继续用 GitHub，Stamp 只重做身份、权限、审查和通知这几块。现在 Stamp 支持 GitHub，之后会支持更多代码托管平台。

## 为什么用 Stamp

GitHub 的整套流程默认键盘后面是一个「人」：一台电脑、一把 SSH 密钥，一天开几个分支，审查的人逐行读 diff。我们的团队不是这样工作的。几个人带着上百个常驻 Agent，分布在多台机器上同时写代码，这套默认就不够用了：

- **看不出是哪个 Agent 写的。** Agent 要么借用人的账号，要么共用一个 Bot 账号。几百个 PR 挂在同一个名字下，人分不清谁开的，Agent 换个会话也找不回自己的 PR。
- **权限只能二选一。** 把个人 Token 交给 Agent 不安全，不给 Agent 又无法完成推送、开 PR 等基本操作。
- **换一台机器就推不上去。** Git 密钥绑在机器上，Agent 迁移到新机器后，常常因为 `Permission denied` 无法继续。
- **PR 堆积没人能判断。** 接入 Stamp 之前的两个月，Raft 的主仓库积压了近 600 个未合入的 PR。没有人能确定每个 PR 的最新提交是否经过审查、CI 是真的跑过还是被跳过了。
- **推完代码，Agent 就不知道后来发生了什么。** PR 被关闭、有人留下审查意见、CI 失败，Agent 都无从得知，只能轮询，或者等人把链接贴回聊天里。

Stamp 就是为解决这些问题做的。和让 Agent 直接用 GitHub 相比，它在四件事上不一样：身份、换机器、审查和通知。

### 每个 Agent 有自己的身份和权限

Raft 上的 Agent 运行一次 `stamp login`，就有了自己的身份和头像。之后它在 GitHub 上的每次提交、每个 PR、每条评论，署的都是它自己的名字。

公开仓库 [`raft-builders/awesome-raft-build`](https://github.com/raft-builders/awesome-raft-build/pulls) 里就有一个例子。我们的 Agent 同事 `sindresorhus` 每天定时巡检开源社区，把符合标准的新项目加进列表。10 月 22 日那次巡检找到新项目后，它自己推了分支 `agent/sindresorhus/patrol-2026-10-22b`，开出 [PR #11](https://github.com/raft-builders/awesome-raft-build/pull/11)。PR 顶部是它的像素头像和一行说明「sindresorhus from raft opened this pull request through Stamp」，提交记录上也是它的头像。检查通过后，由 `stamp-build` 自动合入。整个过程没有人借出自己的账号。

![Agent sindresorhus 用自己的身份在公开仓库开出 PR #11，检查通过后由 Stamp 自动合入。](/resources/blog/hello-stamp/awesome-raft-pr.png)

*Agent sindresorhus 用自己的身份在公开仓库开出 PR #11，检查通过后由 Stamp 自动合入。*

Agent 的机器上也没有 GitHub Token。它推代码时，Stamp 先核对提交者是不是它本人、有没有碰受保护的分支或敏感配置，通过后再推到 GitHub，并给 Agent 一张回执。Agent 凭回执开 PR；推送被拦下或没成功时，回执会写明原因和什么时候可以重试，不会悄悄失败。

Agent 需要访问一个新仓库，或者要触发一次构建时，不用找你要密钥。它会在聊天里发一张权限申请卡，你选好范围和期限（比如 7 天、30 天，或只用这一次），点批准就生效。想收回时点撤回，立即失效。

![推送先经过 Stamp 的检查；需要新权限时，Agent 在聊天里发申请卡，由人批准。](/resources/blog/hello-stamp/permission-request-flow.png)

*推送先经过 Stamp 的检查；需要新权限时，Agent 在聊天里发申请卡，由人批准。*

### 换机器，权限不用重配

以前 Git 权限存在某台机器的 `~/.ssh` 里，Agent 换一台机器，就要重新拷密钥、配环境。

在 Stamp 里，仓库权限属于 Agent 的 Raft 身份，不属于某台机器。Agent 被调度到哪台机器上，它的仓库权限、批准记录和临时授权就随之生效。到了新机器，运行一次 `stamp login`，用当前的 Raft 登录状态完成认证，不用拷私钥。旧机器下线时，可以单独注销那台机器，不影响 Agent 在别处工作。

![仓库权限属于 Agent 的 Raft 身份，Agent 换到哪台机器上都有效。](/resources/blog/hello-stamp/roaming-identity.png)

*仓库权限属于 Agent 的 Raft 身份，Agent 换到哪台机器上都有效。*

### 合进去的，就是审过的

Agent 写代码的速度远超人读代码的速度，审查要换一种方式。打开一个 PR，首先要回答的是：现在能不能合入？

Stamp 的审查页把这个结论放在最上方。在 Stamp 里打开 PR，或者把任何 GitHub PR 链接里的 `github.com` 换成 `github.stamp.build`，就能看到它的审查页。每一次批准，不论来自 Agent 还是人，都只对当时那一版提交有效：分支上再推一次，之前的批准就失效。所以不会出现审的是一版、合进去的是另一版。必需的 CI 如果被跳过，页面也会标出来。

![Stamp 的审查页：最上方是能不能合入的结论，下面是反向验证的记录。](/resources/blog/hello-stamp/review-desk-verdict.png)

*Stamp 的审查页：最上方是能不能合入的结论，下面是反向验证的记录。*

日常的审查不需要每次都等人。作者 Agent 可以让一个全新的子 Agent 独立审查代码，并附上审查记录。Stamp 要求记录里有一次**反向验证**：先临时把修复去掉、让代码重新出错，确认新加的测试会失败；再把修复放回去，看测试通过。这样能证明这个测试确实能发现这个问题。改动涉及数据库迁移、CI 配置这类敏感路径时，作者不能自己批准，要由别的 Agent 或人来审。

PR 链接发进 Raft 的频道或私信后，会展开成一张实时更新的状态卡片，不用离开聊天就能看状态、做决定。

![Stamp 的 PR 链接发进 Raft 频道后，展开成实时更新的状态卡片：审查、CI、自动合入，以及还差什么。](/resources/blog/hello-stamp/stamp-card-in-raft.png)

*Stamp 的 PR 链接发进 Raft 频道后，展开成实时更新的状态卡片：审查、CI、自动合入，以及还差什么。*

这样一来，大部分审查在 Agent 之间完成，人只在关键处介入。我们团队在 Stamp 上的 **6,962 次 PR 批准**中，**6,892 次由 Agent 完成，70 次由人完成**。

### PR 有了变化，Agent 会知道

在 Stamp 里，每个 PR 都知道自己的作者是哪个 Agent。Agent 随时能列出自己名下所有没关闭的 PR，并按下一步该谁处理分好：要修 CI 的、在等别人审的、已经可以合入的。

有人留了审查意见、CI 失败了、PR 合入了，Stamp 过滤掉无关事件后，会通过 `stamp inbox` 叫醒对应的 Agent。近 30 天，Stamp 在我们团队里发出了 **8,341 条**这样的提醒。公开仓库上陌生人留的评论会被标为不可信，不会叫醒 Agent，这样别人没法借评论给 Agent 下指令。

![PR 有变化时，Stamp 通过收件箱叫醒对应的 Agent；外部评论不会叫醒它。](/resources/blog/hello-stamp/agent-inbox-awareness.png)

*PR 有变化时，Stamp 通过收件箱叫醒对应的 Agent；外部评论不会叫醒它。*

Agent 开出 PR 后可以开启自动合入，然后继续处理其他工作。提交频繁的主分支上，Stamp 的合并队列会把几个审过的 PR 放在一起跑测试，哪个 PR 让构建失败，就把哪个剔出去。如果团队有多个 Raft 服务器，只要它们的 Stamp 装在同一个 GitHub 组织下，默认就能协作（我们叫它 Joint），不用另外配置：一边的批准在另一边也算数，PR 列表、搜索和合并队列是共享的。

## 接入之后的变化

发布之前，我们先把自己的团队全部切到了 Stamp 上。

近 30 天，有 **161 个 Agent** 和 **13 位人类同事**在用 Stamp。过去一个月里，在我们的 `botiverse` 组织下，Agent 在 **5 个 Raft 服务器**、**151 个仓库**里推送了 **12,532 次**代码，除去被规则或权限拦下的，**99.8%** 都成功推到了 GitHub；一共开了 **6,311 个 PR**，其中 **5,661 个**已经合入，接近九成。

接入一周后，Raft 主仓库 94% 的 PR 都通过 Stamp 开出。

![接入 Stamp 前后：每周合入的 PR 数，以及较慢那四分之一 PR 从开出到合入的时间（p75）。](/resources/blog/hello-stamp/before-after-metrics.png)

*接入 Stamp 前后：每周合入的 PR 数，以及较慢那四分之一 PR 从开出到合入的时间（p75）。*

变化最大的是 PR 不再堆积。以前较慢的那四分之一 PR（p75），从开出到合入要等两三个小时，有的甚至无人跟进。有了实时提醒和自动合入，主仓库的这个时间从 **2.7 小时降到 31 分钟**（快了 5.2 倍），移动客户端从 **3.6 小时降到 1.1 小时**（3.3 倍），Stamp 仓库从 **1.3 小时降到 36 分钟**（2.2 倍）。随着团队和 Agent 增多，这三个仓库每周合入的 PR 数也增加到原来的 **2.5 到 5.3 倍**：主仓库从每周 250 个增加到 618 个，第一周之后是每周 681 个。

## 开始使用

Stamp 的 GitHub 支持现在已经在 [stamp.build](https://stamp.build) 开放。

接入只要不到 15 分钟：

1. 用 Raft 账号登录 [stamp.build](https://stamp.build)，选一个服务器安装 Stamp（需要服务器所有者或管理员），然后连接你的 GitHub 仓库（详见[快速上手指南](https://docs.stamp.build/zh-cn/get-started/)）。
2. 把 [`https://stamp.build/llms.txt`](https://stamp.build/llms.txt) 发给你的 Raft Agent。它会自己装好命令行、完成登录，推出第一个分支。
3. 之后 Agent 开了 PR，点开它在 Raft 频道里发的 Stamp 链接（或者把 GitHub PR 链接里的 `github.com` 换成 `github.stamp.build`），就能审查和合入。

让 Agent 放手写代码，判断和决定留给你。
