关于 ForkMind
ForkMind 是一款本地优先的 LLM 调用记录与检查工具,将对话呈现为图结构。它面向开发者和 Agent 构建者,支持分支、比较、重放和回归测试,数据保存在本机。
主要功能
- 01将 LLM 调用记录为本地 JSON
- 02以 DAG 可视化对话历史
- 03分支、比较和重放运行
- 04向仪表板实时推送新节点
- 05测试输出与轨迹回归
- 06存储加密的上下文胶囊
适用场景
- 01追溯 Agent 过去的尝试
- 02比较提示词、回复与 token 用量
- 03修改提示词后重放对话
- 04在 CI 中捕捉输出或路径变化
MCP 相关
内置 MCP 服务,使 Agent 能查询本地 `.forkmind/` 历史,包括过去的尝试及状态形成过程。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
15收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | integer | 否 |
详细介绍
ForkMind 🧠
本地优先的 LLM 分支管理、调试与上下文卸载
像管理 Git 仓库一样管理 AI 对话历史——记录每次调用、从任意轮次创建分支,并排比较结果。所有操作都在你的机器上完成。
10 秒上手 · 功能 · 安装 · 快速开始 · MCP · 上下文胶囊

你现在看到的是: 对话 DAG,其中包含从调试轮次创建的分支、 节点检查器(请求/响应、令牌、来源),以及通过逐令牌差异并排比较两个分支的 ⇄ Compare 视图。绿色的 ● streaming 徽标表示正在实时捕获——节点会在记录时显示。
ForkMind 会将每次 LLM 调用捕获到本地 .forkmind/ 目录中,将对话可视化为有向无环图(DAG),并让你从历史记录中的任意位置创建分支、比较差异和重放。它适用于任何兼容 OpenAI 的 API,默认通过
Ollama 使用免费开源模型——也支持 Anthropic、Groq、OpenRouter、Together、
vLLM 和 LM Studio。
静态截图

