news 2026/9/11 18:57:01

Beads `bd audit` 全解析:用 `.beads/interactions.jsonl` 构建 Agent 交互审计与训练数据集

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Beads `bd audit` 全解析:用 `.beads/interactions.jsonl` 构建 Agent 交互审计与训练数据集

Beadsbd audit全解析:用.beads/interactions.jsonl构建 Agent 交互审计与训练数据集

【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads

bd audit是 Beads(面向编码 Agent 的"记忆升级"工具)提供的可选审计侧车(sidecar)命令,它把 Agent 与 LLM/工具之间的每一次交互以 JSONL 追加式(append-only)格式落盘到.beads/interactions.jsonl。这篇指南将带你完整掌握bd audit recordbd audit label两个子命令的全部参数、启用方式与底层实现原理,并展示如何利用该文件回答"Agent 当时为什么这么做"以及为 SFT/RL 微调生成数据集。

快速导读

  • 核心主题:Beads 的审计日志子系统——一个默认关闭、以 JSONL 存储交互事件的可选侧车文件。
  • 应用场景:审计 Agent 行为("为什么 Agent 要这样做?")与生成训练数据集(SFT/RL 微调)。
  • 你将掌握:如何启用审计、通过record/label写入事件、从 stdin 注入结构化 JSON、理解追加式与标签引用的数据模型,以及其并发安全与随机 ID 的设计细节。

注意:Beads 数据库中的 issue 历史(通过bd history <id> --events查看)始终会被记录;.beads/interactions.jsonl只是面向显式交互捕获的可选补充,二者并存而非互相替代。

bd audit命令总览

命令入口定义在 cmd/bd/audit.go,其定位为"记录和标记 Agent 交互(追加式 JSONL)":

bd audit [flags]

它有两个子命令:

  • bd audit record:追加一条审计交互条目;
  • bd audit label:追加一条标签条目,引用一条已存在的交互。

audit命令自身支持issueIDCompletion参数补全(见 cmd/bd/audit.go),便于在已有 issue 上下文中快速录入。

启用审计:两种开关,默认关闭

审计侧车默认是禁用的,全局默认值在 internal/config/config.go 中定义为audit.enabled=false。启用方式有两种:

# 方式一:持久化配置 bd config set audit.enabled true # 方式二:环境变量(运行时生效,可覆盖配置) BD_AUDIT_ENABLED=1 bd audit record ...

底层判定逻辑见 internal/audit/audit.go:Enabled()优先读取环境变量BD_AUDIT_ENABLED(接受1/t/true/y/yes/on等真值写法),未设置时回落到配置项audit.enabled。若未启用就调用写入接口,会得到明确报错:

audit JSONL sidecar is disabled; set audit.enabled=true or BD_AUDIT_ENABLED=1 to write interactions.jsonl

文件位于仓库的.beads目录下,具体路径由beads.FindBeadsDir()解析得到,固定文件名为interactions.jsonl(常量定义见 internal/audit/audit.go)。.beads目录需包含有效项目元数据(例如metadata.json),测试中即通过写入{"backend":"dolt"}来满足该校验(见 internal/audit/audit_test.go)。

bd audit record:追加一条交互事件

bd audit record [flags]

它的职责是"追加一条审计交互条目"。源码 cmd/bd/audit.go 中,命令执行时优先检测 stdin 是否为管道输入(非字符设备)且未提供任何字段参数,若满足则自动走 stdin JSON 解析分支;否则要求--kind必填。

完整 Flags 参数表

