Beads:AI Agent 的分布式持久化记忆系统——用 Dolt 为编程 Agent 装上永久大脑
一、背景:当 AI Agent 遇上「金鱼记忆」
如果你用过 Claude Code、GitHub Copilot Workspace 或者任何 AI 编程智能体,你一定遇到过这个令人抓狂的场景:
你花了半小时和 AI agent 一起完成了一个复杂任务,第二天回来问它:「我们昨天做的那个功能现在怎么样了?」—— 它一脸茫然地看着你,仿佛从未见过你。
这不是 AI 的「态度问题」,而是工程上的根本矛盾:大语言模型的上下文窗口是有限的,而真实项目的复杂度是无限的。
当一个 AI coding agent 在处理大型代码库时,会面临三重记忆困境:
上下文窗口瓶颈:一个 50 万行代码的 monorepo,每次只能把几千个 token 塞进 context,超出的部分对 agent 来说就是「不存在」。
跨会话失忆:agent 在一次对话结束后,它对项目的所有理解——哪些文件改了、哪些 bug 修过、哪些决策做过——全部归零。下次启动时一切从零开始。
隐式知识流失:agent 在长任务中积累的「经验」——比如某个 API 的坑、某个模块的结构、某个设计决策的背景——并没有被系统性地记录下来。
这就是 Beads 试图解决的问题。Beads(GitHub 22.3k ⭐,由前 Amazon/Google 工程师 Steve Yegge 主导开发)是一个专为 AI coding agent 设计的分布式持久化记忆系统,它用 Dolt(版本控制的 SQL 数据库)作为存储后端,将 agent 的任务、决策、知识组织成一张可查询、可追踪、可合并的图。
今天这篇文章,我将从架构设计、核心原理、代码实战、性能调优四个维度,对 Beads 进行全面深度的解析。读完你不仅会知道 Beads 怎么用,更重要的是理解它为什么这样设计,以及在你自己的项目中如何落地。
二、Beads 是什么:从「任务列表」到「记忆图谱」
2.1 设计哲学:不做笔记工具,做 Agent 的外部海马体
市面上的 AI 记忆方案五花八门——有的用向量数据库存对话摘要、有的用 Markdown 文件记录上下文、还有的直接把整个对话 history 往 context 里塞。但这些方案都有一个共同问题:它们是「人」的记忆工具,而不是「Agent」的记忆工具。
Beads 的核心设计哲学是:Agent 需要的是结构化的、可操作的、可追踪的知识,而不是原始的文本片段。
打个比方:
- 向量数据库 = 图书馆里把所有书撕成碎片,按关键词分类存放。好处是可以相似搜索,坏处是你不知道这些碎片之间的关联关系。
- Markdown 文件 = 在笔记本上写日记。人类看得懂,但 agent 每次都要全文读取、语义理解,效率极低。
- Beads = 给 Agent 装了一个外部大脑,里面存的不是文字,而是带语义关系的事实网络——「任务 A 依赖任务 B」「模块 X 最近被重构过」「函数 Y 有一个已知 bug」。
Beads 不存储 agent 的思考过程,它存储的是agent 的思考结果中,值得长期保留的知识。
2.2 技术选型:为什么是 Dolt 而不是 PostgreSQL/MongoDB?
Beads 选择 Dolt(一个 Git-like 的 SQL 数据库)作为存储后端,这是一个非常有洞见的技术决策。
Dolt 的核心特性:
| 特性 | 传统数据库 | Dolt |
|---|---|---|
| 版本控制 | 需要额外工具(Flyway/Liquibase) | 内置 commit、branch、diff、merge |
| 冲突处理 | 应用层手动处理 | 自动合并(cell-level merge) |
| 协作模式 | 主从复制 / 分布式锁 | Git-style 分支 + PR 合并 |
| 数据溯源 | 依赖业务表设计 | 每行数据都有 system_commit_* 元数据 |
对于 AI agent 场景,Dolt 的优势尤为突出:
多 Agent 并发写入:当多个 agent 同时在同一个项目工作时(比如一个在做功能开发,一个在修 bug),它们的写入可能在不同的 Dolt 分支上。通过 Dolt 的 merge 机制,可以安全地合并两个人的工作成果,而不会像传统数据库那样产生锁冲突或覆盖丢失。
Cell-level Merge:Dolt 能在行级别做合并——即使两个 agent 修改了同一个 issue 的不同字段,也能自动合并,不需要人工介入。这对于任务追踪系统来说是杀手级特性。
完整的变更历史:每次 bd update 都有完整的 diff,可以随时回溯到任何一个历史状态。对于调试「这个 bug 是怎么引入的」这种问题,git 风格的查询比传统审计表高效得多。
2.3 核心数据模型:Beads 的四层知识图谱
Beads 的数据模型分为四层,从底层到顶层:
Layer 1: 原始数据 (SQL Rows)
└─ 每个 issue/task/message 都是一行带 schema 的 SQL 记录
Layer 2: 关系网络 (Graph Edges)
├─ relates_to — 关联关系(不构成依赖)
├─ blocks — 阻塞关系(A 被 B 阻塞)
├─ parent — 父子层级(Epic → Task → Sub-task)
├─ duplicates — 重复关系
├─ supersedes — 替代关系
└─ replies_to — 回复关系(消息线程)
Layer 3: 语义聚合 (Computed Views)
├─ Ready 队列:no open blockers 的可执行任务
├─ 依赖链:从根 Epic 到叶子 Sub-task 的完整路径
└─ Memory Decay:自动摘要旧任务,释放上下文空间
Layer 4: Agent 接口 (JSON API)
└─ 所有查询通过 `bd` CLI 输出 JSON,供 LLM 解析
这种分层设计的好处是:底层保证数据可靠性和版本控制,中层提供语义聚合,上层提供统一的 agent 接口。Agent 不需要理解 Dolt 的内部细节,它只需要调用 bd ready --json 就能拿到当前所有可执行的任务。
三、架构深度解析:从请求到持久化的完整链路
3.1 整体架构图
┌─────────────────────────────────────────────────────────────┐
│ AI Agent (Claude Code / etc.) │
│ 感知上下文 → 决策 → 调用 bd CLI → 接收结果 │
└──────────────────────────┬──────────────────────────────────┘
│ JSON over stdout
▼
┌─────────────────────────────────────────────────────────────┐
│ bd CLI (@beads/bd) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Parser │→ │ Validator │→ │ Dolt SQL Executor │ │
│ │ (command) │ │ (auth/rbac)│ │ (query engine) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
│ SQL / Branch ops
▼
┌─────────────────────────────────────────────────────────────┐
│ Dolt (Embedded / Server Mode) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ issues messages relations │ │
│ │ ───────── ───────── ───────── │ │
│ │ id id from_id │ │
│ │ title issue_id to_id │ │
│ │ body author relation_type │ │
│ │ status body created_at │ │
│ │ priority message_type from_commit │ │
│ │ assignee created_at to_commit │ │
│ │ created_at closed_at │ │
│ │ closed_at │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
3.2 存储后端:Embedded vs Server 模式
Beads 支持两种存储模式,理解它们的取舍对于生产部署至关重要。
Embedded 模式(默认):
bd init # 在 .beads/embeddeddolt/ 创建本地数据库
- Dolt 以嵌入式库的形式运行在
bd进程内,不需要单独的数据库服务器 - 数据目录:
.beads/embeddeddolt/ - 适用场景:单用户本地开发、CI 环境、小型团队
Server 模式:
bd init --server \
--server-host 127.0.0.1 \
--server-port 3307 \
--server-user root \
--server-password secret
- 连接外部 Dolt SQL Server
- 支持多并发写入(通过 Dolt 的分支合并机制)
- 适用场景:多 Agent 并发、多人协作、需要远程访问
Server 模式的连接配置:
| 参数 | 环境变量 | 说明 |
|---|---|---|
--server-host | BEADS_DOLT_SERVER_HOST | Dolt 服务器地址 |
--server-port | BEADS_DOLT_SERVER_PORT | Dolt 服务器端口,默认 3307 |
--server-user | BEADS_DOLT_SERVER_USER | 数据库用户名 |
--server-password | BEADS_DOLT_PASSWORD | 数据库密码 |
--server-socket | BEADS_DOLT_SERVER_SOCKET | Unix 域 socket(优先于 TCP) |
3.3 分支模型:如何让多个 Agent 和平共处
这是 Beads 最精妙的设计之一。Steve Yegge 把 Git 的分支模型引入到了任务管理中:
# 每个 agent 在自己的工作分支上工作
bd branch create agent-feature-auth # 特性开发分支
bd branch create agent-fix-bug-123 # Bug 修复分支
bd branch create agent-refactor-db # 重构分支
# 在自己的分支上操作,互不干扰
bd update bd-a1b2 --claim # 认领任务(原子操作)
bd create "Implement OAuth2" -p 0 # 创建新任务
# 完成工作后,合并到主分支
bd checkout main
bd merge agent-feature-auth
Dolt 的 cell-level merge 让这个过程非常安全:
-- 假设两个 agent 同时修改了同一个 issue
-- Agent A 在 branch A 上把 priority 改成 P0
-- Agent B 在 branch B 上把 assignee 改成 alice
-- 合并后:priority = P0 AND assignee = 'alice'
-- 两个修改都会被保留,不需要手动解决冲突
这种设计对于 AI agent 的工作模式天然友好——每个 agent 可以独立工作,不需要频繁同步,最终通过 merge 汇聚成果。
3.4 核心命令解析
任务生命周期管理:
# 创建任务(支持层级)
bd create "设计 Auth 模块" -p 0 --type epic # P0 Epic
bd create "实现 JWT 验证" -p 1 --type task -e bd-a1b2 # 挂到 Epic 下
bd create "写单元测试" -p 2 -t bug # P2 Bug 类型
# 状态流转
bd update bd-a3f8.1 --claim # 原子操作:设置 assignee + in_progress
bd update bd-a3f8.1 --status done # 完成任务
bd close bd-a3f8.1 "完成" # 关闭并附上原因
# 依赖管理
bd dep add bd-a3f8.1.1 bd-a3f8.1 # 子任务依赖父任务
bd dep add bd-a3f8.1.1 bd-a3f8.2 # 子任务依赖另一个并行任务
bd dep list bd-a3f8 # 列出所有依赖关系
# Ready 队列(最关键!Agent 每次启动时查询这个)
bd ready --json
# 输出:
# {
# "issues": [
# {
# "id": "bd-a3f8.1.1",
# "title": "实现 JWT 验证",
# "priority": 1,
# "type": "task",
# "status": "open",
# "assignee": null,
# "blocked_by": [],
# "blocks": ["bd-a3f8.1"]
# }
# ],
# "total": 1
# }
消息与线程:
# 发送消息(可以指定线程)
bd msg "这个 API 需要加 retry 逻辑" --thread bd-a3f8.1.1
bd msg "已添加 3xx 重试,review 一下" --thread bd-a3f8.1.1
# 查看线程
bd thread bd-a3f8.1.1
# 输出所有相关消息的完整对话历史
语义压缩(Memory Decay):
# 手动触发压缩
bd prime
# 压缩策略:
# 1. 扫描已关闭的旧任务(超过 30 天)
# 2. 提取关键信息:标题、状态、关键评论
# 3. 生成摘要,替换原始详情
# 4. 保留关系图中的节点,但减少 token 占用
四、代码实战:让 Claude Code 用上 Beads
4.1 安装与初始化
# macOS / Linux
brew install beads
# Node.js 用户
npm install -g @beads/bd
# 验证安装
bd --version
# bd version 1.x.x (built with Dolt 1.x.x)
# 在项目中初始化
cd your-project
bd init
# 告诉 Agent 使用 Beads
echo "Use 'bd' for task tracking. Run 'bd ready --json' to see available tasks." >> AGENTS.md
4.2 Agent 集成:让 Claude Code 知道该做什么
将以下提示注入到 Agent 的系统提示中:
## Task Management
You have access to `bd` (Beads), a distributed memory system for AI coding agents.
Use it to track your work and maintain context across sessions.
IMPORTANT WORKFLOW:
1. At the start of EVERY session: run `bd ready --json` to see what needs to be done
2. Before starting a task: run `bd update <id> --claim` to atomically claim it
3. After completing a task: run `bd close <id> "Done: <summary>"` to mark it done
4. When you discover dependencies: run `bd dep add <child> <parent>`
5. When you find relevant context: run `bd create "Observation: <x>" --type message` to record it
Never lose track of work. Every significant decision or discovery should be stored in Beads.
4.3 自动化工作流:Agent 的「上班打卡」脚本
创建一个 Beads Agent 的日常工作流脚本:
#!/bin/bash
# ~/.beads/agent-workflow.sh
set -e
echo "=== Beads Agent Workflow ==="
echo ""
# 1. 检查 Ready 队列
echo "[1/5] Fetching ready tasks..."
READY=$(bd ready --json)
TASK_COUNT=$(echo "$READY" | jq '.total')
if [ "$TASK_COUNT" -eq 0 ]; then
echo "No ready tasks found."
exit 0
fi
echo "Found $TASK_COUNT ready task(s):"
echo "$READY" | jq -r '.issues[] | " - [\( .id )] \( .title ) (P\(.priority))"'
echo ""
# 2. 认领第一个可用任务
FIRST_ID=$(echo "$READY" | jq -r '.issues[0].id')
FIRST_TITLE=$(echo "$READY" | jq -r '.issues[0].title')
echo "[2/5] Claiming task $FIRST_ID..."
bd update "$FIRST_ID" --claim
echo "Claimed: $FIRST_TITLE"
echo ""
# 3. 查看任务详情和依赖
echo "[3/5] Task details:"
bd show "$FIRST_ID"
echo ""
# 4. 查看相关消息和上下文
echo "[4/5] Related context:"
bd thread "$FIRST_ID" 2>/dev/null || echo "(No messages)"
echo ""
# 5. 启动工作
echo "[5/5] Ready to work. Context loaded."
echo ""
echo "Task: $FIRST_TITLE"
echo "ID: $FIRST_ID"
echo ""
echo "When done, run: bd close $FIRST_ID 'Done: <summary>'"
4.4 多 Agent 协作场景实战
假设你有两个 Claude Code 实例同时在一个 monorepo 上工作:
Agent A(前端):
# 在 feature/frontend-auth 分支工作
bd branch create feature/frontend-auth
bd checkout feature/frontend-auth
# 创建前端相关任务
bd create "实现登录表单 UI" -p 0
bd create "对接 Auth API 前端" -p 1
bd create "添加 session 管理" -p 2
# 认领第一个任务
bd update bd-a1b2 --claim
# ... 工作中 ...
bd close bd-a1b2 "完成登录表单 UI,包含 username/password/remember me"
Agent B(后端):
# 在 feature/backend-auth 分支工作
bd branch create feature/backend-auth
bd checkout feature/backend-auth
# 创建后端相关任务
bd create "实现 JWT 颁发接口" -p 0
bd create "实现 refresh token 逻辑" -p 1
bd create "密码加密与验证" -p 2
# 建立跨分支依赖(这是关键!)
bd dep add bd-a1b2 bd-a2c3 # 前端依赖后端:登录表单依赖 JWT 接口
合并工作:
# 合并到 main
bd checkout main
bd merge feature/backend-auth # 先合并后端
bd merge feature/frontend-auth # 再合并前端
# Dolt 自动处理 cell-level merge
# bd-a1b2 和 bd-a2c3 如果被不同分支同时修改,会自动合并冲突字段
4.5 Dolt SQL 直接查询:高级用法
Beads 的所有数据都在 Dolt SQL 中,可以直接用 SQL 查询:
# 查询所有 P0 任务
bd dolt sql -q "SELECT * FROM issues WHERE priority = 0 AND status != 'closed'"
# 统计每个状态的分布
bd dolt sql -q "
SELECT
status,
COUNT(*) as count
FROM issues
GROUP BY status
ORDER BY count DESC
"
# 查看一个 Epic 下的所有子任务树
bd dolt sql -q "
WITH RECURSIVE task_tree AS (
SELECT id, title, parent_id, priority, status, 0 as depth
FROM issues
WHERE type = 'epic' AND title LIKE '%Auth Module%'
UNION ALL
SELECT i.id, i.title, i.parent_id, i.priority, i.status, tt.depth + 1
FROM issues i
JOIN task_tree tt ON i.parent_id = tt.id
)
SELECT
REPEAT(' ', depth) || title as hierarchy,
id,
status,
priority
FROM task_tree
ORDER BY depth, priority
"
# 查看消息线程(跨 Agent 协作记录)
bd dolt sql -q "
SELECT
m.id,
m.body,
m.created_at,
i.title as issue_title
FROM messages m
JOIN issues i ON m.issue_id = i.id
WHERE m.issue_id = 'bd-a1b2'
ORDER BY m.created_at ASC
"
# 查看版本历史(谁在什么时候改了什么)
bd dolt dolt_log --limit 10
4.6 MCP Server 集成:让 Agent 拥有工具调用能力
对于支持 MCP (Model Context Protocol) 的 Agent,可以通过 beads-mcp 获取 Beads 的工具调用能力:
# 安装 MCP Server
pip install beads-mcp
# 配置 MCP(根据你的 Agent 框架)
# 在 .mcp.json 中添加:
{
"mcpServers": {
"beads": {
"command": "beads-mcp",
"args": ["--db", ".beads/embeddeddolt/"]
}
}
}
MCP Server 暴露的工具包括:
| 工具名 | 参数 | 说明 |
|---|---|---|
bd_create | title, priority, type, parent_id | 创建任务 |
bd_update | id, status?, assignee?, claim? | 更新任务状态 |
bd_ready | 无 | 获取可执行任务列表 |
bd_show | id | 查看任务详情 |
bd_dep_add | child_id, parent_id | 添加依赖关系 |
bd_search | query | 全文搜索任务和消息 |
bd_thread | issue_id | 获取消息线程 |
五、性能优化与生产实践
5.1 大型项目的存储优化
对于超过 1000 个任务的 monorepo,需要关注存储优化:
压缩旧数据:
# 自动压缩策略(建议每周一次 cron)
0 2 * * 0 cd /path/to/project && bd prime --force
# 手动验证压缩效果
bd dolt sql -q "
SELECT
COUNT(*) as total_issues,
SUM(CASE WHEN status = 'closed' THEN 1 ELSE 0 END) as closed,
AVG(LENGTH(body)) as avg_body_length
FROM issues
"
索引优化:
Beads 的 issues 表默认在 status、priority、type 上有索引。对于大量任务,可以添加复合索引:
bd dolt sql -q "
CREATE INDEX idx_issues_status_priority
ON issues (status, priority)
"
bd dolt sql -q "
CREATE INDEX idx_relations_from_to
ON relations (from_id, to_id)
"
5.2 多 Agent 并发写入的冲突处理
当 3 个以上的 Agent 同时在同一个 Dolt 分支上工作时,可能遇到写冲突。Dolt 的 cell-level merge 处理了大部分情况,但某些边界情况需要处理:
场景:两个 Agent 同时 claim 同一个任务
# Agent A
bd update bd-a1b2 --claim # 成功,assignee = "agent-a"
# Agent B
bd update bd-a1b2 --claim
# 失败!任务已被认领
# 错误信息:
# ERROR: Cannot claim issue bd-a1b2: already claimed by agent-a
解决策略:在 Agent 的系统提示中加入冲突处理逻辑:
If you encounter a "cannot claim" error:
1. Run `bd ready --json` again to get an updated task list
2. Pick the next available task from the list
3. If no tasks available, create a new one for exploratory work
4. Never retry a failed claim - always re-query the ready list
5.3 与 Git 集成的最佳实践
Beads 的 .beads/ 目录应该与 Git 仓库一起版本控制:
# .gitignore 中排除(可选,取决于你的工作流)
# 如果你希望 .beads/ 跟随代码一起版本控制,不加 .gitignore
# 如果使用 stealth 模式(不污染 git)
bd init --stealth
# .beads/ 数据库存在项目目录中,但不会有任何 git 操作
# Git hooks 自动同步(推荐配置)
# 在 .git/hooks/pre-commit 中添加:
cat >> .git/hooks/pre-commit << 'EOF'
if git diff --cached --name-only | grep -q "^issues/"; then
bd dolt add .
bd dolt commit -m "Sync issues from git commit"
fi
EOF
chmod +x .git/hooks/pre-commit
5.4 监控与可观测性
# 查看数据库大小
du -sh .beads/
# 查看操作历史
bd dolt dolt_log --limit 20 --format=short
# 查看分支信息
bd dolt dolt_branch
# 查看未合并的更改
bd dolt status
# 清理不需要的分支
bd branch delete feature/old-experiment
六、架构权衡与局限性
诚实地评估,Beads 也有其局限性:
6.1 不适合的场景
超大规模团队(100+ 开发者):Dolt 的 merge 机制在高并发写入时,冲突解决的计算成本会显著上升。如果你需要强一致性的任务锁定,Redmine 或 Linear 仍然是更好的选择。
非编程任务的通用项目管理:Beads 是专为 AI coding agent 设计的,它的 SQL schema 和命令设计都围绕「代码修改」这一场景优化。对于产品需求管理、UI 设计等非编程任务,它的体验不如 Linear 或 Jira。
需要富文本描述的任务:Beads 的 issue body 是纯文本,不支持 Markdown 渲染、图片附件、复选框等富文本特性。
6.2 当前版本的已知限制
No 全文搜索索引:当前的 bd search 是基于 Dolt 的 LIKE 查询实现的,不支持全文索引。对于大型知识库,搜索性能可能不理想。(社区正在讨论集成 SQLite FTS5 或 Tantivy)
单表事务:Beads 的原子操作(如 --claim)在单个 Dolt transaction 内完成,但在极端情况下(网络中断、Dolt 服务崩溃)可能需要手动恢复。
CLI 优先,没有原生 Web UI:Beads 官方没有 Web UI,主要通过 CLI 操作。虽然社区有一些第三方 UI 项目,但官方立场是「CLI 是唯一的一等公民」。
七、横向对比:为什么 Beads 比其他方案更值得投入
| 维度 | 向量数据库 (Pinecone等) | GitHub Issues | Linear | Beads |
|---|---|---|---|---|
| Agent 可读性 | 需要 Embedding 查询 | 需要解析 Markdown | 需要 API | 原生 JSON 输出 |
| 版本控制 | ❌ | ✅ Git history | ❌ | ✅ Cell-level |
| 多 Agent 并发 | 需要外部锁 | PR-based | 付费席位限制 | 原生分支模型 |
| 关系图谱 | 需要手动维护 | 标签/Labels | 泳道 | 原生 Graph |
| 安装复杂度 | 需要部署服务 | 零成本 | 需要账号 | 零成本 CLI |
| 数据自主性 | 第三方托管 | GitHub 托管 | SaaS | 本地/自托管 |
| 长任务追踪 | 差 | 一般 | 差 | 优秀 |
Beads 的核心竞争力在于:它是唯一一个把「多 Agent 并发」「版本控制」「关系图谱」「Agent 原生接口」这四个需求同时满足的系统。
八、总结与展望
Beads 代表了 AI Agent 记忆系统的一个新范式:不是用更多的 token 来弥补记忆不足,而是用结构化的外部知识图谱来扩展 agent 的认知边界。
它的核心价值主张可以归结为三点:
持久化:Agent 的工作成果(任务、决策、知识)不随 session 结束而消失,而是永久存储在版本化的数据库中。
结构化:与向量数据库的「语义相似性」检索不同,Beads 提供的是精确的关系查询——「这个任务被哪些任务阻塞?」「这个 Epic 下有哪些未完成的子任务?」——这些查询对于编程 Agent 来说远比相似性搜索更有价值。
协作友好:Dolt 的分支模型让多个 Agent 可以在不相互干扰的情况下并行工作,最终通过 cell-level merge 安全合并。
展望未来,随着 AI coding agent 从「辅助工具」进化为「自主编程者」,外部记忆系统将成为不可或缺的基础设施。Beads 已经在这个方向上迈出了坚实的一步——它不是终点,而是一个充满可能性的起点。
如果你正在构建 AI coding agent,或者希望现有的 agent 在你的项目中保持长期记忆,我强烈建议你尝试一下 Beads。安装只需一行命令,但它带来的工程价值的提升,远超这个命令的长度。
curl -fsSL https://raw.githubusercontent.com/gastownhall/beads/main/scripts/install.sh | bash
你的下一个 10 万行代码的 monorepo,值得拥有一个真正懂得记忆的 AI 伙伴。
References:
- Beads 官方文档: https://gastownhall.github.io/beads/
- Beads GitHub: https://github.com/gastownhall/beads (22.3k stars)
- Dolt 官方文档: https://docs.dolthub.com/
- Steve Yegge 的博客: https://steve-yegge.medium.com/