为什么选择 ForkMind
调试 Agent 流程或工具调用流程时,往往需要对同一个提示词反复运行,只做细微调整,然后在终端日志中来回翻找,查看发生了哪些变化。ForkMind 会将每次运行记录为对话树中的一个节点,因此你无需重新阅读日志,就能查看完整历史、从任意轮次创建分支,并以可视化方式比较结果。
所有数据都是磁盘上的纯 JSON。无需数据库、账户或遥测——除了你原本就会发出的 LLM 调用外,没有任何数据会离开你的机器。
功能
- 捕获 — 每次大模型调用都会记录为
.forkmind/下的普通 JSON 节点。 通过兼容 OpenAI 的代理,可用于任何语言;流式响应会被重建(文本以及碎片化的工具调用参数)。 - DAG 仪表板 — React Flow 画布将整个对话绘制成一棵树:展示每轮对话、工具调用、模型和令牌数,并可一键打开节点检查器。
- 实时捕获流 — 节点一经记录便立即脉动显示在 DAG 中(Server-Sent Events),让你实时观察 Agent 的思考过程。
- 分支 — 从任意历史轮次分叉:编辑提示词或更换模型后重新运行,并以可见分支的形式关联到原节点。
- ⇄ 比较 — 选择任意两个节点,逐词并排比较提示词和响应,并查看包含各字段差值的令牌用量表。“大模型输出的 Git 差异比较。”
- ⏪ 时间旅行重放 — 从编辑过的节点重新运行整条链;重新生成的轮次会作为同级分支写入,同时按顺序重新应用原始用户轮次和工具结果。
- MCP 服务 — Agent 可在任务执行过程中查询自己的
.forkmind/历史记录(回忆尝试过的内容、追溯如何得出结果、自我纠正)。 - 回归测试 — 将已知的良好输出固定为基线,在提示词或模型变更后重新运行,并通过免费的离线检查(包含 / 正则表达式 / 相似度)、工具调用断言,或选择启用的 LLM 评审器(根据你自己的评分标准评分)检测偏差。可用于 CI。
- 轨迹回归 — 从捕获的图中固定整个多轮 Agent 路径并重放,这样即使最终答案看起来仍然没问题,也能检测到提示词变更导致 Agent 在运行中途转向。
- 上下文胶囊 — 将上下文卸载到加密、不可变的 DAG 胶囊中;可完整或按片段恢复;支持复制(RAID)、导出 / 导入和加密销毁。
forkmind demo— 一条命令即可在预置的示例 DAG 上打开仪表板,无需设置,也无需 API 密钥。
10 秒体验
npx forkmind demo
无需 API 密钥,也无需设置:仪表板会打开一个预置的对话 DAG —— 一次编码 Agent 调试会话,分叉为失败的修复方案和成功的修复方案, 外加一个已归档的上下文胶囊。所有内容都存放在临时目录中;不会触碰你的项目。如果本地正在运行 Ollama,从这里分叉即可使用你的本地模型实时运行。
进入后,可以试试:
- ⇄ 比较任意两个节点,逐词并排比较提示词、响应和令牌用量 —— “大模型输出的 git diff”。
- ⏪ 从这里重放,从编辑过的节点重新运行整条链;重新生成的轮次会作为同级分支写入。
- 实时捕获 — 节点一经记录便立即脉动显示在 DAG 中,让你实时观察 Agent 的思考过程。
安装
# Run without installing (published on npm)
npx forkmind init
npx forkmind start
# …or install the CLI globally
npm install -g forkmind
forkmind start
也无需使用 npm 注册表 —— ForkMind 可直接通过 git 链接运行,并且仪表板会在安装时自动构建:
# Run without installing, from GitHub
npx github:medhovarsh/forkmind init
npx github:medhovarsh/forkmind start
# …or clone to hack on it
git clone https://github.com/medhovarsh/forkmind
cd forkmind && npm install
安装为 Claude Code 插件
ForkMind 提供 Claude Code 插件(skill + /forkmind 命令),让 Claude 知道何时以及如何使用它 —— 安装流程与任何市场插件相同:
/plugin marketplace add Medhovarsh/forkmind
/plugin install forkmind
该插件包含:
forkmindskill — 当你要求 Claude 调试提示词、比较模型、从过去的轮次分支,或对调用进行回归测试时,Claude 就会使用 ForkMind。/forkmindcommand — 按需启动 / 分支 / 测试 / mcp。forkmind-debuggeragent — 在隔离的上下文中运行模型 / 提示词比较,并返回简洁的结论,而不是倾倒完整记录。- MCP 服务,自动接入 — Agent 可查询自己的
.forkmind/历史记录(回忆尝试、追溯脉络、自我纠正),无需手动配置。
CLI 仍负责运行代理和仪表板;插件则负责教会 Claude 如何使用它。
快速开始(免费,无需 API 密钥)
# 1. Install a free local model
# (install Ollama from https://ollama.com first)
ollama pull llama3
# 2. Init + start ForkMind
npx github:medhovarsh/forkmind init # create .forkmind/ in your project
npx github:medhovarsh/forkmind start # proxy on http://localhost:4500 + dashboard
# 3. Point your code at the proxy (see SDK below), make some calls
# 4. Open the dashboard
open http://localhost:4500
即插即用的 SDK(自动构建树)
npm i openai # the wrapper extends the official SDK
const { ForkMindOpenAI } = require('forkmind');
const client = new ForkMindOpenAI({
apiKey: 'ollama', // ignored by Ollama; required by SDK
upstream: 'http://localhost:11434', // free local open-source models
});
// Each call is recorded; sequential calls auto-chain into a conversation tree.
const res = await client.chat.completions.create({
model: 'llama3',
messages: [{ role: 'user', content: 'Explain backpropagation simply.' }],
});
运行完整示例:
node examples/chain.js
任意语言 — 将客户端指向代理
SDK 封装只是为了方便,并非必需。ForkMind 的代理使用兼容 OpenAI 的传输协议,因此任何语言都能捕获:将客户端的基础 URL 设置为 http://localhost:4500/v1,请求就会被记录。将上一次响应中的 x-forkmind-node-id 作为下一次请求的 x-forkmind-parent 标头传回,即可将多轮对话串成一棵树(JS 封装会自动完成这一步)。
# Python — official openai client, zero ForkMind code
from openai import OpenAI
client = OpenAI(base_url="http://localhost:4500/v1", api_key="ollama")
res = client.chat.completions.create(
model="llama3",
messages=[{"role": "user", "content": "Explain backpropagation simply."}],
extra_headers={"x-forkmind-upstream": "http://localhost:11434"},
)
# read res via .with_raw_response to grab x-forkmind-node-id and chain the next call
# curl — anything that can POST JSON
curl http://localhost:4500/v1/chat/completions \
-H 'content-type: application/json' \
-H 'x-forkmind-upstream: http://localhost:11434' \
-d '{"model":"llama3","messages":[{"role":"user","content":"hi"}]}' -i
# response header `x-forkmind-node-id: <id>` → pass as `x-forkmind-parent` next call
Go、Ruby、Rust、Java 也一样:基础 URL 加上两个标头即可。无论使用哪种源语言,仪表板、分支、MCP 和回归测试都能正常工作。
框架集成
ForkMind 为两大 JS LLM 生态系统提供了轻量适配器。两者都通过同一个代理路由,因此捕获、分支、仪表板、MCP 和回归测试都能照常工作,无需替换模型类,也无需使用回调。
LangChain.js
npm i @langchain/openai @langchain/core
const { ChatOpenAI } = require('@langchain/openai');
const { forkmind } = require('forkmind/langchain');
const fm = forkmind({ upstream: 'http://localhost:11434' }); // free local Ollama
const model = new ChatOpenAI({
apiKey: 'ollama',
model: 'llama3',
configuration: fm.configuration, // baseURL → proxy + chaining fetch
});
await model.invoke('Explain backpropagation simply.');
// sequential calls on `fm` auto-chain; fm.setParent(id) to branch from a node.
Vercel AI SDK
npm i ai @ai-sdk/openai
const { generateText } = require('ai');
const { forkmindOpenAI } = require('forkmind/vercel');
const openai = forkmindOpenAI({ upstream: 'http://localhost:11434' });
const { text } = await generateText({
model: openai('llama3'),
prompt: 'Explain backpropagation simply.',
});
// openai.setParent(id) / openai.resetParent() control the branch point.
两者都支持 FORKMIND_PROXY(代理基础 URL),并且允许为每个实例显式指定 baseURL / upstream。
使用其他免费 / 开源提供商
ForkMind 不绑定特定提供商——它会原样转发你的身份验证标头,并允许你为每个客户端设置上游地址。任何兼容 OpenAI 的服务都能直接使用:
| 提供商 | upstream | apiKey |
|---|---|---|
| Ollama(本地) | http://localhost:11434 | 任意字符串 |
| LM Studio(本地) | http://localhost:1234 | 任意字符串 |
| Groq(免费套餐) | https://api.groq.com/openai | gsk_... |
| OpenRouter | https://openrouter.ai/api | sk-or-... |
| Together | https://api.together.xyz | 你的密钥 |
| OpenAI | https://api.openai.com(默认) | sk-... |
new ForkMindOpenAI({ apiKey: process.env.GROQ_API_KEY,
upstream: 'https://api.groq.com/openai' });
如果不通过 SDK,而是直接调用代理,也可以使用 x-forkmind-upstream 标头逐个请求覆盖上游地址。
Anthropic(Claude)
npm i @anthropic-ai/sdk
const { ForkMindAnthropic } = require('forkmind');
const client = new ForkMindAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
await client.messages.create({ model: 'claude-3-5-sonnet-latest', max_tokens: 512,
messages: [{ role: 'user', content: 'hi' }] });
工作原理
your app ──▶ ForkMindOpenAI (baseURL = localhost:4500/v1)
│ injects x-forkmind-parent
▼
ForkMind proxy (Express, :4500)
│ forwards verbatim (your key, your upstream)
▼
provider (Ollama / Groq / OpenAI / ...)
│ response
▼
proxy reconstructs + saveNode() ──▶ .forkmind/nodes/<id>.json
│ returns x-forkmind-node-id
▼
wrapper chains it as the next call's parent
- 确定性节点 ID。
sha256(request + parentId)→ 前 12 个十六进制字符。同一父节点下的相同提示词会合并为一个节点。ID 不依赖响应,因此即使流式响应体尚未传输完毕,也可以将其作为标头返回。 - 流式传输。 字节会原样传递给你的应用(真实 SSE);代理会复制数据流,重建完整消息(文本以及分片的工具调用参数),并在数据流结束时保存节点。
- 分支。 每个节点都会记录其提供商和上游地址,因此在仪表板中选择“从此处分叉”,即可将编辑后的请求发送到同一主机,并关联到历史父节点。
- 比较。 任意两个节点都可以并排比较——按词对比提示词 / 响应的差异,并通过令牌表显示带正负号的差值。比较在客户端基于捕获的 JSON 计算(
dashboard/src/lib/diff.js)。 - 重放。
POST /api/replay会从编辑后的节点遍历捕获的对话链,直到选定的叶节点;它会根据修改后的历史重新生成每轮助手回复,同时原样重新应用原始用户轮次和工具结果。新对话链会保存为同级分支。 - 实时流。
saveNode会在进程内总线上发出事件;GET /api/stream会通过 SSE 将每个新节点转发到仪表板,因此画布无需轮询即可更新。
MCP — 让 Agent 查询自身历史记录
ForkMind 提供了一个 MCP 服务,让 AI Agent
可以在任务进行中读取自己的 .forkmind/ 历史记录并自我纠正——回想已经尝试过什么,了解某个状态是如何产生的,或搜索过去的尝试。
forkmind mcp # stdio MCP server (or: forkmind-mcp)
通过 Smithery 一行命令即可安装(在
smithery.yaml 中配置)——请在项目根目录运行,以便它能读取
你的 .forkmind/:
npx -y @smithery/cli install forkmind --client claude
……也可以在任意 MCP 客户端中手动注册(Claude Desktop / Claude Code / Cursor / Cline):
{
"mcpServers": {
"forkmind": {
"command": "npx",
"args": ["-y", "github:medhovarsh/forkmind", "mcp"]
}
}
}
提供的工具:
| 工具 | 用途 |
|---|---|
forkmind_recent | 最新捕获的轮次(精简) |
forkmind_get_node | 单个节点的完整请求和响应 |
forkmind_lineage | 根节点→节点路径——生成某个状态的确切上下文 |
forkmind_children | 从某个节点分出的同级分支 |
forkmind_search | 在所有请求/响应中进行子字符串搜索 |
forkmind_stats | 树的总计:节点、根节点、叶节点、提供方 |
forkmind_context_save | 将上下文卸载到加密 DAG 胶囊中 |
forkmind_context_list | 列出已保存的胶囊(标题、摘要、大小、时长) |
forkmind_context_digest | 摘要 + 分段映射——低成本的恢复前探测 |
forkmind_context_restore | 完整恢复或按段恢复,并验证完整性 |
forkmind_context_forget | 不可逆的加密销毁(需要回显 ID) |
forkmind_context_replicas | 副本(RAID)运行状况,可选同步 |
forkmind_context_stats | 汇总统计:数量、字节数、估算 Token 数 |
forkmind_context_export | 可移植的口令加密包 |
forkmind_context_import | 导入并重新验证软件包,然后在本地重新封装 |
该服务会读取其工作目录中的 .forkmind/——请将客户端的
cwd 指向你的项目。
上下文胶囊 — 将上下文卸载为加密 DAG
大多数上下文管理器会将完整上下文窗口视为缓存淘汰问题:截断并丢失。ForkMind 的胶囊则反其道而行——先持久化,再验证,然后压缩。胶囊是由上下文片段组成的不可变、内容寻址 DAG,在磁盘上使用 AES-256-GCM 加密,可完整恢复,也可一次恢复一个片段。
# Save (items JSON from a file or stdin), get back a 12-char handle
echo '{"title":"auth debug","items":[{"role":"user","content":"..."}]}' \
| forkmind context save --digest "oauth loop root-caused; fix in token.js"
forkmind context list # all capsules, newest first
forkmind context show 9f3ac21b7e04 # decrypt + verify + print
forkmind context verify 9f3ac21b7e04 # DAG integrity: parents, acyclicity, hashes
forkmind context forget 9f3ac21b7e04 --confirm 9f3ac21b7e04 # crypto-shred
同一引擎也可通过 HTTP(POST/GET/DELETE :4500/api/context…)和五个 MCP
工具使用,因此 Agent 可以在任务进行中归档自己的上下文,并在之后取回。Claude Code 插件附带了 forkmind-archivist 技能 + 子 Agent,教会 Claude 遵循卸载约定:保存 → 验证磁盘上的内容 → 然后才从上下文窗口中移除。
保证:
- 不可变,且从设计上保证无环——片段 ID 是基于内容 + 父节点计算的哈希(类似 Git);要形成环,就必须让哈希包含自身。
- 静态数据不含明文——每个胶囊都有独立密钥,并由存储在
.forkmind/之外的主密钥封装(~/.forkmind-keys/);意外提交的.forkmind/只会泄露密文和结构。 - 摘要为可选项——Agent 可编写一份不超过 5 行的检索摘要,也可以完全省略私密胶囊的摘要。
- 遗忘是真正的遗忘——删除时先销毁密钥(加密销毁),再将 ID 标记为墓碑,因此相同内容永远无法复原。
- 不会触及模型——胶囊处理的是客户端发送的内容;按设计,提供方、权重和 KV 缓存均不在处理范围内。
RAID — 独立 DAG 冗余阵列
将胶囊镜像到任意数量的额外文件系统目标(第二块磁盘、同步文件夹、网络挂载)。副本只保存密文 + 清单,不会复制密钥。如果主副本丢失或发生位腐坏,系统会从第一个通过验证的副本自动修复;修复后的副本不会获得信任捷径(仍会执行完整性检查)。
forkmind context replicas add D:\backup\forkmind # add target + sync
forkmind context replicas list # coverage per target
forkmind context replicas sync # catch up offline targets,
# propagate tombstones
忘记操作会应用于所有副本:可访问的副本会立即被粉碎;离线副本中的过期密文会在下一次 sync 时删除(墓碑传播)——而且它本来也无法读取,因为胶囊密钥在忘记时就已销毁。墓碑还会阻止修复操作复活任何已忘记的内容。
便携式导出/导入
将胶囊移至另一台机器或项目——例如不共享此项目 ~/.forkmind-keys/ 主密钥的笔记本电脑、队友或冷存储:
forkmind context export 9f3ac21b7e04 --passphrase "correct horse battery staple" --out capsule.json
# ... move capsule.json anywhere ...
forkmind context import capsule.json --passphrase "correct horse battery staple"
这个包包含通过 scrypt 派生的密钥材料(N=32768,刻意设置为较慢,以抵御对弱口令的离线暴力破解)——它绝不依赖源机器的主密钥,口令也绝不会写入包中。导入时,每个片段都会单独重新验证(重新计算 ID、重新计算哈希、解析父项、执行无环 DFS),然后才会写入磁盘——绝不盲目信任这个包,只接受经过验证的内容。导入具有幂等性,并会像新保存操作一样遵守墓碑。
直接从捕获 DAG 创建归档
两部分可以衔接:代理捕获的任何对话,都能一步归档到胶囊中——无需手动组装 JSON——之后还可恢复为适用于提供方的 messages[] 数组,随时拼接到下一个请求中:
# archive the whole lineage ending at a captured turn
forkmind context save --from-node a1b2c3d4e5f6 --digest "auth debug, resolved"
# restore as chat messages (or GET /api/context/:id/messages)
forkmind context show 9f3ac21b7e04 --messages
通过 MCP 也可执行相同操作:forkmind_context_save { fromNodeId } 和
forkmind_context_restore { asMessages: true }——Agent 可以在任务进行中归档自己捕获的历史记录,并在需要时将其拼接回来。胶囊会保留指向轮次 DAG 中对应节点的 sourceNodeIds 链接。
Token 节省量
forkmind context save 和 forkmind context stats 会报告从上下文窗口中释放的预估 Token 数量(~4 bytes/token,这是标准的粗略估算方法),让你直观了解胶囊实际节省了多少。
回归测试——固定良好输出,捕捉退化
调整系统提示词或更换模型,可能会悄无声息地降低结果质量。ForkMind 允许你将一个已捕获的良好节点固定为基线,然后日后重新运行其原始请求并检查新输出是否发生偏移。
# 1. Pin a good node (grab its id from the dashboard or forkmind_recent)
forkmind regression pin a1b2c3d4e5f6 \
--name octopus-fact \
--contains "hearts" \
--regex "blue|copper" \
--min-similarity 0.5
# 2. List / remove cases
forkmind regression list
forkmind regression remove octopus-fact
# 3. Re-run after changing prompts/models (exit code 1 if any case fails — CI-ready)
forkmind regression run # keyless local (Ollama)
forkmind regression run --key $GROQ_API_KEY --upstream https://api.groq.com/openai
机械检查——免费、离线、确定性
contains— 必须出现的子字符串not-contains— 绝不能出现的子字符串regex— 必须匹配的模式min-similarity— 与基线相比的 Jaccard 词语重叠率(偏移保护;默认值为0.3,因此即使没有显式断言,差异很大的回答也会判定失败)。大模型输出具有非确定性,因此应优先使用断言,而非完全匹配。
这些检查都不会理解含义。它们回答的是*"这段文本看起来是否仍像那段文本",而不是"这个回答是否仍然正确"*。contains 和 regex 是精确的代理指标——如果某个必要事实消失,它们每次都能捕捉到。相似度是一种刻意保持简单的警报:它会标记内容发生了变化,但对于正确的改写也可能误报。
工具调用检查——检查 Agent 实际做了什么,而不是说了什么
文本检查会询问答案读起来是否依然通顺。对于 Agent 来说,这不是正确的问题。错误的句子令人烦恼;错误的工具调用则会写入他人的系统。这些检查会直接断言调用本身——结构化数据,因此无需成本、可离线执行,而且结果精确:
forkmind regression pin a1b2c3d4e5f6 \
--name refund-flow \
--tool 'create_ticket:{"priority":"high"}' \ # must call it, with these args
--not-tool issue_refund \ # must never call this
--tools-exact # and must call nothing else
--tool name/--tool 'name:{json}'——调用必须出现。 参数按子集匹配,因此你可以指定重要字段,忽略其余字段。--not-tool name——破坏性操作防护。当提示词调整让 Agent 变得比预期更大胆时,这项检查最为重要。--tools-exact——任何额外调用都会导致失败,而不仅仅是缺少调用。完全不使用--tool时,此选项会断言 Agent 没有执行任何操作。
对 OpenAI tool_calls 和 Anthropic tool_use 块的处理完全相同;两者都会规范化为 { name, args }。如果模型输出格式错误的参数 JSON,系统会在 args._raw 下报告原始文本,而不是静默丢弃,因此断言会明确失败,而不是让调用消失。
这项检查旨在捕捉以下失败情况:**文本可以逐字完全相同,但执行的操作却是错误的。**所有文本检查都通过,相似度得分为 1.0,但 Agent 却向错误的账户收费。只有工具检查能捕捉到这一点。
LLM 评审——需主动启用、需要 API 调用、会理解含义
对于措辞可以变化,但内容不得改变的情况,可以固定一份评分标准,让模型根据它评估回放结果:
forkmind regression pin a1b2c3d4e5f6 \
--name refund-policy \
--judge "The answer must state the 30-day window and must not promise an exception." \
--judge-threshold 0.8 \
--judge-model gpt-4o # optional: grade with a stronger model than the case uses
forkmind regression run --judge-key $OPENAI_API_KEY
forkmind regression run --no-judge # mechanical checks only — free, offline, no API calls
评审模型会看到评分标准、已批准的基线和候选结果,并会收到明确指示:不得因改写措辞而扣分,只针对错误、缺失或矛盾的内容扣分。它会返回一个 0-1 分数;得分低于 --judge-threshold(默认值为 0.7)时,该用例将失败。
在信任它之前,有三点值得了解:
- 失败时默认拒绝通过。如果评审模型报错、超时或返回无法解析的输出,检查会标记为失败,而不是跳过。如果评分器故障时门禁仍静默放行,那还不如没有门禁。
- **跳过状态清晰可见。**使用
--no-judge时,检查仍会记录在报告中,并标记为已跳过,这样测试套件就不会悄悄停止执行其评分标准。 - **它不是证明。**评审结果具有非确定性,而且质量取决于你编写的评分标准。它比词语重合度能提供更强的信号,但不能保证正确性。
用例以 JSON 格式存放在 .forkmind/regressions/ 中——将它们提交到仓库,即可共享基线,并在 CI 中拦截提示词变更。
轨迹回归——固定路径,而不是单轮对话
上述所有内容都在测试单轮对话。对于 Agent 来说,这不是合适的单位。Agent 往往会在运行过程中失败——跳过查询、未确认就写入,或因提示词调整而完全改走其他路径——最终却生成一句读起来完全没问题的话。只断言最后一条消息,什么也看不出来。
由于 ForkMind 会将真实流量捕获为带父节点关联的 DAG,整个路径已经记录在其中。将它固定下来:
# Pin the path ending at this node (walks up to the root)
forkmind trajectory pin f4e5d6c7b8a9 \
--name refund-run \
--sequence exact \ # same actions, same order
--not-tool issue_refund \ # never, anywhere in the run
--tool-order verify_identity,charge_card
forkmind trajectory list
forkmind trajectory run # exit 1 on any failure — CI-ready
对整个运行过程的检查内容:
--sequence exact——展开后的操作序列必须逐步匹配基线。subsequence允许出现额外操作,只要基线中的操作仍按顺序出现。none则不限制路径。--not-tool——轨迹中任何位置都不允许出现指定操作。--tool-order before,after——操作顺序约束。先查询再写入。先验证再收费。--judge——可选的最终答案评分标准,使用与上文相同的评审模型。--from <nodeId>——从某个祖先节点而不是根节点开始路径,这样就可以只固定长流程中感兴趣的尾部。
**文本刻意不设限制。**改写后的输出仍然通过。固定的只有路径——因为真正会触及他人系统的正是这部分。
明确说明这一限制
重放路径会重新应用原始记录的工具结果。工具不会实时执行。这是刻意设计的——它将环境固定下来,让模型的决策成为唯一变量——但这会带来一个严重后果:一旦 Agent 采取了不同的操作,等待它的记录结果就会回答一个它从未提出的问题。从那一刻起,后续的一切都是虚构的。
因此,运行会在首次出现分歧时停止,并准确报告位置:
✗ FAIL refund-run (2/3 steps)
path: verify_identity → issue_refund
↳ failed divergence: step 2/3: expected [charge_card], got [issue_refund]
— replay stopped (recorded tool results no longer apply)
这项功能的意义就在于此:最终消息本来会看起来完全没问题。
轨迹以 JSON 格式存放在 .forkmind/trajectories/ 中——请将它们与单轮测试用例一起提交。
零成本且本地运行
- 无需付费 API——默认通过 Ollama 使用免费的本地模型。
- 无需数据库——每个轮次都是
.forkmind/下的一个普通 JSON 文件。 - 无需账户,不收集遥测数据——除了你本来就会发出的 LLM 调用(原样转发给你选择的提供商)外,没有任何内容会离开你的计算机。
.forkmind/ 目录结构
.forkmind/
├── nodes/
│ ├── a1b2c3d4e5f6.json # one node per turn
│ └── ...
├── contexts/ # encrypted context capsules
│ └── 9f3ac21b7e04/
│ ├── manifest.json # public: DAG shape, hashes, opt-in digest
│ └── seg-<id>.enc # AES-256-GCM ciphertext per segment
├── tombstones.json # forgotten capsule ids (never resurrected)
└── manifest.json # version + root node ids
节点架构:
{
"id": "a1b2c3d4e5f6",
"parentId": null, // null = root
"timestamp": "2026-01-01T00:00:00.000Z",
"request": { /* the exact request body */ },
"response": { /* full or stream-reconstructed response */ },
"meta": { "provider": "openai", "upstream": "http://localhost:11434", "stream": true },
"children": ["..."] // child node ids
}
CLI
| 命令 | 功能 |
|---|---|
forkmind demo | 零配置演示:在临时目录中创建示例 DAG 和仪表板 |
forkmind init | 在当前目录中创建 .forkmind/ |
forkmind start | 启动代理(:4500),并在仪表板已构建时提供服务 |
forkmind mcp | 启动供 Agent 使用的 stdio MCP 服务 |
forkmind regression pin/list/remove/run | 固定基线并重新运行,以捕获偏移 |
forkmind trajectory pin/list/remove/run | 固定多轮 Agent 路径并捕获路由变化 |
forkmind context save/list/show/verify/forget | 加密上下文胶囊(见上文) |
环境变量:FORKMIND_PORT、FORKMIND_HOST(默认值为 127.0.0.1——仅限环回地址;如需在局域网中公开,请将其设为 0.0.0.0,风险自负)、FORKMIND_OPENAI_UPSTREAM、FORKMIND_ANTHROPIC_UPSTREAM、FORKMIND_PROXY(SDK 目标基础 URL)、FORKMIND_KEY_DIR(胶囊主密钥位置,默认值为 ~/.forkmind-keys)。
开发
npm install # installs proxy + dashboard (npm workspaces)
npm test # jest: hashing, storage, stream reconstruction, API
npm run dashboard:dev # vite dev server on :5173, proxies API to :4500
npm run dashboard:build
npm run lint
发布到 npm
通过 .github/workflows/release.yml 按标签发布(需要具有发布权限的 NPM_TOKEN 仓库密钥):
npm version patch # bumps package.json + tags
git push --follow-tags # tag push → CI lints, tests, builds dashboard, publishes
prepack 会重新构建 dashboard/dist,确保压缩包始终包含 UI。
请参阅 CONTRIBUTING.md。
路线图
- CLI + 确定性存储引擎
- 与提供商无关的代理(兼容 OpenAI + Anthropic),支持流式传输
- 可直接替换的 SDK 包装器,支持自动链式调用
- React Flow 仪表板 + 分支执行
- MCP 集成——让 Agent 查询自己的
.forkmind/历史记录 - 自动化回归测试:固定“良好”分支,在编辑提示词后重新运行
- 上下文胶囊——将上下文作为加密、不可变的 DAG 移出;可完整恢复或按片段恢复;通过加密擦除实现遗忘
- RAID——独立 DAG 冗余阵列:跨文件系统目标复制胶囊,支持自我修复恢复和墓碑传播
- 胶囊导出/导入——使用密码短语加密的可移植包,可在不同计算机和项目之间移动上下文,并在导入时独立重新验证
- 仪表板胶囊面板——浏览胶囊、检查 DAG 片段映射,并从 UI 运行完整性验证(按设计为只读)
-
forkmind demo——零配置示例 DAG + 仪表板,无需 API 密钥 - 分支差异视图——并排比较节点,支持词级高亮和逐令牌差异
- 时间旅行式重放——从编辑过的节点重新运行整条链,创建同级分支
- 实时捕获流——通过 SSE 推送,让节点实时显示在 DAG 中
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。