Flag类型默认值说明
--kindstring条目类型(如llm_calltool_calllabel),非 stdin 模式必填
--modelstring模型名称(用于llm_call
--promptstring提示词文本(用于llm_call
--responsestring响应文本(用于llm_call
--issue-idstring关联的 issue id(bd-...
--tool-namestring工具名称(用于tool_call
--exit-codeint-1退出码(用于tool_call),只有>= 0才会写入条目
--errorstring错误字符串(llm_call/tool_call通用)
--stdinboolfalse从 stdin 读取 JSON 对象(必须符合audit.Entry结构)

以上 Flag 的注册见 cmd/bd/audit.go。

使用示例

# 记录一次 LLM 调用 bd audit record --kind llm_call \ --model gpt-4o \ --prompt "summarize this issue" \ --response "The issue is caused by ..." \ --issue-id bd-123 # 记录一次工具调用(含退出码) bd audit record --kind tool_call \ --tool-name bash \ --exit-code 0 \ --issue-id bd-123 # 记录一次失败的工具调用 bd audit record --kind tool_call \ --tool-name bash \ --exit-code 1 \ --error "command not found: foo"

从 stdin 注入结构化 JSON

当命令参数为空且 stdin 被管道输入时(或显式传入--stdin),record会读取整个 stdin 并json.Unmarshalaudit.Entry(见 cmd/bd/audit.go):

echo '{"kind":"llm_call","model":"gpt-4o","prompt":"p","response":"r","issue_id":"bd-123"}' \ | bd audit record --stdin

如果--actor全局参数非空,还会覆盖写入Entry.Actor字段。

输出与成功判定

每次成功写入后,命令默认打印新条目的 ID(形如int-<32位hex>);若传入了--json全局输出开关,则输出{"id":"...","kind":"..."}结构。命令在成功时会触发metrics.NewCommandEvent("audit-record")的遥测事件上报(见 cmd/bd/audit.go)。

bd audit label:为已有交互打标签

bd audit label <entry-id> [flags]

它负责"追加一条引用既有交互的标签条目",entry-id为必填位置参数(cobra.ExactArgs(1),见 cmd/bd/audit.go)。因为文件是追加式设计,标签不会修改原条目,而是生成一条新的kind=label条目,通过parent_id指向父条目。

完整 Flags 参数表

Flag类型默认值说明
--labelstring标签值(如"good""bad"),必填
--reasonstring打标签的原因说明

Flag 注册见 cmd/bd/audit.go。若--label为空会直接报错。

使用示例

# 为某次 llm_call 打上 "good" 标签,并注明原因 bd audit label int-4f8a... --label good --reason "accurate and concise summary" # 为某次失败的工具调用打上 "bad" 标签 bd audit label int-9c21... --label bad --reason "exit code 1 with misleading error"

标签条目写入后同样打印新条目 ID;--json模式输出{"id":"...","parent_id":"...","label":"good"}

数据模型:audit.Entry字段详解

所有条目的底层结构是Entry(见 internal/audit/audit.go),其设计"刻意保持灵活":用Kind+ 类型化字段覆盖常见场景,用Extra承接其余任意扩展数据。JSON 字段(omitempty表示可为空省略):

JSON 字段Go 类型用途
idstring条目唯一 ID,前缀int-+ 128 位随机 hex
kindstring条目类型:llm_call/tool_call/label/field_change
created_attime.Time创建时间(UTC,自动填充)
actorstring执行者标识(可选)
issue_idstring关联 issue id(bd-...,可选)
modelstring模型名(llm_call
promptstring提示词文本(llm_call
responsestring响应文本(llm_call
errorstring错误字符串(llm_call/tool_call
tool_namestring工具名(tool_call
exit_code*int退出码指针(tool_call,仅>=0时写入)
parent_idstring父条目 ID(label类型引用)
labelstring标签值("good"/"bad"等)
reasonstring标签或变更原因
extramap[string]any任意扩展字段

ID 生成:随机而非序号

newID()使用crypto/rand生成 16 字节(128 位)熵,前缀int-(见 internal/audit/audit.go)。源码注释指出:8000 个 ID 的碰撞概率约为 9e-32。这刻意规避了"扫描文件种子化序号计数器"的并发竞态问题——并发测试 internal/audit/concurrency_test.go 中记录了这类下游消费者曾出现的重复序号 bug,而 audit 包因"无序号字段 + 随机 ID"从设计上免疫该问题。

底层写入流程与并发安全

追加式写入:Append

Append(见 internal/audit/audit.go)的完整流程:

  1. 校验条目非 nil 且kind非空;
  2. 调用EnsureFile()确保.beads/interactions.jsonl存在(以O_CREATE|O_EXCL方式创建,已存在则忽略os.ErrExist,绝不截断,见 internal/audit/audit.go);
  3. 为空 ID 生成随机 ID;为空created_at填充time.Now().UTC()
  4. O_APPEND模式打开文件,一次性f.Write(buf.Bytes())写入完整 JSON 行。

关键细节:写入刻意不用bufio.NewWriter分块写入。源码注释说明(internal/audit/audit.go):分块写会拆成多次write()系统调用,在并发O_APPEND场景下会互相穿插、破坏单行完整性;单次写入依赖 POSIXO_APPEND的原子语义(写入小于 PIPE_BUF 即 4096 字节时原子)。同时使用enc.SetEscapeHTML(false)保证 JSON 输出的 HTML 字符不做额外转义。

开关门面:AppendIfEnabled

所有 CLI 路径都走AppendIfEnabled(见 internal/audit/audit.go):未启用时返回错误并不创建文件。测试 internal/audit/audit_test.go 专门验证了禁用状态下不会生成interactions.jsonl

并发正确性的三重验证

并发测试 internal/audit/concurrency_test.go 以 8 个 writer × 1000 条条目并发写入,验证三个不变量:

  1. 返回的 ID 全部唯一(随机 ID,无共享计数器竞态);
  2. 磁盘上每行都是合法 JSON(无撕裂写);
  3. 磁盘 ID 集合与返回 ID 集合一致(无丢失、无重复)。

自动化的字段变更审计:field_change

除了显式record,audit 子系统还提供了程序化钩子LogFieldChange(见 internal/audit/audit.go):当 issue 的字段(状态、负责人、优先级等)发生变化时,best-effort 写入一条kind=field_change的条目(错误被静默忽略,绝不阻塞业务操作),字段值差异放入extraold_value/new_value/field/reason

在 CLI 层,以下操作会自动触发字段变更审计:

  • bd close:状态从旧状态变更为closed,并携带关闭原因(cmd/bd/close.go);
  • bd update:状态、负责人、优先级任一字段变更都会记录(cmd/bd/update.go);
  • Proxied/代理服务器路径同样覆盖:close_proxied_server.goreopen_proxied_server.gogate_proxied_server.go中均调用了LogFieldChange(如重新打开时记录status → open)。

这使.beads/interactions.jsonl不仅能回答"Agent 调用了哪些工具、问了哪些模型",还能回答"issue 的字段在何时被谁改成了什么值"。

用 JSONL 做审计与数据集生成

由于每行是独立的 JSON 对象,可直接用标准命令行工具流式处理:

# 查看所有 LLM 调用 grep '"kind":"llm_call"' .beads/interactions.jsonl # 查看所有工具调用及退出码 grep '"kind":"tool_call"' .beads/interactions.jsonl # 关联父条目(label -> parent) grep '"kind":"label"' .beads/interactions.jsonl # 用 jq 展开 extra 字段(field_change 示例) jq -c 'select(.kind=="field_change") | {id, issue_id, field: .extra.field, old: .extra.old_value, new: .extra.new_value}' .beads/interactions.jsonl

审计场景

  • "为什么 Agent 当时这么做?":通过id关联llm_call的 prompt/response、tool_call的退出码与错误、label的人工评判与 reason,完整还原一次决策链;
  • 文件注释明确说明其设计意图之一是在 git 中版本化并跨克隆共享(见 internal/audit/audit.go),适合团队间共享 Agent 行为日志。

数据集生成场景(SFT/RL 微调)

  • llm_call条目的prompt+response天然构成(输入, 输出)样本对;
  • label条目的good/bad可作为偏好对(RLHF/DPO)的正负信号,parent_id精确指回被评判的样本;
  • reason字段可承载人工或流水线给出的改进说明,作为高质量微调注释;
  • field_change记录可观察 Agent 对 issue 状态机的操作序列,用于行为建模。

注意事项与限制

  • 默认关闭:必须显式bd config set audit.enabled true或设置BD_AUDIT_ENABLED=1,否则所有写入都会报错且不创建文件;
  • 追加式不可变:条目只增不改,打标签只能新增label条目引用父条目,不能回改;
  • 与数据库历史的区别:issue 生命周期历史始终记录在数据库的 events 表中,可通过bd history <id> --events查看;JSONL 侧车是显式交互捕获的补充层,两者数据来源和用途不同;
  • 单行原子性前提:单条 JSON 行需小于 PIPE_BUF(通常 4096 字节),超大的 prompt/response 在极端并发场景下可能越过单次写原子边界——这是设计上已知的权衡;
  • 文件权限:文件以0644创建,目录以0700创建,注释明确这是为了让 JSONL 能通过 git 在克隆与工具间共享。

参考资料

  • 命令实现:cmd/bd/audit.go
  • 数据模型与写入引擎:internal/audit/audit.go
  • 单测(文件创建/禁用不创建/并发不截断):internal/audit/audit_test.go
  • 并发唯一性测试:internal/audit/concurrency_test.go
  • 默认配置开关:audit.enabled=false(internal/config/config.go)
  • 字段变更审计调用点:cmd/bd/close.go、cmd/bd/update.go

【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 18:56:02

OpenProject 开源项目管理:部署到协作完整指南

OpenProject 开源项目管理&#xff1a;部署到协作完整指南 【免费下载链接】openproject OpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue trac…

作者头像 李华
网站建设 2026/9/11 18:53:31

AI产品经理六大核心能力:从大模型原理到落地实战

过去三年&#xff0c;我筛过三百多份想做AI产品经理的简历&#xff0c;面过其中两百多人。聊下来最大的感受不是大家不懂AI技术&#xff0c;而是大多数人的思维方式还停在传统产品经理那套流程里&#xff1a;画原型、写PRD、排版本、催开发。这套东西在确定性业务里没问题&…

作者头像 李华
网站建设 2026/9/11 18:51:46

MATLAB+C++车辆检测系统:无深度学习依赖的可调试实时方案

简介&#xff1a;本资源是一套基于MATLAB实现车辆检测与识别的完整项目源码&#xff0c;面向图像处理初学者及计算机视觉方向的进阶开发者&#xff0c;适用于智能交通、自动驾驶辅助系统等场景下的车辆目标定位与分析任务。压缩包共15个文件&#xff0c;涵盖3个C核心算法文件&a…

作者头像 李华
网站建设 2026/9/11 18:50:30

大模型长对话上下文管理:context-mode模式设计与实践

先说明一下&#xff0c;这篇文章里的“context-mode”不是某个特定开源仓库的名字&#xff0c;而是我在实际项目里因为反复折腾上下文管理&#xff0c;最后沉淀下来的一套设计思路和配套工具。你可以把它理解成一套“对话上下文管理模式”&#xff1a;解决的是大模型应用里最常…

作者头像 李华