开源项目,通过对每个任务记录「决策理由」和「遗留债务」并做 Embedding,实现语义化搜索和上下文共享,解决 Agent 遗忘执行逻辑的问题。
一个 AI 编程 agent 在任务图中快速推进——一个下午完成十个任务现在已经不稀奇了。每一个任务都涉及真实的决策:"为 MVP 选了 Postgres 而不是 SQLite"、"留下了一个问题:auth 用明文存储 token,这是技术债务"、"选了这个库因为另一个没有 TypeScript 类型支持。"这些推理没有任何一个能留到产生它的会话之后。它不在 diff 里。它不在任何人后来会读的 commit 信息里。下一个会话——或者下一个 agent,或者下一个人——只能从代码出发,必须重新推导原因,或者直接猜,有时候猜错。
代码注释解决不了这个问题。一条注释只能待在它所在的那个文件里,只有打开那个具体文件的人才会读到。它不会在依赖同一决策的其他任务中被呈现出来,而且任何按语义而非文件路径搜索的东西都看不到它。
PacketForge 是任务图的共享记忆:一个小型、自托管的 API,任何 agent、CLI 或编辑器插件都可以读写,这样"上一个任务为什么这么做"就有了一个真实的答案,而不是重新读一遍 diff 然后猜测。
每个任务都有两类笔记附加在上面:
Decisions——为什么它被建成这样。
Debt——它还有什么问题,留给依赖它的部分。
两者都会被 embedding(Gemini 的 gemini-embedding-001,免费额度,无需绑卡——插拔在 one-method 的 EmbeddingProvider 接口后面),这样 GET /graph/search 能按语义而非字面文本找到它们——搜索"cards 怎么建模的",它会呈现那条写着"plain object, no behavior yet"的决策,而不只是包含"model"这个词的行。在同一任务上写一条近重复的决策会自动标记冲突(与已有笔记的余弦相似度)——一个警告,不会拒绝,因为写它的 agent 比一个阈值更能判断。
本轮发布的内容
PacketForge 起步时只是一个纯 API 的 MVP。这一批让它变成了更接近真实基础设施的东西:
多项目。现在一个部署可以服务多个仓库,而不需要每个项目单独部署一个。POST /projects,然后通过 projectId 限定任务范围——在任何地方省略它,一切仍然默认到"default",所以已有内容不会 break。
之前不存在的仪表盘。GET /dashboard——一个看板面板,按实际使用的状态值分组,可点击进入详情面板,一个项目过滤器,一个实时语义搜索框。一个文件,无需构建步骤,不用框架——它只是像其他任何客户端一样调用 PacketForge 自己的 REST API。
MCP,以及为什么没有专用的 n8n node。POST /mcp 将所有读写操作暴露为 Model Context Protocol 工具。n8n 自带一个内置的 MCP Client node,只需一个 URL 就能连接到任何 MCP server——所以一个 n8n workflow 今天就能读写这个图,两边都不需要 PacketForge 专用的集成。
一个 Cursor 适配器,基于现有的 generic-json 适配器——GET /graph/tasks/:id/packet?adapter=cursor 将一个任务的决策和债务渲染成 Cursor 自己的上下文机制所期望的 Markdown 格式,而不是一个 JSON blob。
真正的运维接口:GET /health(真实的数据库检查,不是"进程在跑"),GET /export(整个图作为一个 JSON 文档——这些数据除了数据库哪里都不存,不像代码),以及带可关联 request id 的结构化 JSON 请求日志。
一个按时间顺序的时间线。GET /graph/timeline 将整个图(或一个项目)中的每一条决策和每一笔债务合并成一个信息流,按实际发生的时间排序——"这个 agent 做了什么,按顺序"而不是去每个任务里翻。
审计日志。对任务、决策、债务条目或项目的每次创建/更新/删除现在都会向 GET /audit-log 写入一行——谁动了什么,什么时候,独立于图数据本身。这是一个共享、多 agent 记忆存储在能信任用于任何真实场景之前需要的基础设施,有点无聊但很必要。
限流。写路由有上限(默认 20/min,可按路由配置),通过 @nestjs/throttler 实现——一旦同一时间有多个 agent 能访问它,任何公共写 API 都需要同样的保护。
仪表盘学会了两个新 tab 和第二种语言。Board 还在,但现在与 Timeline tab 和 Audit Log tab 并排——同一页面,同一实时数据,不需要单独的工具。所有内容——标签、空状态、项目选择器——现在也可以用西班牙语渲染,从 header 切换,浏览器端记忆。
无需安装即可试用
上面的链接是一个线上实例——看板、时间线、审计日志,全部都在。它从空状态开始;向它 POST 一个任务(见下面的教程),然后看它实时出现在看板上。这是在决定是否自托管一个之前,看一个 agent 共享任务图实际长什么样的最快方式。它跑在 Render 的免费 tier 上,所以空闲一段时间后第一个请求需要约 50s 唤醒——之后速度正常。
git clone https://github.com/Bryandero98/packetforge
cd packetforge
npm install
docker compose up -d # Postgres 17 + pgvector, one container
cp .env.example .env
npm run db:migrate
npm run start:dev
# Create a task
curl -X POST localhost:3000/graph/tasks \
-H 'Content-Type: application/json' \
-d '{"id": "CARD-MODEL", "title": "Card domain model"}'
# Record why it was built a certain way
curl -X POST localhost:3000/decisions \
-H 'Content-Type: application/json' \
-d '{"taskId": "CARD-MODEL", "note": "Plain object, not a class - no behavior yet"}'
# Search by meaning, not literal text
curl 'localhost:3000/graph/search?q=data+model+for+cards&limit=5'
然后打开 localhost:3000/dashboard,看同一份数据以看板形式呈现。
扩展点是刻意做得很小的:一个新的输出格式就是一个 PacketAdapter 类(参见 src/adapter/adapters/cursor.adapter.ts 看这个模式),一个新的 embedding 模型就是一个 EmbeddingProvider 类。打开 issue 如果你想试试:good first issue。
Repo (MIT): https://github.com/Bryandero98/packetforge
如果你觉得有用,一杯 Ko-fi 或一点 USDT 对一个独立维护的项目帮助很大——两者都在仓库的 README 中有链接。