关于 RAWThink
RAWThink 是面向 Claude Code 用户的本地持久记忆 MCP 服务,可让推理与决策延续到后续会话。它结合混合搜索、时间知识图谱和会话交接,将结论及被否决的选项保存在用户自己的文件中。
主要功能
- 01语义与 BM25 混合搜索
- 02记录实体和信念的时间图谱
- 03记录决策及被否决的选项
- 04修订信念并保留历史
- 05导出会话并生成交接内容
- 06按回忆、记录或完整模式配置工具
适用场景
- 01跨会话查找先前的推理
- 02回顾信念或决策如何变化
- 03将项目背景带入下一次会话
MCP 相关
向 MCP 客户端提供搜索、会话和图谱工具。会话生命周期命令面向 Claude Code,搜索和图谱工具则可用于任意 MCP 客户端。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx rawthink-mcpRAWTHINK_VAULTPath to the vault directory holding sessions, qnotes and the knowledge graph.MEMORY_FILE_PATHPath to memory.jsonl. Defaults to <vault>/memory.jsonl.QDRANT_URLQdrant server URL.QDRANT_PATHSet to a directory to run Qdrant embedded instead of via Docker.OLLAMA_URLOllama server URL. Without it, retrieval degrades to sparse-only.OLLAMA_MODELEmbedding model. Changing it requires a full reindex.RAWTHINK_TOOL_PROFILEWhich tools to expose: recall (4, read-only), record (5, the write path), or full (17).RAWTHINK_BM25_STATEPath to the BM25 state file. Defaults to <vault>/.bm25_state.json.RAWTHINK_LOG_LEVELLog level for diagnostics on stderr.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
RAWThink
为 AI 思考伙伴关系提供持久记忆。一个可以与你辩论的知识图谱,能够搜索你历来每次会话的搜索工具,以及一份不仅记录你做了什么决定,还记录你否决了什么的档案。
面向 Claude Code 的 MCP 服务。使用 Python,运行在本地,无需云服务。
问题所在
每次与 AI 对话,都从零开始。你一遍遍解释相同的背景,重新推导相同的结论,再次发现早已做过的决定——而随着窗口滚动,得出这些结论的推理也随之消失。
聊天记录解决不了这个问题。历史记录只是文字稿;你需要的是结构:哪些想法彼此关联,哪些信念你后来已不再认同,考虑过哪些替代方案又放弃了它们,以及原因。
RAWThink 通过三层结构来保存这些内容,并将它们存储在由你掌控的文件中。
功能
混合语义搜索覆盖每次会话和每条笔记——结合 BGE-M3 稠密嵌入与 BM25 稀疏向量,并通过 RRF 融合。询问“我对自由意志有什么看法?”,就能找到相关段落,而不只是匹配关键词。
时间知识图谱中的观察都带有日期和状态。信念可以标记为已失效,并关联到取代它们的内容,因此档案不仅记得你现在的想法,也记得你过去的想法。
会话生命周期管理——关闭命令会导出对话、将实体提取到图谱中,并写入一份交接记录,供下一次会话自动加载。
活跃度衰减——未使用的知识会以约 23 天的半衰期逐渐淡出;访问过的知识则会保持活跃。旧内容仍会保留,只是不再挤占你当前工作的空间。
快速开始
前置条件
- Python 3.10+
- Docker,用于运行 Qdrant——或设置
QDRANT_PATH以启用嵌入式模式 - 安装了
bge-m3的 Ollama:ollama pull bge-m3
安装
pip install rawthink-mcp
rawthink-install # creates ~/rawthink-vault with everything inside
cd ~/rawthink-vault
docker compose up -d # starts Qdrant
rawthink-install 会创建知识库结构、CLAUDE.md、THINKING_DIRECTIVES.md、SETUP.md、docker-compose.yml 和 /rtclose 命令。若要更改位置,请使用 rawthink-install --vault ~/my-vault。
在 Claude Code 中注册
claude mcp add --scope user rawthink -- rawthink-mcp
检查安装
rawthink-doctor
包含 9 项检查,并为每项失败提供修复命令:知识库、图谱架构、BM25 状态格式、Qdrant、索引覆盖率、向量维度、Ollama、MCP 注册。
值得特别了解的是索引覆盖率检查。索引可能中途停止,留下一个看似正常的集合——它确实存在,里面也有数据点,查询也能返回结果。但这些结果只来自知识库的一部分,而没有其他迹象能告诉你这一点。
从 0.x 升级
1.5.0 更改了图谱架构,2.0.0 更改了稀疏索引。 写入任何内容之前,请先迁移图谱:
python -m rawthink_mcp.migrate --path vault/memory.jsonl --guess-domains --heal-dangling
这是一次试运行——它会打印将要进行的更改,但不会写入任何内容。查看报告后,再使用 --apply 重新运行。操作前会先创建带时间戳的备份。
然后重新编码搜索索引,因为 BM25 词条 ID 已更改:
reindex(full=True)
普通的重新索引会跳过未更改的分块,并保留旧编码。若此操作仍未完成,rawthink-doctor 会提示你。
更改内容及原因请参见 CHANGELOG.md。
首次会话
> search_thoughts("what have I decided about caching?")
> record_decision(
name="api/cache: read-through",
domain="software",
decided="read-through cache in front of the read model",
because="the write path is already the bottleneck; adding invalidation there costs more",
rejected=["write-through — couples the write path to cache health",
"no cache — p99 was 400ms against a 200ms SLO"]
)
使用 /rtclose 结束会话。它会导出对话,将值得保留的内容提取到图谱中,并留下交接记录供下次使用——下一次会话会自动加载该记录。
架构,以及它为何如此设计
这部分值得了解,因为正是它让图谱能够跨越数年而非数月保持可查询状态。
角色和主题是分开的字段
entityType 回答这个节点扮演什么角色。这是一个包含十项的封闭列表:
| type | 用途 |
|---|---|
decision | 作出的选择,以及被否决的备选方案 |
concept | 一个想法、理论、模型或类比 |
finding | 发现或测量到的内容——例如 bug、结果或审计发现 |
rule | 持久有效的约束或需要遵循的模式 |
open-question | 尚未解决、等待证据的问题 |
artifact | 项目、工具、文档、功能或来源 |
insight | 改变了人们看待某事方式的领悟 |
task | 计划要完成的一项工作 |
event | 在某个时间点发生的事情 |
thing | 直接命名的人、物体或物质 |
domain 回答它涉及什么主题:software、music、history、
philosophy、health、writing、neuro、finance、personal、galaxy。
将二者分开并非为了整洁。当一个字段同时承载二者时,类型列表会针对每个主题增加一项——有个真实的知识库因此一度积累了 46 种类型,saglik-bulgusu、teknik-karar 和 bug-pattern 与 karar 并列。到那时,任何内容都无法筛选,因为没有两项对类型含义达成一致。
未知关系类型会被拒绝,而非发出警告
规范词汇表:supports、contradicts、evolved_into、depends_on、
exemplifies、part_of、caused_by、enables、supersedes、related_to、
investigates、informs、uses。
近义词会自动归并——connected_to → related_to、aspect_of →
part_of。其他任何类型都会触发错误。
早期版本会接受未知类型并发出警告。没有任何机制会处理这些警告,结果积累了 56 种仅出现一次的类型。发出警告却仍允许写入,实际上就是以不赞同的口吻表达允许。
认知状态默认为未知
assertion、hypothesis、speculation——未说明时则为 unknown。
unknown 是有意为之。如果某次会话没有确认某事,将其记录为断言就等于把没人提出过的说法升级为事实。迁移也遵循同一规则:144 个未设置认知状态字段的实体被标记为 unknown,而非 assertion。
修订,而非删除
> revise(entity_name="api/cache: read-through",
observations=["read-through cache in front of the read model"],
superseded_by="moved to write-through after the read model split",
superseding_entity="api/cache: write-through")
旧观察会被标记为已失效,注明日期,并关联到取代它的内容。删除工具确实存在,但不属于默认面向 Agent 的配置:如果一个档案会忘记自己的更正,就无法回答它原本要回答的问题。
决策会记录被否决的选项
record_decision 会将 decided、because 和 rejected 保存为可分别查询的观察。被否决的备选方案才是值得保留的部分——选定的内容会永远留在代码中,曾考虑但最终放弃的内容却不会在其他地方留下记录。这正是六个月后会有人提出的问题。
MCP 工具
工具定义从会话的第一个 token 起就占用上下文窗口,因此其占用是持续成本,而不是按调用次数产生的成本。配置文件只加载特定步骤所需的内容。
RAWTHINK_TOOL_PROFILE=recall # 4 tools, ~900 tokens — read-only
RAWTHINK_TOOL_PROFILE=record # 5 tools, ~1750 tokens — the write path
RAWTHINK_TOOL_PROFILE=full # 17 tools, ~4200 tokens — everything (default)
不在当前配置文件中的工具仍是普通函数——可以通过 CLI 和测试调用。它只是不显示在不会调用它的 Agent 面前。
搜索
| 工具 | 功能 |
|---|---|
search_thoughts | 混合搜索。mode="overview" 为每个会话返回一行 |
get_session | 按 ID 获取会话的完整内容 |
store_thought | 将快速笔记保存为 qnote |
reindex | 将知识库重新索引到 Qdrant |
图谱 — 读取
| 工具 | 功能 |
|---|---|
search_nodes | 有界搜索。按 domain 和 entity_type 筛选;报告 total_matched 和 truncated |
open_nodes | 获取特定实体及其关系 |
read_graph | 读取整个图谱,支持分页和摘要模式 |
图谱 — 写入
| 工具 | 功能 |
|---|---|
record | 在一次经过验证的原子调用中记录实体、关系和观察 |
record_decision | 记录一项决定及其被否决的备选方案 |
revise | 将观察标记为已被取代,并关联取代它们的内容 |
create_entities · create_relations · add_observations | 更底层的等效工具 |
invalidate_observations | 修订信念,不添加关系链接 |
delete_entities · delete_observations · delete_relations | 仅适用于 full 配置 |
record() 会在写入前验证整个批次。只要批次中有一项无效,就不会写入任何内容——让图谱处于无人希望的状态,比拒绝写入更糟。关系只能指向已存在的实体,或在同一次调用中创建的实体。
每个工具都带有 MCP 注解(readOnlyHint、destructiveHint、idempotentHint),因此宿主可以区分删除操作和搜索操作。
架构
Claude Code
│ MCP (stdio)
▼
rawthink-mcp
├── search ──► Qdrant dense (BGE-M3) + sparse (BM25), RRF fusion
├── graph ──► memory.jsonl entities, relations, temporal observations
└── export ──► vault/ sessions, qnotes, handoffs as markdown
│
Ollama (bge-m3)
所有内容都在本地运行。知识库是带有 YAML frontmatter 的纯 Markdown 文件——无需插件,即可在 Obsidian 中直观浏览。
为什么图谱采用 JSONL
可读性强、可用 git 对比差异,且没有依赖项。你可以打开并阅读它,文件更改时也能看到有意义的差异——对于旨在保存思考过程的内容来说,这一点很重要。
代价是加载时间:每次读取都会解析整个文件。实体只有几百个时没有问题,随着规模增长则会变慢。达到数万个实体后,SQLite 显然是下一步选择。
会话生命周期
session start handoff loads automatically (SessionStart hook)
↓
think together
↓
/rtclose export → extract entities → write handoff → update MEMORY.md
/rtclose 会将对话导出为整洁的 Markdown,通过 record() 提取实体和关系,写入项目级交接记录,并更新 MEMORY.md。
生命周期命令目前需要 Claude Code。搜索和图谱工具可与任何 MCP 客户端配合使用。
配置
| 设置 | 环境变量 | 默认值 |
|---|---|---|
| Vault 路径 | RAWTHINK_VAULT | ../vault |
| 知识图谱文件 | MEMORY_FILE_PATH | <vault>/memory.jsonl |
| Qdrant URL | QDRANT_URL | http://localhost:6333 |
| Qdrant 嵌入式路径 | QDRANT_PATH | —(设置此项即可跳过 Docker) |
| Ollama URL | OLLAMA_URL | http://localhost:11434 |
| 嵌入模型 | OLLAMA_MODEL | bge-m3 |
| 工具配置 | RAWTHINK_TOOL_PROFILE | full |
| 土耳其语规范化 | RAWTHINK_TURKISH_NORMALIZATION | false |
| 评估集 | RAWTHINK_EVAL_GT | tests/ground_truth.example.json |
词汇表 — ENTITY_TYPES、DOMAINS、RELATION_TYPES、RELATION_ALIASES —
位于 rawthink_mcp/config.py 中。添加一个领域只需改一行。
自定义
CLAUDE.md — 思考伙伴的角色、语气和模式。
THINKING_DIRECTIVES.md — 双方协作的准则。每条规则都是在未能遵守后写下的。
你可以添加自己的规则;这个文件唯一糟糕的版本,就是照做却不理解每条规则为何存在的版本。
这两个文件都会由 rawthink-install 复制到你的 Vault 中。如果编辑仓库中的副本,
请运行 python scripts/check_templates.py — 安装程序会将它们嵌入其中,而同一文档的
两份副本若有差异,会在不知不觉中逐渐偏离。
已知限制
直言不讳,因为只列优点的 README 没什么用。
Ollama 不可用时会降级为仅稀疏检索。 嵌入缓存有助于处理重复查询; 它不是备用方案。检索质量会明显下降。
优雅关闭仅支持 POSIX。 信号处理程序会在收到 SIGINT/SIGTERM 时释放 Qdrant
目录锁和图谱文件锁。Windows 没有真正的 SIGTERM — 终止中的客户端会调用
TerminateProcess,且不会运行任何处理程序 — 因此强制停止可能会留下锁。
Ctrl-C 仍会正常展开调用栈,rawthink-doctor 会报告陈旧锁。
加载时间会随图谱规模增长。 文件发生更改后,首次读取时会解析整个 JSONL。 后续读取会复用以 (mtime, size) 为键的缓存。
尚未在大规模场景下对搜索质量进行基准测试。 之前列出的检索指标从未重新测量,
因此已将其删除,而不是沿用。tests/search_quality.py 会针对合成 Vault 运行,
并报告 MRR/nDCG;将 RAWTHINK_EVAL_GT 指向你自己的评估集,即可得到对你的数据有意义的指标。
路线图
下一步 — 图谱可视化、原生 MCP 会话生命周期支持(使关闭命令不再只适用于 Claude Code)、 支持更多 MCP 客户端,以及一项任何人都能用可再生成数据运行的检索基准测试。
贡献
欢迎提交问题和拉取请求。
如果你更改架构,请一并更改 config.py、migrate.py 中的迁移逻辑以及会话关闭说明。
它们是同一份约定的三个视图;若不作为一组一起编辑,就会悄然出现偏差。
docs/postmortem-bm25-term-drift.md 是最鲜明的例子 — 一个从各个角度看起来都没问题的缺陷,
直到有人分别评估两个检索器后才被发现。
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。