Paperclip 活动日志怎么查:把 Agent 干过的每一次改动追回来
一堆 Agent 在同一家「公司」里跑,最难受的不是它们干错事,而是你事后不知道是谁在什么时候把状态改成了那样。任务莫名其妙从 in progress 掉回待办、某个 Agent 被暂停了却没人承认、预算额度昨天还够今天就见底——这些问题共同的特点是:现场已经没了,你只能靠记录复盘。
Paperclip 对这件事的处理方式是一刀切:所有 mutation(写操作)都进活动日志。官方文档的原话是「Every mutation in Paperclip is recorded in the activity log」,提供的是一条完整的审计线索——发生了什么、什么时候、谁干的。而且这条日志是 append-only 且不可变的(append-only and immutable),也就是说没人能回头把自己的痕迹抹掉,包括 Agent 自己。
这一条设计决定了活动日志在排查流程里的位置:它不是「补充信息」,而是出问题时的第一站。下面按「记什么、长什么样、怎么查、查完怎么用」的顺序过一遍,最后说说文档里没写清、你别自己脑补的几处。
到底哪些操作会被记下来
两份官方文档(board operator 指南和 API 参考)列的清单基本一致,合起来是这些:
| 类别 | 被记录的动作 |
|---|---|
| Issue(任务) | 创建、更新、状态流转、指派、评论创建 |
| Agent | 创建、配置变更、暂停、恢复、终止 |
| 审批 | 审批项的创建,以及通过 / 驳回的决定 |
| 预算 | 预算变更 |
| 公司 | 公司配置变更 |
值得注意的是评论:Agent 之间在任务下的沟通,本身就算一次 mutation,会进日志。所以你回溯一条任务时,看到的不只是状态跳变,还有中间那些交流的时间点。这对判断「Agent 是真卡住了还是在等别人回话」很关键。
另一件事是审批。审批的创建和裁决都在日志里,意味着「谁批的」这个问题永远有答案。如果你正被审批卡住的问题困扰,活动日志是确认「这条审批到底有没有被创建出来」的最直接手段——很多时候卡住不是没人批,而是审批压根没生成。
预算变更同样进日志。当你发现预算或 token 支出对不上账时,先在活动日志里确认额度是不是被谁手动调过,再去看成本报表,顺序别反了。
一条活动记录有哪些字段
API 文档给出的字段表是这样的:
| 字段 | 含义 |
|---|---|
actor | 执行这个动作的 Agent 或用户 |
action | 做了什么(created、updated、commented 等) |
entityType | 被影响的实体类型 |
entityId | 被影响实体的 ID |
details | 变更的具体内容 |
createdAt | 动作发生的时间 |
board operator 指南里描述同一个结构时,措辞略有不同:它把 Details 解释为「specifics of the change (old and new values)」,也就是变更前后的值都在里面。API 参考那张表只写了 details 是「变更的具体内容」,没展开说结构。想按 details 的内部字段做程序化解析的话,两份文档都没给出具体 schema,得自己打一条真实响应看。
actor 这个字段设计得挺实在:它不区分「人」和「Agent」,统一是「执行者」。在一个人和 Agent 混合操作同一批任务的系统里,这样反而省事——你不用先猜是人改的还是 Agent 改的,看 actor 就完了。
Web 端和 API 各能按什么过滤
这两条路径的过滤能力并不相同,这是最容易踩的地方。
Web 端的 Activity 区域在侧边栏,展示的是全公司事件的时间序信息流,支持三个维度过滤:
- Agent
- 实体类型(issue、agent、approval)
- 时间范围
API 是这个接口:
GET /api/companies/{companyId}/activity
查询参数只有三个:
| 参数 | 作用 |
|---|---|
agentId | 按执行者 Agent 过滤 |
entityType | 按实体类型过滤(issue、agent、approval) |
entityId | 过滤到某个具体实体 |
对比一下就能看出差异:API 多了 entityId(可以精确锁定单个任务或单个 Agent 的全部历史),但文档里没有列出时间范围参数,而 Web 端有时间范围过滤。所以「查昨天 14:00 到 15:00 之间发生了什么」这类需求,按文档写明的参数,接口层没有直接对应项;反过来,「把某一条 issue 从头到尾的所有事件拉出来」这种,只有 API 干得了。
调接口前还得先解决鉴权,那部分不在这两份文档里,走的是 Paperclip 的通用 API 总览与鉴权那一套。
官方给的四步排查法
board operator 指南里有一段专门讲「Using Activity for Debugging」,出问题时按这个顺序走:
- 先定位到出问题的 Agent 或任务;
- 把活动日志过滤到这个实体上;
- 沿时间线一路走下来,还原发生了什么;
- 重点检查三类异常:漏掉的状态更新(missed status updates)、失败的 checkout(failed checkouts)、意料之外的指派(unexpected assignments)。
第四步那三项值得单独说,因为它对应的是三种不同的故障形态。
「漏掉的状态更新」通常意味着 Agent 那一侧的流程没走完——活儿可能做了,但状态没回写,看板上就一直挂着。「失败的 checkout」指向的是执行环节没能把工作区拿起来。「意料之外的指派」则是编排层的问题,任务被分给了不该拿它的角色。
三类里前两类经常和 Agent 侧的运行状态纠缠在一起。如果日志显示某个 Agent 在某个时间点之后就再没产生过任何记录,那问题多半不在日志能覆盖的范围内,得转去查心跳与看门狗那条线——活动日志只记「发生了的写操作」,一个彻底不动的 Agent,恰恰是靠「什么都没记」这个空白暴露出来的。
这也是用活动日志的一个心法:既看有什么,也看该有而没有的。一条正常流转的任务,从创建到指派到状态跳变到评论到关闭,时间线上是密的;哪一段突然稀疏了,问题就在那一段的起点。
用起来的几个实际建议
按实体而不是按时间查。全公司的信息流在 Agent 多起来之后噪声很大,与其滚屏幕,不如先拿到出问题那条 issue 的 ID,用 entityId 直接锁死。
先确认动作是否发生,再讨论动作是否正确。很多争论其实卡在第一层——「这个状态到底有没有被改过」。日志是 append-only 的,它给的是确定性答案,不用再靠回忆。
把 actor 当成第一分类维度。同一类异常,如果 actor 全是同一个 Agent,那是这个 Agent 的行为问题;如果 actor 散在多个身上,那更可能是编排规则或配置的问题。
这套机制不解决什么
得把边界说清楚,免得你指望它干它不干的事。
它只记 mutation,不记读操作。 「哪个 Agent 看过哪份资料」这类访问审计需求,不在活动日志的覆盖范围内——文档明确说的是「所有 mutation」,读取不在其中。
日志保留多久,官方文档没说明。 两份文档都没提留存期、归档策略或容量上限。做长期合规审计前,这一条得单独确认。
分页与排序参数,文档没列。 API 只给了三个过滤参数,返回结果的分页方式、默认条数、排序方向都未说明,写脚本拉全量历史前先试探一下实际行为。
entityType 的枚举和被记录的事件类型对不上。 过滤参数里 entityType 只有 issue、agent、approval 三个值,但「什么会被记录」的清单里还包括预算变更和公司配置变更。这两类事件挂在哪个 entityType 下、能不能被过滤出来,文档没有交代。真要查预算改动,别假定 entityType=budget 能用,先拉一批不带过滤的记录看看实际取值。
它是事后工具,不是告警。 活动日志本身不主动推送、不设阈值。想在异常发生时被叫醒,得靠别的机制,日志负责的是「发生之后你能查得清」。
把这几条限制放在心上,活动日志的定位就很清楚了:它是 Paperclip 里最靠得住的一份事实底稿,不可修改、覆盖所有写操作。它不会告诉你该怎么办,但它能保证——不管这家 AI 公司里发生过什么,都留得下痕迹。
延伸阅读
- 从头读起:Paperclip 是什么:一个自己不跑 Agent 的控制平面,怎么管住一整家 AI 公司
- 本专题共 40 篇,完整分组目录见专题页
- Paperclip 仪表盘与状态卡片怎么读:五组指标的口径、数据来源与刷新机制
- Paperclip 公司配置怎么导出导入:包结构、collision 策略与「导入后不自动跑」
本文依据 Paperclip 官方仓库(github.com/paperclipai/paperclip,MIT 协议)的 docs/ 用户文档
与 doc/ 下的规范、运维与连接器手册整理,核对日 2026-08-17。
我们没有部署或运行过 Paperclip,因此不涉及界面外观与操作手感;
部分规范文档描述的是目标架构而非当前实现,文中已就地标注,不构成对实际行为的保证。
请以仓库最新内容为准。