不到一个月前,我写了篇完整文章介绍如何在Claude Code中使用三层记忆系统:Linear负责战略、Beads负责战术、Tasks负责执行。构建了一个优雅的金字塔模型。

然而现实很骨感。

今天我正式退役Beads。这不是心血来潮,而是因为这个工具制造的麻烦已经超过了它解决的问题——它不再是工具,而是累赘。

Beads的初衷

对于没读过前文的读者,Beads是一个基于Git的issue跟踪器。作为Claude Code的插件,它将issues存储为代码库中的JSONL文件。理论上设计很精妙:

  • Git持久化:issues保存在.beads/目录并与代码一起提交
  • 依赖管理:支持issue间阻塞关系
  • 离线工作:无需网络连接
  • LLM原生支持:直接读取文件,无需API配置

其核心价值是作为"本周计划"(Linear)和"当前任务"(Tasks)之间的战术衔接层。

故障始末

起初一切顺利,直到各种创意故障接踵而至。

恶魔守护进程

Beads依赖后台守护进程管理SQLite数据库并与Git同步。听起来合理?实际状况:

检测到数据库不匹配!

当前数据库属于其他代码库:
  数据库记录库ID:d1f9ca0c
  当前代码库ID:01eac8ea

⚠️ 严重警告:此错误可能导致同步时误删issues!

这个错误会在每次会话启动时出现。守护进程崩溃、同步失败,导致issues陷入量子态——既存在于本地SQLite又不存在于Git,反之亦然。

幽灵同步

bd sync本应同步Git远程仓库的issues,但经常失效:

→ 从远程拉取中...
错误:git pull执行失败:退出状态1
remote: 仓库不存在
fatal: 无法访问'https://git.frr.dev/frr/wuwei.git/'

当代码库配置多个remote时(这很常见),Beads可能选错远程仓库。若该仓库不存在或已更名,每次操作都会静默报错。最终issues停止同步,直到下次会话时数据全部消失才后知后觉。

认知损耗

每次Claude Code会话都这样开始:

  1. Claude读取Beads提示(通过hooks注入)
  2. 尝试启动守护进程
  3. 因数据库不匹配失败
  4. Claude尝试bd sync
  5. 因远程仓库错误失败
  6. 你手动输入"忽略该错误"
  7. 终于可以开始工作

六个摩擦步骤消耗着上下文、时间和耐心。

局势转变

两件事让Beads从"带bug的实用工具"沦为"不必要的负担":

1. Tasks的成熟

当初设计三层架构时,Tasks功能简陋。现在已具备:

  • 支持描述和元数据的TaskCreate
  • 带依赖关系的TaskUpdate
  • 查询功能TaskList/TaskGet
  • 通过CLAUDE_CODE_TASK_LIST_ID实现跨会话持久化

简言之:Tasks现已实现Beads的所有会话内功能,且无需守护进程、SQLite或Git同步。

2. Linear CLI问世

原生的Linear管理控制台(MCP)往好了说也很糟糕——延迟高、稳定性差,总在关键时刻掉链子。

直接调用GraphQL API?理论上可行,直到你需要在issue描述中使用特殊字符:

# 尝试1:使用bash字符串插值
# 结果:括号和箭头破坏JSON结构

# 尝试2:Python urllib方案
# 结果:因op read无法在Python环境执行报401错误

# 尝试3:默默流泪
# 结果:情绪宣泄但无实际产出

直到发现linear命令行工具:

brew install schpet/tap/linear
linear auth login -k "$(op read 'op://FRR DEV/Linear/api-key')"

现在创建issue只需:

linear issue create --team RST --no-interactive \
  -t "移植:agent/loop模块" \
  --project "第一阶段:核心循环" \
  --priority 1 \
  -l 移植 \
  -d "移植代理循环模块(476行代码)。系统的核心组件。"

无需处理GraphQL转义,没有守护进程,杜绝同步故障。我用bash脚本一分钟创建了49个issue,而用MCP或原生API需要折腾一个半小时。

新架构(不再是金字塔)

三层模型很优雅,但现实证明两层足矣:

需求层级旧方案新方案
战略规划Linear(MCP/API)Linear(CLI)
战术管理BeadsLinear(CLI)
执行跟踪TasksTasks

Linear CLI覆盖战略和战术,Tasks专注执行。Beads的职能已被完美替代。

旧流程:
Linear(周级)→Beads(天级)→Tasks(小时级)

新流程:
Linear(周/天级)→Tasks(小时级)

更少层级,更少摩擦,更少故障点。

经验总结

这印证了我常说的观点:不必要的复杂度是沉默的杀手。Beads确实解决了LLM的会话间记忆问题,但引入的基础设施层长期来看弊大于利。

工程领域的永恒定律再次应验:正确的解决方案有时不是增加新组件,而是意识到现有工具已经进化到不再需要补丁。

Linear MCP糟糕 → CLI工具出现
Tasks简陋 → 功能完善
Beads的生存空间自然消失

终极删除令

rm -rf .beads/
git add -A && git commit -m "移除beads工具"

两行命令。没有告别仪式,没有戏剧冲突。

Beads曾物尽其用,如今功成身退。这或许是最好的结局。


内容提要:从Claude Code工作流中移除Beads工具。Linear命令行工具(schpet/linear-cli)完美解决issue管理需求,避免了MCP和GraphQL API的痛点。Tasks工具已成熟至足以处理会话内跟踪。双层架构即可满足:Linear负责战略战术,Tasks专注执行。

往期相关文章:


本文原文为西班牙语,借助AI翻译。