mcpField
F
ForkMind

ForkMind

本地服务
medhovarsh.github.ioAI 与智能体311 周前更新

关于 ForkMind

ForkMind 是一款本地优先的 LLM 调用记录与检查工具,将对话呈现为图结构。它面向开发者和 Agent 构建者,支持分支、比较、重放和回归测试,数据保存在本机。

主要功能

  1. 01将 LLM 调用记录为本地 JSON
  2. 02以 DAG 可视化对话历史
  3. 03分支、比较和重放运行
  4. 04向仪表板实时推送新节点
  5. 05测试输出与轨迹回归
  6. 06存储加密的上下文胶囊

适用场景

  1. 01追溯 Agent 过去的尝试
  2. 02比较提示词、回复与 token 用量
  3. 03修改提示词后重放对话
  4. 04在 CI 中捕捉输出或路径变化

MCP 相关

内置 MCP 服务,使 Agent 能查询本地 `.forkmind/` 历史,包括过去的尝试及状态形成过程。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"forkmind": {
"command": "npx",
"args": [
"-y",
"forkmind"
]
}
}
}
启动命令npx -y forkmind

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmforkmind0.9.0

工具

15

收录的工具列表 · 更新于 3 周前

参数类型必填说明
limitinteger否

详细介绍

ForkMind 🧠

本地优先的 LLM 分支管理、调试与上下文卸载

像管理 Git 仓库一样管理 AI 对话历史——记录每次调用、从任意轮次创建分支,并排比较结果。所有操作都在你的机器上完成。

npm License: MIT CI Node MCP Live site

10 秒上手 · 功能 · 安装 · 快速开始 · MCP · 上下文胶囊

ForkMind 演示——浏览对话 DAG、检查节点,并排比较两个分支

你现在看到的是: 对话 DAG,其中包含从调试轮次创建的分支、 节点检查器(请求/响应、令牌、来源),以及通过逐令牌差异并排比较两个分支的 ⇄ Compare 视图。绿色的 ● streaming 徽标表示正在实时捕获——节点会在记录时显示。

ForkMind 会将每次 LLM 调用捕获到本地 .forkmind/ 目录中,将对话可视化为有向无环图(DAG),并让你从历史记录中的任意位置创建分支、比较差异和重放。它适用于任何兼容 OpenAI 的 API,默认通过 Ollama 使用免费开源模型——也支持 Anthropic、Groq、OpenRouter、Together、 vLLM 和 LM Studio。

静态截图

ForkMind 仪表板——带分支的对话 DAG、流式徽标和节点检查器


为什么选择 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

该插件包含:

  • forkmind skill — 当你要求 Claude 调试提示词、比较模型、从过去的轮次分支,或对调用进行回归测试时,Claude 就会使用 ForkMind。
  • /forkmind command — 按需启动 / 分支 / 测试 / mcp。
  • forkmind-debugger agent — 在隔离的上下文中运行模型 / 提示词比较,并返回简洁的结论,而不是倾倒完整记录。
  • 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 的服务都能直接使用:

提供商upstreamapiKey
Ollama(本地)http://localhost:11434任意字符串
LM Studio(本地)http://localhost:1234任意字符串
Groq(免费套餐)https://api.groq.com/openaigsk_...
OpenRouterhttps://openrouter.ai/apisk-or-...
Togetherhttps://api.together.xyz你的密钥
OpenAIhttps://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 中

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。