Doramagic 项目包 · 项目说明书
thought-mcp 项目
生成时间:2026-05-16 09:07:15 UTC
项目概述
thought-mcp 是一个本地AI记忆工具(Local-AI Memory Tool),旨在为开发者提供完整的知识库管理、代码理解、本地大语言模型集成和自然语言查询能力。该项目通过 SQLite 作为底层存储,结合向量嵌入技术和 Cypher 图查询语言,实现了一个功能完备的个人知识管理系统。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
简介
thought-mcp 是一个本地AI记忆工具(Local-AI Memory Tool),旨在为开发者提供完整的知识库管理、代码理解、本地大语言模型集成和自然语言查询能力。该项目通过 SQLite 作为底层存储,结合向量嵌入技术和 Cypher 图查询语言,实现了一个功能完备的个人知识管理系统。
资料来源:CHANGELOG.md:1-15
核心定位
thought-mcp 扮演着开发者第二大脑的角色,它将代码库、知识文档、工作会话等信息统一纳入管理范围。与传统的笔记工具不同,thought-mcp 具有以下独特优势:
- 代码感知:原生支持多种编程语言的 AST 解析,能够理解代码结构、依赖关系和调用图
- 时间旅行:采用双时态模型(Bi-temporal Model),支持
valid_time和learned_time两种时间维度 - 本地优先:完全运行在本地环境,支持 Ollama、LM Studio 等本地 LLM 和 embedding 服务
- 图数据库能力:通过 Cypher 查询语言实现复杂的知识图谱查询
资料来源:src/thought/layers/code.py:1-20
系统架构
thought-mcp 采用分层架构设计,各层职责明确:
graph TD
subgraph "表示层"
CLI[CLI 命令行]
MCP[MCP 服务器]
TUI[图形界面 TUI]
end
subgraph "应用层"
Router[路由层]
Ask[自然语言查询]
Demo[演示模块]
end
subgraph "领域层"
CodeLayer[代码层]
GraphLayer[图查询层]
MemoryLayer[记忆层]
end
subgraph "摄入层"
Ingest[代码摄入]
GitIngest[Git历史摄入]
ProseIngest[文本摄入]
end
subgraph "存储层"
SQLite[(SQLite)]
Backend[存储后端]
WAL[WAL检查点]
end
CLI --> Router
MCP --> Router
Router --> Ask
Ask --> GraphLayer
CodeLayer --> GraphLayer
Ingest --> Backend
GitIngest --> Backend
Backend --> SQLite各层职责
| 层次 | 组件 | 职责 | 源码位置 |
|---|---|---|---|
| 表示层 | cli.py | 命令行入口,处理用户输入 | src/thought/cli.py |
| 表示层 | MCP 服务器 | 提供 Model Context Protocol 接口 | src/thought/server/ |
| 应用层 | ask 命令 | 自然语言转 Cypher 查询 | src/thought/cli.py |
| 领域层 | CodeLayer | 代码特定查询封装 | src/thought/layers/code.py |
| 领域层 | GraphLayer | 图查询操作核心 | src/thought/layers/graph.py |
| 存储层 | SQLiteBackend | 数据库操作封装 | src/thought/storage/sqlite/backend.py |
资料来源:src/thought/cli.py:1-35 资料来源:src/thought/layers/code.py:1-30
核心功能模块
1. CLI 命令行工具
thought CLI 是用户与系统交互的主要入口,提供以下命令:
| 命令 | 功能 | 源码位置 |
|---|---|---|
thought init | 初始化数据库和配置 | src/thought/cli.py |
thought serve | 启动 MCP 服务器 | src/thought/cli.py |
thought ingest | 摄入实体信息 | src/thought/cli.py |
thought recall | 召回相关记忆 | src/thought/cli.py |
thought ask | 自然语言查询 | src/thought/cli.py |
thought callers | 查找调用者(PageRank排序) | CHANGELOG.md |
thought impact | 计算变更影响范围 | CHANGELOG.md |
thought diff | 比较两个提交间的差异 | CHANGELOG.md |
thought schema | 查看实体类型统计 | src/thought/cli.py |
thought db flush/backup/load/inspect | 数据库生命周期管理 | CHANGELOG.md |
2. 代码理解引擎
thought-mcp 的代码理解能力基于多语言 AST 解析器,支持以下编程语言:
每个语言提取器都能识别以下代码实体类型:
graph TD
subgraph "代码实体类型"
Module[模块/命名空间]
Class[类定义]
Function[函数]
Method[方法]
File[文件]
Import[导入关系]
end
subgraph "代码边类型"
DEFINES[DEFINES - 定义关系]
IMPORTS[IMPORTS - 导入关系]
INHERITS_FROM[INHERITS_FROM - 继承关系]
OVERRIDES[OVERRIDES - 重写关系]
CALLS[CALLS - 调用关系]
end
Class --> DEFINES
Class --> INHERITS_FROM
Module --> IMPORTS资料来源:src/thought/ingest/code/types.py:1-50 资料来源:src/thought/ingest/code/python_extractor.py:1-50
3. 数据模型
thought-mcp 使用双时态数据模型记录实体和边的生命周期:
#### Entity 实体模型
class Entity(BaseModel):
id: str
type: str
name: str
canonical_name: str
owner_id: str | None = None
scope: ScopeName # shared | private
tier: Tier # hot | warm | cold
importance: float # 0.0 ~ 1.0
valid_from: datetime # 事实生效时间
valid_until: datetime | None # 事实失效时间
learned_at: datetime # 系统学习时间
unlearned_at: datetime | None
created_at: datetime
last_accessed_at: datetime
access_count: int = 0
attrs: dict[str, object]
资料来源:src/thought/models.py:1-80
#### 双时态模型说明
| 时间维度 | 字段 | 含义 | 使用场景 |
|---|---|---|---|
| 有效时间 | valid_from / valid_until | 事实本身在现实世界生效的时间段 | 查询"某代码在某个时间点是否存在" |
| 学习时间 | learned_at / unlearned_at | 系统何时获知该事实 | 查询"系统在某个时间点知道什么" |
这种设计允许用户进行真正的"时间旅行"查询:
as_of_kind='valid'— "在 X 日期,什么是真实现实?"as_of_kind='learned'— "在 X 日期,系统知道什么?"
4. Git 历史感知摄入
thought ingest-git 命令支持两种摄入模式:
| 模式 | 说明 | 适用场景 |
|---|---|---|
snapshot (默认) | 仅摄入 HEAD 提交 | 快速初始化 |
full | 遍历每个提交,记录每个实体的提交SHA | 完整历史追溯 |
graph LR
A[Git仓库] --> B[GitWalker]
B --> C[逐提交遍历]
C --> D{摄入模式}
D -->|snapshot| E[仅HEAD]
D -->|full| F[所有提交]
E --> G[(SQLite KB)]
F --> GGitWalker 使用纯 Python subprocess 实现,不依赖 pygit2 等本地库。
资料来源:src/thought/ingest/code/git_pipeline.py:1-50
5. 本地 LLM 集成
thought-mcp 支持多种本地 LLM 提供商:
| 提供商 | Embedder 类 | 特点 |
|---|---|---|
| Ollama | OllamaEmbedder | 使用原生 /api/embed 接口,支持批量操作 |
| LM Studio | LMStudioEmbedder | OpenAI 兼容接口 |
| 任意 OpenAI 兼容服务器 | OpenAICompatEmbedder | 通用兼容层 |
配置通过 thought.toml 文件管理:
[llm]
provider = "ollama" # anthropic | ollama | lmstudio | openai-compat | openai
[embedding]
model = "nomic-embed-text" # 或其他 embedding 模型
资料来源:CHANGELOG.md:1-50
6. Cypher 图查询
v0.4.0 引入的 Cypher 查询子集允许直接查询知识图谱:
// 查找某个函数的所有调用者
MATCH (caller)-[:CALLS]->(target {name: 'authenticate_user'})
RETURN caller
// 查找继承链
MATCH (child)-[:INHERITS_FROM*]->(parent)
WHERE child.name = 'MyClass'
RETURN parent
当前限制:Cypher 子集是只读的,写操作仍需通过 remember / ingest / 自动写入钩子。
资料来源:CHANGELOG.md:1-80
使用场景与演示
thought demo 命令提供内置的演示功能,针对不同用户群体:
| 受众 | 演示内容 | 源码位置 |
|---|---|---|
code | Agent/开发者流程,14阶段代码分析演示 | src/thought/demo.py |
writer | 小说家/论文作者,矛盾检测,时间旅行查询 | src/thought/demo.py |
legal | 调查员/律师,证词矛盾图分析 | src/thought/demo.py |
researcher | 学术研究,引用关系分析 | src/thought/demo.py |
all | 运行所有受众演示 | src/thought/demo.py |
技术栈概览
| 组件 | 技术选型 | 用途 |
|---|---|---|
| 数据库 | SQLite + WAL 模式 | 持久化存储 |
| 向量检索 | sentence-transformers / Ollama embed | 语义搜索 |
| 图查询 | Cypher 子集 | 复杂关系查询 |
| AST 解析 | tree-sitter | 多语言代码解析 |
| CLI | Typer + Rich | 命令行界面 |
| 协议 | MCP (Model Context Protocol) | AI 助手集成 |
资料来源:src/thought/ingest/code/python_extractor.py:1-30
版本路线图
| 版本 | 主题 | 资料来源 |
|---|---|---|
| v0.5 | 写作垂直领域,代码理解增强 | CHANGELOG.md |
| v0.6 | 写作功能完善(小说/学术写作) | CHANGELOG.md |
| v0.7 | 调查领域(法律/合规/取证) | CHANGELOG.md |
| v0.8 | 平台功能(图TUI/基准测试/联邦同步) | CHANGELOG.md |
资料来源:CHANGELOG.md:1-100
开发规范
项目遵循以下开发准则:
- 测试策略:使用真实 SQLite 数据库测试,不使用 mock,确保测试与生产环境一致
- 代码风格:显式优于巧妙,注释说明"为什么"而非"做什么"
- PR 规范:一个 PR 一个主题,必须有测试,必须更新 CHANGELOG
- 类型注解:新代码应清晰标注类型
- Linting:提交前必须通过
ruff check src tests
资料来源:CONTRIBUTING.md:1-50
总结
thought-mcp 是一个功能完备的本地 AI 记忆工具,通过以下核心能力为开发者提供知识管理服务:
- 多语言代码理解:支持 Python、TypeScript、Rust、PHP 等语言的 AST 解析
- 双时态模型:支持事实的有效时间和系统学习时间的独立追踪
- 本地优先:无需云服务,完全运行在本地环境
- 图查询能力:通过 Cypher 子集实现复杂关系查询
- 灵活摄入:支持代码、文本、Git 历史等多种数据源的摄入
资料来源:[CHANGELOG.md:1-15]()
安装与快速开始
本页面介绍 thought-mcp 的完整安装流程和快速上手指南。thought-mcp 是一个本地AI记忆工具,通过 SQLite 数据库存储知识库,支持代码图谱查询、Git历史感知摄取和多语言代码解析。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
系统要求
在开始安装前,请确保环境满足以下要求:
| 组件 | 最低版本 | 说明 |
|---|---|---|
| Python | 3.10+ | 项目主语言 |
| Git | 任意版本 | 用于代码仓库摄取 |
| pip / uv | 最新版本 | 包管理器 |
可选依赖项:
| 组件 | 用途 | 安装方式 |
|---|---|---|
| sentence-transformers | 语义向量嵌入 | 可选,未安装时使用确定性嵌入器 |
| Ollama / LM Studio | 本地LLM集成 | 支持OpenAI兼容API |
| tree-sitter | AST代码解析 | 自动安装 |
安装方式
方式一:pip 安装(推荐)
pip install thought-mcp
方式二:源码安装
git clone https://github.com/RNBBarrett/thought-mcp.git
cd thought-mcp
pip install -e .
方式三:Docker 部署
项目根目录包含 Dockerfile,支持容器化部署:
docker build -t thought-mcp .
docker run thought-mcp thought --help
初始化项目
安装完成后,需要初始化 thought-mcp 来创建数据库和配置文件:
thought init
init 命令参数
| 参数 | 默认值 | 说明 |
|---|---|---|
--config | thought.toml | 配置文件路径 |
--db-path | .thought/thought.db | SQLite 数据库路径 |
--embedder | auto | 嵌入器选择:auto、sentence-transformers 或 deterministic |
--write-claude-md | True | 是否生成 CLAUDE.md 供 MCP 客户端使用 |
--quick | False | 跳过首次运行的嵌入器预热 |
初始化过程会执行以下操作:
- 创建
.thought目录 - 初始化 SQLite 数据库文件
- 生成
thought.toml配置文件 - 可选:写入
CLAUDE.md提示文件
核心命令速查
初始化完成后,可以使用以下核心命令:
| 命令 | 功能 |
|---|---|
thought ingest TEXT | 从命令行一次性摄取文本 |
thought recall QUERY | 自然语言查询知识库 |
thought serve | 启动 MCP 服务器 |
thought stats | 查看知识库统计信息 |
thought doctor | 环境健康检查 |
快速开始示例
步骤一:验证安装
thought doctor
此命令会检查环境依赖是否正确安装,包括数据库访问、嵌入器配置等。
步骤二:知识摄取
摄取文本:
thought ingest "今天学习了Python的装饰器模式"
摄取文件:
thought ingest --file ./src/main.py
批量摄取(glob模式):
thought ingest --glob "**/*.py"
从标准输入摄取:
cat files.txt | thought ingest --stdin
资料来源:src/thought/cli.py:100-120
步骤三:查询召回
thought recall "Python装饰器"
recall 命令返回最多 10 条匹配结果,支持以下高级参数:
| 参数 | 说明 |
|---|---|
--as-of | 时间旅行查询,指定历史时间点 |
--scope | 作用域过滤 |
步骤四:运行演示
项目内置多种场景演示:
thought demo [audience]
| audience 参数 | 说明 |
|---|---|
code | Agent/开发者流程,包含 14 阶段代码垂直演示 |
writer | 小说家/论文作者场景,演示双时态模型 |
legal | 法律调查场景,演示矛盾检测 |
researcher | 学术研究场景,Cypher 查询演示 |
all | 运行所有场景 |
代码仓库摄取
thought-mcp 支持深入分析代码仓库,建立代码知识图谱:
基本摄取
thought ingest-git ./my-project
高级选项
| 参数 | 可选值 | 说明 |
|---|---|---|
--mode | snapshot(默认)、full | 快照模式仅摄取HEAD,全量模式遍历所有提交 |
--language | python、typescript、rust、php 等 | 指定语言覆盖自动检测 |
--skip-call-graph | - | 跳过调用图构建 |
摄取流程架构:
graph TD
A[git仓库] --> B[GitWalker遍历]
B --> C{--mode参数}
C -->|snapshot| D[仅获取HEAD]
C -->|full| E[遍历所有提交]
D --> F[代码文件解析]
E --> F
F --> G[语言提取器]
G --> H[CodeEntity + CodeEdge]
H --> I[CallGraph构建]
I --> J[SQLite存储]摄取完成后,可使用以下代码查询命令:
| 命令 | 功能 |
|---|---|
thought callers <name> | 查询直接调用者,按 PageRank 排序 |
thought impact <name> | 变更影响分析,查询传递调用者 |
thought diff --from SHA1 --to SHA2 | 对比两次提交间的实体差异 |
资料来源:src/thought/ingest/code/git_walker.py:1-35
MCP 服务器模式
启动 MCP 服务器供 AI 助手集成使用:
thought serve
传输方式
| 方式 | 命令 | 说明 |
|---|---|---|
| stdio(默认) | thought serve | 标准输入输出通信 |
| HTTP | thought serve --transport streamable-http | HTTP 协议通信 |
服务器启动后会持续运行,等待 MCP 客户端连接。
配置说明
初始化后生成的 thought.toml 配置文件结构:
[database]
path = ".thought/thought.db"
[embedder]
type = "auto" # auto | sentence-transformers | deterministic
[server]
transport = "stdio"
嵌入器配置
| 类型 | 说明 | 依赖 |
|---|---|---|
auto | 自动检测sentence-transformers可用性 | 可选安装 |
sentence-transformers | 语义向量嵌入 | pip install sentence-transformers |
deterministic | 基于文本哈希的确定性嵌入 | 无外部依赖 |
当设置 auto 时,系统会通过 importlib.util.find_spec 检测 sentence-transformers 是否可用,若未安装则回退到确定性嵌入器。
资料来源:src/thought/ingest/code/pipeline.py:40-60
故障排除
doctor 命令检查项
thought doctor 会验证以下项目:
- Python 版本兼容性
- 数据库文件可访问性
- 嵌入器配置有效性
- 必要的目录权限
常见问题
| 问题 | 解决方案 |
|---|---|
| 嵌入器加载失败 | 使用 --embedder deterministic 降级使用 |
| Git仓库检测失败 | 确认目录包含 .git 目录 |
| 数据库锁定 | 检查是否有其他进程正在访问 |
下一步
安装完成后,建议继续阅读以下文档:
- 使用指南 - 深入了解 recall、caller、impact 等高级命令
- 代码图谱分析 - 理解调用图构建和代码实体关系
- 开发指南 - 参与项目开发的代码规范
资料来源:[src/thought/cli.py:1-25]()
系统架构
thought-mcp 是一个基于 SQLite 的本地 AI 记忆工具,采用分层架构设计,核心功能围绕知识库(Knowledge Base)管理、代码实体解析、自然语言查询路由三大模块展开。系统通过 MCP(Model Context Protocol)协议对外提供服务,支持本地 LLM 集成和双时态(bi-temporal)数据模型。资料来源:src/thought/l...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
thought-mcp 是一个基于 SQLite 的本地 AI 记忆工具,采用分层架构设计,核心功能围绕知识库(Knowledge Base)管理、代码实体解析、自然语言查询路由三大模块展开。系统通过 MCP(Model Context Protocol)协议对外提供服务,支持本地 LLM 集成和双时态(bi-temporal)数据模型。资料来源:src/thought/layers/__init__.py
核心架构分层
系统采用四层架构模型,每一层职责明确,通过标准化接口进行通信:
| 层级 | 模块 | 职责 |
|---|---|---|
| 接口层 | CLI / MCP Server | 用户交互、命令解析 |
| 路由层 | Router / Dispatcher | 查询分类、自然语言转 Cypher |
| 业务层 | Layers (Graph, Code, Recall) | 图查询、代码分析、实体检索 |
| 存储层 | SQLite Backend | 数据持久化、向量存储 |
graph TD
A[CLI / MCP Client] --> B[Router / Dispatcher]
B --> C{C 查询类型}
C -->|CODE| D[CodeLayer]
C -->|GRAPH| E[GraphLayer]
C -->|RECALL| F[RecallLayer]
C -->|ASK| G[AskModule]
D --> H[SQLite Backend]
E --> H
F --> H
G --> H
H --> I[(SQLite DB)]资料来源:src/thought/router/dispatcher.py
存储层架构
SQLite Backend
存储层是整个系统的基础,采用 SQLite 作为主数据库,支持向量嵌入存储和双时态数据模型。Backend 提供了实体的创建、更新、查询以及嵌入向量存储的核心接口。资料来源:src/thought/storage/base.py
#### 核心数据模型
系统定义了两种核心数据模型:
Entity(实体)
| 字段 | 类型 | 说明 | |
|---|---|---|---|
| id | str | 实体唯一标识符 | |
| type | str | 实体类型(function, class, method 等) | |
| name | str | 实体名称 | |
| canonical_name | str | 规范化名称 | |
| scope | ScopeName | 作用域(shared/private) | |
| tier | Tier | 热数据层级(hot/cold) | |
| valid_from | datetime | 有效起始时间 | |
| valid_until | datetime \ | None | 有效结束时间(双时态) |
| code_file | str \ | None | 代码文件路径 |
| code_language | str \ | None | 编程语言 |
| code_commit_sha | str \ | None | Git 提交 SHA |
Edge(关系)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | str | 关系唯一标识符 |
| source_id | str | 源实体 ID |
| target_id | str | 目标实体 ID |
| relation_type | str | 关系类型(CALLS, IMPORTS, DEFINES 等) |
存储层核心接口
Backend 提供了以下核心方法来管理实体和关系:
upsert_entity()- 创建或更新实体,身份包含(code_file, code_commit_sha)以区分同名方法find_code_entity()- 通过规范化名称快速查找代码实体store_embedding()- 存储嵌入向量query_similar()- 相似度检索
资料来源:src/thought/storage/base.py
摄入层架构
摄入管道
摄入管道负责将外部数据(代码、文档、法律文本等)转换为统一的实体-关系模型并存储到知识库中。Pipeline 是摄入管道的核心调度器,支持文件级别的原子性写入。资料来源:src/thought/ingest/pipeline.py
graph LR
A[Source File] --> B[Language Detection]
B --> C[Language Extractor]
C --> D[Entities + Edges]
D --> E[Backend upsert]
E --> F[Embedding]
F --> G[(Knowledge Base)]多语言代码解析器
系统为每种支持的编程语言实现了专门的提取器,所有提取器遵循统一的接口规范:
def extract(source: str, file_path: str) -> tuple[list[CodeEntity], list[CodeEdge]]
支持的编程语言及提取器:
| 语言 | 提取器文件 | 提取的实体类型 |
|---|---|---|
| Python | python_extractor.py | module, function, class, method, import |
| TypeScript | typescript_extractor.py | module, function, class, method, import, export, inheritance |
| PHP | php_extractor.py | module, function, class, method, import |
| Rust | rust_extractor.py | module, function, struct, impl, method |
资料来源:src/thought/ingest/code/python_extractor.py
调用图构建
build_call_graph 模块负责解析代码中的函数调用关系,支持多级解析策略:
- 文件内匹配 - 在同一文件中查找被调用函数定义
- 唯一qualified后缀匹配 -
obj.method()匹配唯一的ClassName.method - 跨文件裸名称匹配 - 查找其他文件中定义的顶级函数
- Stub创建 - 当找不到定义时,创建占位实体
资料来源:src/thought/ingest/code/call_graph.py
Git 历史感知摄入
GitWalker 支持两种摄入模式:
- snapshot 模式(默认) - 仅摄入 HEAD 提交内容
- full 模式 - 遍历每个提交,关联实体与对应提交 SHA
这种设计支持双时态查询,可以查询特定时间点的代码状态。资料来源:src/thought/ingest/code/git_pipeline.py
业务层架构
Layer 模块
Layers 模块封装了针对不同数据类型的图查询操作,提供领域特定的查询接口。资料来源:src/thought/layers/__init__.py
#### GraphLayer
通用的图查询层,提供基础的实体和关系查询能力,支持作用域过滤(shared/private/all)。
#### CodeLayer
代码专用查询层,提供程序员友好的接口:
| 方法 | 功能 |
|---|---|
callers_of(name) | 查询直接调用者,按 PageRank 排序 |
callees_of(name) | 查询调用的函数(同包内) |
impact_set(name) | 传递性影响集合(变更会影响哪些代码) |
defines_in_file(path) | 查询文件中定义的所有实体 |
资料来源:src/thought/layers/code.py
查询路由器
Router/Dispatcher 是系统的查询入口点,负责将用户查询分类到对应的处理器:
查询类型分类:
| 查询类型 | 触发关键词 | 处理器 |
|---|---|---|
| CODE | function, class, caller, callee, file extensions, camelCase/snake_case | |
| CHANGE | changed, added, removed, since, before | |
| RECALL | 记忆相关查询 | |
| ASK | 自然语言问题 |
路由组合:
- CODE × CHANGE → HYBRID(如 "auth.middleware 自 v1.0 以来的变更")
- 支持
as_of时间旅行查询
资料来源:src/thought/router/dispatcher.py
自然语言查询模块
Ask 模块将自然语言问题翻译为 Cypher 查询语句:
graph TD
A[Natural Language Question] --> B[LLM Provider]
B --> C[Cypher Query]
C --> D[Parser Validation]
D -->|Valid| E[Execute Query]
D -->|Invalid| F[Recall Fallback]翻译过程遵循以下约束:
- 仅使用只读 Cypher 特性(MATCH, WHERE, RETURN, LIMIT)
- 禁止使用写操作(MERGE, CREATE, DELETE, SET)
- 支持 AS_OF 时间旅行语法
MCP 服务器架构
Server 组件
MCP 服务器通过 server.py 实现,提供标准化的工具接口供 MCP 客户端调用。服务器封装了 CLI 的核心功能,暴露为 MCP 工具。资料来源:src/thought/server.py
graph TD
A[MCP Client] --> B[Server Handler]
B --> C[Router]
B --> D[Ingest Pipeline]
B --> E[Recall Layer]
B --> F[Code Layer]数据库生命周期管理
系统提供完整的数据库管理命令:
| 命令 | 功能 |
|---|---|
thought db size | 查看磁盘使用情况和实体/关系数量 |
thought db flush | 清空知识库(支持时间范围过滤) |
thought db backup | 在线备份快照 |
thought db load | 加载备份文件(支持合并模式) |
thought db inspect | 预览备份文件内容 |
所有破坏性操作前自动备份到 <db>.bak.<timestamp>。资料来源:src/thought/cli.py
本地 LLM 集成
系统支持连接本地 LLM 提供者:
- Ollama - 原生
/api/embed端点(批量) - LM Studio - OpenAI 兼容接口
- 任意 OpenAI 兼容服务器
自动嵌入选择器会探测 sentence_transformers 包是否可用,不可用时自动降级到确定性嵌入器。资料来源:src/thought/storage/sqlite/backend.py
CLI 命令体系
系统提供丰富的命令行接口:
| 命令类别 | 主要命令 |
|---|---|
| 初始化 | thought init |
| 数据摄入 | thought ingest-code, thought ingest-git, thought ingest-prose |
| 查询 | thought recall, thought ask, thought callers, thought impact |
| 代码分析 | thought diff --from <sha1> --to <sha2> |
| 数据库 | thought db size/flush/backup/load |
| 客户端 | thought install (Cline/Claude Code/Cursor) |
资料来源:src/thought/cli.py
资料来源:[src/thought/router/dispatcher.py](src/thought/router/dispatcher.py)
配置管理
配置管理是 thought-mcp 系统的核心基础设施,负责管理数据库连接、嵌入器选择、CLI 参数配置以及多客户端(MCP Server)集成配置。系统通过 TOML 格式的配置文件、环境变量和命令行参数三层配置机制,为用户提供灵活的定制能力。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
配置管理是 thought-mcp 系统的核心基础设施,负责管理数据库连接、嵌入器选择、CLI 参数配置以及多客户端(MCP Server)集成配置。系统通过 TOML 格式的配置文件、环境变量和命令行参数三层配置机制,为用户提供灵活的定制能力。
配置管理模块贯穿整个应用生命周期,包括初始化阶段(thought init)、运行阶段(各 CLI 命令)以及客户端集成阶段(Claude Code Hooks、MCP Server 安装)。资料来源:src/thought/cli.py:50-80
配置架构
thought-mcp 采用分层配置架构,核心组件包括:
graph TD
A[用户配置] --> B[CLI 参数]
A --> C[TOML 配置文件]
A --> D[环境变量]
B --> E[Config 对象]
C --> E
D --> E
E --> F[SQLiteBackend]
E --> G[Embedder]
E --> H[HookInstall]
E --> I[ClientInstall]配置层级
| 层级 | 来源 | 优先级 | 典型用途 |
|---|---|---|---|
| CLI 参数 | 命令行传入 | 最高 | 临时覆盖、脚本自动化 |
| TOML 配置 | thought.toml | 中 | 持久化项目级配置 |
| 环境变量 | 系统环境 | 最低 | 容器化部署默认值 |
CLI 初始化配置
thought init 命令是配置管理的入口点,负责创建数据库文件、配置文件和 Agent 面向文档。
命令签名
@app.command()
def init(
config: Path = typer.Option("thought.toml", help="Path to config file."),
db_path: str = typer.Option(".thought/thought.db", help="SQLite database path."),
embedder: str = typer.Option(
"auto", help="'auto' picks sentence-transformers if available, else deterministic.",
),
write_claude_md: bool = typer.Option(
True, "--write-claude-md/--no-claude-md",
help="Drop a CLAUDE.md so MCP clients learn how to use the tool.",
),
quick: bool = typer.Option(
False, "--quick", help="Skip first-run embedder warmup.",
),
) -> None:
参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
config | Path | thought.toml | TOML 配置文件路径 |
db_path | str | .thought/thought.db | SQLite 数据库文件路径 |
embedder | str | auto | 嵌入器选择:auto、sentence-transformers、deterministic |
write_claude_md | bool | True | 是否生成 CLAUDE.md 供 MCP 客户端学习 |
quick | bool | False | 是否跳过嵌入器首次预热 |
配置初始化流程
sequenceDiagram
participant User as 用户
participant CLI as thought init
participant FS as 文件系统
participant TOML as TOML 解析器
participant DB as SQLiteBackend
User->>CLI: thought init --config thought.toml
CLI->>FS: 检查配置文件
FS-->>CLI: 配置文件不存在
CLI->>FS: 创建目录结构 (.thought/)
CLI->>FS: 创建 thought.toml
Note over CLI: 使用 POSIX 风格路径分隔符<br/>避免 Windows 路径解析问题
CLI->>DB: 初始化数据库
CLI->>FS: 写入 CLAUDE.md (可选)
CLI-->>User: 配置完成初始化时,系统会自动创建父目录(parents=True),确保数据库路径有效。TOML 配置文件采用 POSIX 风格路径分隔符,以兼容 Windows 系统。资料来源:src/thought/cli.py:74-78
嵌入器配置
嵌入器(Embedder)是 thought-mcp 向量检索能力的核心,负责将文本转换为高维向量。
嵌入器自动选择机制
# 伪代码示例
if embedder == "auto":
if importlib.util.find_spec("sentence_transformers"):
return OllamaEmbedder() # 或 SentenceTransformerEmbedder
else:
return DeterministicEmbedder()
系统通过 importlib.util.find_spec 检测 sentence_transformers 包是否可用,自动选择最优嵌入器实现。这种设计确保了:
- 在安装了
sentence-transformers的环境中自动使用高质量嵌入器 - 在未安装可选依赖时优雅降级到确定性嵌入器
- 避免因可选依赖缺失导致的运行时错误
资料来源:src/thought/cli.py:95-102
嵌入器配置参数
| 参数 | 说明 | 可选值 |
|---|---|---|
model_name | 嵌入模型名称 | 字符串 |
model_version | 模型版本 | 字符串 |
dim | 向量维度 | 整数 |
batch_size | 批处理大小 | 整数 |
嵌入器配置存储在数据库的 embeddings 表中,每个实体可关联多个嵌入向量。资料来源:src/thought/storage/sqlite/backend.py:1-50
数据库配置
数据库路径配置
数据库路径通过 db_path 参数指定,默认为 .thought/thought.db。初始化时会自动创建父目录:
Path(db_path).parent.mkdir(parents=True, exist_ok=True)
数据库后端配置
SQLiteBackend 类管理所有数据库操作,包括:
- 连接管理(读写、只读模式)
- 事务控制
- 实体与关系存储
- 向量嵌入存储
- 代码实体索引
graph TD
A[应用程序] --> B[SQLiteBackend]
B --> C[主数据库文件]
B --> D[WAL 文件]
B --> E[SHM 文件]
B --> F[entities 表]
B --> G[edges 表]
B --> H[embeddings 表]
B --> I[applied_migrations 表]资料来源:src/thought/storage/sqlite/backend.py:1-100
数据库生命周期命令
| 命令 | 功能 |
|---|---|
thought db size | 显示数据库磁盘占用及实体/关系计数 |
thought db flush | 清空知识库,支持按时间范围过滤 |
thought db backup | 在线备份数据库快照 |
thought db load | 原子级替换或合并数据库 |
thought db inspect | 检查备份文件内容 |
Hook 配置管理
Hook 系统允许 thought-mcp 与 Claude Code 深度集成,在特定事件触发时自动执行记忆操作。
支持的 Hook 类型
| Hook 类型 | 触发事件 | 命令 | 说明 |
|---|---|---|---|
recall | UserPromptSubmit | thought hook recall | 用户提交提示时召回相关记忆 |
write | Stop | thought hook write | 会话结束时自动保存上下文 |
context | SessionStart | thought hook context | 会话开始时注入相关上下文 |
Hook 安装范围
def settings_path(*, scope: Literal["project", "user"] = "project") -> Path:
"""Return the ``.claude/settings.json`` path for the requested scope."""
if scope == "project":
return Path.cwd() / ".claude" / "settings.json"
- 项目级别(默认):
.claude/settings.json,随代码库版本控制 - 用户级别:用户主目录下的全局配置
资料来源:src/thought/hooks/install.py:40-50
Hook 安装结果
@dataclass(frozen=True)
class HookInstallResult:
kind: HookKind
path: Path
status: Literal["installed", "already_present", "error"]
detail: str = ""
安装状态含义:
installed:新安装成功already_present:Hook 已存在且配置匹配error:安装失败(详情在detail中)
MCP 客户端配置
MCP(Model Context Protocol)客户端配置允许将 thought-mcp 作为服务器集成到各种 IDE 和工具中。
支持的客户端
| 客户端 | 配置文件 |
|---|---|
| Claude Code | .claude/settings.json |
| Cursor | cursor.settings.json |
| VS Code | vscode-mcp.json |
| 其他 | 根据 _PATH_FNS 映射 |
服务器配置块
def server_block() -> dict:
"""Generate the MCP server configuration block."""
return {
"command": "uv",
"args": ["run", "thought", "mcp"],
"env": {
"THOUGHT_DB_PATH": str(DB_PATH),
},
}
客户端安装流程
graph TD
A[install call] --> B{配置文件存在?}
B -->|否| C[创建空配置对象]
B -->|是| D[读取现有配置]
D --> E{JSON 有效?}
E -->|否| F[返回错误]
E -->|是| G[合并服务器配置]
C --> G
G --> H{需要备份?}
H -->|是| I[创建 .thought.bak 备份]
H -->|否| J[写入配置文件]
I --> J
J --> K[返回安装结果]安装过程会备份原配置文件(后缀 .thought.bak),确保配置可回滚。资料来源:src/thought/clients.py:60-90
TOML 配置文件格式
配置文件位置
默认搜索顺序:
- 当前目录的
thought.toml - 用户指定路径(通过
--config参数)
典型配置示例
# thought.toml
[database]
path = ".thought/thought.db"
[embedder]
type = "auto" # 或 "sentence-transformers", "deterministic"
model_name = "all-MiniLM-L6-v2"
[hooks]
recall = true
write = true
context = false
[client]
server_name = "thought"
路径格式规范
# 确保 TOML 中使用 POSIX 风格路径分隔符
# 避免 Windows 路径如 C:\Users\...\thought.db 在 TOML 解析时出现问题
代码图谱配置
代码图谱是 thought-mcp 的核心功能之一,支持通过 Git 历史追踪代码实体变化。
Git 摄入配置
class GitIngestReport:
head_sha: str # 当前 HEAD 提交 SHA
mode: str # "snapshot" 或 "full"
commits_visited: int # 访问的提交数
files_ingested: int # 摄入的文件数
call_edges: int # 创建的调用关系边数
Git 摄入模式
| 模式 | 说明 | 适用场景 |
|---|---|---|
snapshot(默认) | 仅摄入 HEAD,快速初始化 | 首次摄入、日常使用 |
full | 遍历所有提交,完整历史 | 历史分析、时间旅行查询 |
# 快照模式(默认)
thought ingest-git <repo>
# 全量模式
thought ingest-git <repo> --mode full
资料来源:src/thought/ingest/code/git_pipeline.py:80-95
代码实体存储配置
每个代码实体存储以下元数据:
| 字段 | 说明 |
|---|---|
code_file | 代码文件相对路径 |
code_language | 编程语言(python, typescript, rust, php) |
code_commit_sha | 所在提交的 SHA |
这些字段支持按代码文件和提交进行精确查询。资料来源:src/thought/layers/code.py:30-50
环境变量配置
支持的环境变量
| 变量名 | 说明 | 默认值 |
|---|---|---|
THOUGHT_DB_PATH | 数据库文件路径 | .thought/thought.db |
THOUGHT_CONFIG | 配置文件路径 | thought.toml |
环境变量在配置层级中优先级最低,可被 CLI 参数和 TOML 配置覆盖。
配置验证与错误处理
常见配置错误
| 错误类型 | 原因 | 解决方案 |
|---|---|---|
| 数据库路径无效 | 父目录不存在 | 使用 --db-path 指定有效路径 |
| TOML 解析失败 | 语法错误 | 检查配置文件格式 |
| 嵌入器初始化失败 | 缺少可选依赖 | 安装 sentence-transformers 或使用 auto |
| Hook 安装失败 | 权限不足 | 检查 .claude 目录写入权限 |
备份与恢复
系统自动执行以下备份:
- 数据库备份:执行
db flush前自动备份到<db>.bak.<timestamp> - 配置文件备份:安装 Hook/Client 前备份原配置到
.thought.bak
# 自动备份示例
if backup:
shutil.copy(path, f"{path}.thought.bak")
配置最佳实践
项目级配置
- 使用默认的
thought.toml配置文件 - 将
.thought/目录添加到.gitignore - 通过
.claude/settings.json版本控制 Hook 配置
生产环境配置
- 使用绝对路径指定数据库位置
- 启用
db backup定期备份 - 生产环境建议显式指定嵌入器类型而非
auto
团队协作
- 项目级 Hook 配置应纳入版本控制
- 数据库文件不应提交到代码仓库
- 使用
thought db inspect验证备份文件后再加载
相关命令参考
| 命令 | 功能 |
|---|---|
thought init | 初始化配置和数据库 |
thought db size | 查看配置状态 |
thought db backup | 备份配置数据 |
thought hook install | 安装 Claude Code Hooks |
thought client install | 安装 MCP 客户端配置 |
thought config show | 显示当前配置 |
资料来源:[src/thought/cli.py:50-72]()
代码摄取与解析
代码摄取与解析是 thought-mcp 项目的核心子系统,负责将源代码文件解析为结构化的实体(Entity)和关系边(Edge),并存储到知识库中。该系统支持多种编程语言的 AST 解析、调用图构建、嵌入向量生成,以及 Git 历史感知的增量摄取。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
代码摄取与解析是 thought-mcp 项目的核心子系统,负责将源代码文件解析为结构化的实体(Entity)和关系边(Edge),并存储到知识库中。该系统支持多种编程语言的 AST 解析、调用图构建、嵌入向量生成,以及 Git 历史感知的增量摄取。
核心职责:
- 使用 tree-sitter 解析多种语言的源代码
- 提取函数、类、方法、模块等代码实体
- 构建实体间的调用关系(Call Graph)
- 生成语义嵌入向量以支持 VIBE 检索
- 支持 Git 历史感知的多快照摄取
资料来源:src/thought/ingest/code/pipeline.py:1-50
系统架构
graph TD
A[代码文件] --> B[语言检测]
B --> C[对应语言 Extractor]
C --> D[CodeEntity 列表]
C --> E[CodeEdge 列表]
D --> F[upsert_entity]
E --> G[build_call_graph]
G --> H[upsert_edge]
F --> I[嵌入向量生成]
I --> J[store_embedding]
D --> K[source_id 生成]
J --> L[(SQLite KB)]
H --> L
K --> F
K --> G核心组件
| 组件 | 文件路径 | 职责 |
|---|---|---|
| CodePipeline | pipeline.py | 主编排器,协调摄取流程 |
| PythonExtractor | python_extractor.py | Python AST 解析 |
| TypeScriptExtractor | typescript_extractor.py | TypeScript/JavaScript 解析 |
| RustExtractor | rust_extractor.py | Rust AST 解析 |
| PHPExtractor | php_extractor.py | PHP AST 解析 |
| CallGraphBuilder | call_graph.py | 调用关系构建 |
| GitPipeline | git_pipeline.py | Git 历史感知摄取 |
| GitWalker | git_walker.py | Git 仓库遍历 |
资料来源:src/thought/ingest/code/pipeline.py:1-100
语言支持与检测
支持的语言
系统通过文件扩展名自动检测编程语言:
| 语言 | 扩展名 | Extractor |
|---|---|---|
| Python | .py | PythonExtractor |
| TypeScript | .ts, .tsx | TypeScriptExtractor |
| Rust | .rs | RustExtractor |
| PHP | .php | PHPExtractor |
语言检测逻辑位于 detect_language() 函数,通过文件扩展名匹配对应的提取器。
资料来源:src/thought/ingest/code/pipeline.py:150-180
实体提取流程
通用提取模式
每种语言的提取器遵循统一的接口模式:
def extract(source: str, file_path: str) -> tuple[list[CodeEntity], list[CodeEdge]]:
parser = _get_parser()
source_bytes = source.encode("utf-8")
tree = parser.parse(source_bytes)
root = tree.root_node
# 1. 创建模块实体
entities.append(CodeEntity(...))
# 2. 遍历 AST 节点
_walk_module(root, ...)
return entities, edges
所有提取器返回类型一致的 CodeEntity 列表和 CodeEdge 列表,确保下游处理逻辑统一。
资料来源:src/thought/ingest/code/python_extractor.py:80-100
提取的实体类型
| 实体类型 | 说明 | 典型属性 |
|---|---|---|
module | 模块/文件 | signature, docstring, visibility |
class | 类定义 | signature, docstring, visibility |
function | 函数定义 | signature, docstring, visibility |
method | 类方法 | signature, visibility, class 属性 |
import | 导入语句 | from_import 属性 |
资料来源:src/thought/ingest/code/python_extractor.py:1-50
Python 提取器
Python 提取器使用 tree-sitter-python 解析器,处理以下 AST 节点类型:
module→ 模块实体class_definition→ 类实体function_definition→ 函数/方法实体import_statement/import_from_statement→ 导入边decorated_definition→ 装饰器处理
Python 内置函数(len, sum, .append 等)被过滤,不生成实体,避免污染影响图。
资料来源:src/thought/ingest/code/python_extractor.py:50-80
TypeScript 提取器
TypeScript 提取器额外处理:
- 继承关系 (
INHERITS_FROM):解析extends和implements子句 - 导出语句 (
export_statement):支持export class/export function递归解析
class Foo extends Bar implements Baz {}
// 生成 INHERITS_FROM 边: Foo → Bar
资料来源:src/thought/ingest/code/typescript_extractor.py:1-80
Rust 提取器
Rust 提取器处理 function_item 节点,并记录 impl_type 属性以关联方法与类型:
impl TypeName {
fn method(&self) {}
}
// 方法实体的 attrs 包含 {"impl_type": "TypeName"}
资料来源:src/thought/ingest/code/rust_extractor.py:1-60
PHP 提取器
PHP 提取器使用递归扫描处理嵌套结构:
<?php
namespace App;
class MyClass {
public function method() {}
}
由于 PHP 文件可能包含命名空间定义块,提取器递归扫描 namespace_definition 内部的节点。
资料来源:src/thought/ingest/code/php_extractor.py:1-50
调用图构建
构建策略
build_call_graph() 函数通过多种策略解析函数调用:
- 同文件qualified名称匹配:调用
obj.method()时解析为同文件的ClassName.method - 唯一qualified后缀匹配:在知识库中查找唯一的
*.method匹配项 - 跨文件裸名称匹配:查找其他文件中定义的同名顶层函数
# 解析逻辑优先级
# 1. 同文件完全限定名
tgt_id = backend.find_code_entity(canonical_name=callee_name, scope_filter=sf, code_file=file_path)
# 2. 唯一 qualified 后缀
if tgt_id is None and "." not in callee_name:
rows = backend.execute("SELECT id FROM entities WHERE ... LIKE ?", (f"%.{callee_name.lower()}",))
# 3. 跨文件裸名称
if tgt_id is None:
row = backend.execute("SELECT id FROM entities WHERE canonical_name = ? AND type IN ('function','method') ...")
资料来源:src/thought/ingest/code/call_graph.py:1-80
边类型
| 边类型 | 说明 | 生成时机 |
|---|---|---|
CALLS | 函数调用关系 | 调用图构建时 |
DEFINES | 类定义成员 | 提取器遍历时 |
IMPORTS | 模块导入关系 | 解析 import 语句时 |
INHERITS_FROM | 类继承关系 | TypeScript 解析 extends 时 |
资料来源:src/thought/ingest/code/typescript_extractor.py:60-100
Git 历史感知摄取
GitPipeline
GitPipeline 类实现 Git 历史感知的代码摄取,支持两种模式:
| 模式 | 说明 | 用途 |
|---|---|---|
snapshot | 仅摄取 HEAD 提交 | 快速增量更新 |
full | 遍历所有历史提交 | 支持时序查询 |
# GitPipeline 使用 GitWalker 遍历提交
commits = list(git_walker.walk(mode=mode, ...))
for commit in commits:
for fpath, content in git_walker.file_snapshot(commit.sha):
r = code_pipe.ingest_code_file(real_path, commit_sha=commit.sha, ...)
build_call_graph(backend=backend, file_path=fpath, source=content, commit_sha=commit.sha, ...)
资料来源:src/thought/ingest/code/git_pipeline.py:1-80
GitWalker
GitWalker 使用纯子进程调用 Git 命令,避免对 pygit2 的原生依赖:
git rev-parse HEAD # 获取当前 SHA
git log --format=... # 获取提交元数据
git ls-tree -r <sha> # 获取提交时的文件列表
git show <sha>:<path> # 获取文件在特定提交的内容
资料来源:src/thought/ingest/code/git_walker.py:1-50
Bi-temporal 模型
摄取时记录 code_commit_sha,支持 bi-temporal 查询:
valid_from/valid_until:实体的有效时间范围as_of_kind='valid':查询特定日期的代码状态as_of_kind='learned':查询系统在该日期学到的知识
eid = self._backend.upsert_entity(
code_commit_sha=commit_sha, # 关联到特定提交
...
)
资料来源:src/thought/ingest/code/pipeline.py:100-150
嵌入向量生成
VIBE 检索支持
为每个代码实体生成嵌入向量,支持通过意图(而非精确名称)检索:
embed_text_parts = [ent.name, ent.signature]
if ent.docstring:
embed_text_parts.append(ent.docstring)
embed_text = "\n".join(p for p in embed_text_parts if p)
vec = self._embedder.embed(embed_text)
self._backend.store_embedding(
entity_id=eid,
model_name=self._embedder.model_name,
model_version=self._embedder.model_version,
dim=self._embedder.dim,
vector=vector_to_bytes(vec),
)
资料来源:src/thought/ingest/code/pipeline.py:120-140
自动嵌入器选择
系统支持自动选择嵌入器:
- 优先使用
sentence-transformers(如已安装) - 回退到确定性嵌入器(
auto模式)
# auto embedder selector
if importlib.util.find_spec("sentence_transformers") is not None:
return SentenceTransformerEmbedder()
return DeterministicEmbedder()
资料来源:src/thought/ingest/code/pipeline.py:150-180
事务与存储
原子性保证
每个文件的摄取在单个事务中完成:
self._backend.begin()
try:
name_to_id, embeddings_created = self._write_entities(...)
edge_ids, unresolved = self._write_edges(...)
self._backend.commit()
except Exception:
self._backend.rollback()
raise
资料来源:src/thought/ingest/code/pipeline.py:180-220
实体唯一性
实体的唯一标识包含 (code_file, code_commit_sha),确保同一函数在不同文件或不同提交中不会合并:
# upsert_entity identity now includes (code_file, code_commit_sha)
资料来源:src/thought/ingest/code/pipeline.py:60-80
增量扫描
ScanLog
系统维护 scan_log 表记录扫描历史,支持增量摄取:
def scan(repo_path: str, agent: str | None = None, since: str | None = None, max_files: int | None = None, note: str | None = None):
"""Incremental code-scan primitive. Walks repo_path, ingests changed/new files,
records a row in scan_log so the next call picks up where this one left off."""
每次扫描后记录时间戳,下次调用时跳过已处理的变更。
资料来源:src/thought/server.py:1-50
配置与使用
CLI 命令
| 命令 | 说明 |
|---|---|
thought ingest-git <repo> | Git 历史摄取 |
thought ingest-code <path> | 单文件/目录摄取 |
thought callers <name> | 查询直接调用者 |
thought impact <name> | 查询影响集合 |
thought diff --from <sha1> --to <sha2> | 提交间差异 |
初始化配置
@app.command()
def init(
config: Path = typer.Option("thought.toml"),
db_path: str = typer.Option(".thought/thought.db"),
embedder: str = typer.Option("auto"),
write_claude_md: bool = typer.Option(True),
quick: bool = typer.Option(False),
):
数据模型
CodeEntity
| 字段 | 类型 | 说明 |
|---|---|---|
name | str | 实体名称 |
type_ | str | 实体类型(module/class/function/method) |
language | str | 编程语言 |
file_path | str | 文件路径 |
line_start | int | 起始行号 |
line_end | int | 结束行号 |
signature | str | 函数签名 |
docstring | str | 文档字符串 |
visibility | str | 可见性(public/private) |
attrs | dict | 额外属性 |
CodeEdge
| 字段 | 类型 | 说明 |
|---|---|---|
source_name | str | 源实体名称 |
target_name | str | 目标实体名称 |
relation_type | str | 关系类型(CALLS/DEFINES/IMPORTS) |
line_number | int | 关联代码行号 |
attrs | dict | 额外属性(如 from_import) |
资料来源:src/thought/ingest/code/python_extractor.py:20-50
扩展新的语言
要添加新的语言支持,需实现以下步骤:
- 创建提取器文件:如
newlang_extractor.py - 实现
extract()函数:返回list[CodeEntity]和list[CodeEdge] - 注册语言检测:在
pipeline.py的detect_language()中添加扩展名映射 - 安装 tree-sitter 语法:确保 tree-sitter-{lang} 可用
def extract(source: str, file_path: str) -> tuple[list[CodeEntity], list[CodeEdge]]:
parser = _get_parser()
source_bytes = source.encode("utf-8")
tree = parser.parse(source_bytes)
root = tree.root_node
# ... 遍历 AST,生成实体和边
return entities, edges资料来源:[src/thought/ingest/code/pipeline.py:1-50]()
实体与关系管理
实体与关系管理是 thought-mcp 的核心子系统,负责从代码库中提取结构化实体(函数、类、模块、方法等)及其关系(CALLS、IMPORTS、DEFINES、INHERITSFROM 等),并将这些信息持久化到知识库中供后续查询使用。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
实体与关系管理是 thought-mcp 的核心子系统,负责从代码库中提取结构化实体(函数、类、模块、方法等)及其关系(CALLS、IMPORTS、DEFINES、INHERITS_FROM 等),并将这些信息持久化到知识库中供后续查询使用。
该系统基于树形语法解析器(tree-sitter)实现多语言代码解析,采用双向时态数据模型记录实体的生命周期,并通过 PageRank 算法实现智能调用链分析。
资料来源:src/thought/ingest/code/types.py:1-50
核心数据模型
CodeEntity 代码实体
CodeEntity 是代码提取阶段产生的中间数据结构,代表代码库中的一个可识别元素:
@dataclass
class CodeEntity:
name: str # 实体名称
type_: str # 实体类型 (function, class, method, module...)
language: str # 编程语言 (python, typescript, rust...)
file_path: str # 文件路径
line_start: int # 起始行号
line_end: int # 结束行号
signature: str | None = None # 函数/方法签名
docstring: str | None = None # 文档字符串
visibility: str = "public" # 可见性 (public, private, protected)
attrs: dict[str, object] = field(default_factory=dict) # 扩展属性
资料来源:src/thought/ingest/code/types.py:10-22
CodeEdge 代码关系
CodeEdge 描述两个代码实体之间的关系:
@dataclass
class CodeEdge:
source_name: str # 源实体名称
target_name: str # 目标实体名称
relation_type: str # 关系类型
line_number: int | None = None # 定义行号
attrs: dict[str, object] = field(default_factory=dict) # 扩展属性
资料来源:src/thought/ingest/code/types.py:24-31
Entity 与 Edge (存储模型)
存储层使用 pydantic 模型定义实体和边的结构:
class Entity(BaseModel):
id: str
type: str
name: str
canonical_name: str
scope: ScopeName # shared | private
tier: Tier # hot | warm | cold
importance: float = Field(ge=0.0, le=1.0)
valid_from: datetime # 有效起始时间(双向时态)
valid_until: datetime | None = None # 有效结束时间(NULL 表示当前有效)
learned_at: datetime # 系统学习时间
code_file: str | None = None # 代码文件路径
code_language: str | None = None # 代码语言
code_commit_sha: str | None = None # Git 提交 SHA
access_count: int = 0
attrs: dict[str, object] = Field(default_factory=dict)
资料来源:src/thought/models.py:58-76
实体类型分类
| 类型 | 描述 | 示例 |
|---|---|---|
function | 函数定义 | Python def func() |
class | 类定义 | Python class Foo: |
method | 类方法 | Rust fn method(&self) |
module | 模块/文件 | 每个代码文件 |
interface | 接口定义 | TypeScript interface Foo |
struct | 结构体 | Rust struct Foo |
资料来源:src/thought/ingest/code/python_extractor.py:40-48
关系类型分类
| 关系类型 | 描述 | 方向 |
|---|---|---|
CALLS | 函数调用关系 | source → target |
DEFINES | 定义关系 | class/module → method/function |
INHERITS_FROM | 继承关系 | 子类 → 父类 |
IMPORTS | 导入关系 | 模块 → 被导入模块 |
CONTRADICTS | 矛盾关系 | 用于事实校正 |
资料来源:src/thought/ingest/code/typescript_extractor.py:80-90
多语言代码提取架构
提取器注册表
系统通过懒加载方式注册各语言的提取器:
_LOADERS = {
"python": _python_extractor,
"typescript": _typescript_extractor,
"go": _go_extractor,
"rust": _rust_extractor,
"java": _java_extractor,
"php": _php_extractor,
}
资料来源:src/thought/ingest/code/ast_extractor.py:30-44
Python 提取器
Python 提取器使用 tree-sitter-python 解析代码 AST:
- 模块实体:为每个文件创建模块节点
- 函数扫描:遍历
function_definition节点 - 类扫描:遍历
class_definition节点 - 继承关系:从类定义的
base_clause提取父类 - 导入关系:处理
import_statement和import_from_statement
def extract(source: str, file_path: str) -> tuple[list[CodeEntity], list[CodeEdge]]:
parser = _get_parser()
tree = parser.parse(source_bytes)
# 创建模块实体,遍历 AST 提取函数/类/导入
资料来源:src/thought/ingest/code/python_extractor.py:50-72
TypeScript 提取器
TypeScript 提取器扩展了 Python 提取器的模式,增加了:
- 可见性修饰符:从
accessibility_modifier节点提取 - 接口支持:处理
interface_declaration - 类型别名:处理
type_alias_declaration - 命名空间:处理
namespace_declaration
# 继承关系提取
for hc in heritage.named_children:
if hc.type == "extends_clause":
parent = _text(v, source_bytes)
out_edges.append(CodeEdge(
source_name=class_name,
target_name=parent,
relation_type="INHERITS_FROM",
))
资料来源:src/thought/ingest/code/typescript_extractor.py:60-90
Rust 提取器
Rust 提取器处理特有的语言结构:
- 结构体:从
struct_item节点提取 - impl 块:关联方法与类型
- 可见性:从
visibility节点提取(pub,pub(crate)等)
out_entities.append(CodeEntity(
name=qualified,
type_="method",
language="rust",
attrs={"impl_type": type_name}, # 关联 impl 块
))
资料来源:src/thought/ingest/code/rust_extractor.py:40-50
语言支持矩阵
graph LR
A[源代码文件] --> B{语言检测}
B -->|Python| C[python_extractor]
B -->|TypeScript| D[typescript_extractor]
B -->|Rust| E[rust_extractor]
B -->|Go| F[go_extractor]
B -->|Java| G[java_extractor]
B -->|PHP| H[php_extractor]
C --> I[CodeEntity + CodeEdge]
D --> I
E --> I
F --> I
G --> I
H --> I调用图构建
调用图是理解代码依赖关系的关键组件。系统通过静态分析构建 CALLS 关系。
解析策略
call_graph.py 实现三层解析策略:
graph TD
A[调用表达式] --> B{方法调用?}
B -->|是| C[尝试同文件匹配]
B -->|否| D{有qualifier?}
C --> E[1. 同文件精确匹配]
D --> F[Qualified 匹配]
E --> G{找到?}
F --> H[2. Qualified 后缀匹配]
G -->|否| I[3. 跨文件裸名匹配]
G -->|是| J[建立 CALLS 边]
H --> K{唯一匹配?}
I --> L[建立 CALLS 边]
K -->|是| J- 同文件方法调用:直接通过方法名匹配当前文件的类方法
- 唯一 Qualified 后缀匹配:查找
ClassName.method格式的唯一匹配 - 跨文件裸名匹配:在其他文件中查找同名函数
资料来源:src/thought/ingest/code/call_graph.py:60-90
解析示例
# 解析 obj.method() 调用
target_name = _resolve_method_call(node, source_bytes, file_path, backend, ...)
# 目标名称可能为:
# - "ClassName.method" (qualified)
# - "function_name" (bare)
存储管道
实体写入流程
graph TD
A[CodeEntity 列表] --> B[计算规范名称]
B --> C[upsert_entity]
C --> D[生成 embedding]
D --> E[store_embedding]
F[Entity ID 映射] <-- G[name_to_id 字典]
E --> Gdef _write_entities(self, entities, scope, owner_id, source_id, commit_sha, language, now):
eid = self._backend.upsert_entity(
type_=ent.type_,
name=ent.name,
scope=scope,
valid_from=now,
code_file=ent.file_path,
code_language=language,
code_commit_sha=commit_sha,
)
资料来源:src/thought/ingest/code/pipeline.py:80-110
身份去重策略
实体标识包含 (name, code_file, code_commit_sha) 三元组,确保同名函数在不同文件或不同提交中不会合并:
# upsert_entity 身份: (name, code_file, code_commit_sha)
# 这允许:
# - auth.py::authenticate (v1.0)
# - auth.py::authenticate (v2.0) # 视为不同实体
代码查询层
CodeLayer 接口
CodeLayer 提供程序员友好的查询接口:
| 方法 | 功能 |
|---|---|
callers_of(name) | 谁调用了这个函数?(直接调用者,按 PageRank 排序) |
callees_of(name) | 这个函数调用了什么?(直接调用,限包内) |
impact_set(name) | 变更这个的影响范围(传递调用者,PageRank 排序) |
defines_in_file(path) | 文件中定义的所有实体 |
资料来源:src/thought/layers/code.py:20-35
Personalized PageRank 查询
系统使用 HippoRAG 风格的双向 PageRank 遍历进行调用者排名:
def callers_of(self, name: str) -> list[CodeHit]:
entity_id = self._resolve_entity_id(name)
# 执行 PPR 查询,返回按重要性排序的调用者
影响集分析
impact_set 执行传递闭包查询:
影响集 = 直接调用者 + 间接调用者(递归向上遍历)
这回答了 "如果我修改这个函数,哪些代码会受影响?" 的问题。
双向时态模型
系统采用 bi-temporal 模型记录实体生命周期:
gantt
title 双向时态模型示意
dateFormat X
axisFormat %s
section Valid Time
v1.0 实体存在 :0, 100
section Learned Time
被学习 :10, 120
被更正 :80, 120| 时间轴 | 字段 | 语义 |
|---|---|---|
| 有效时间 | valid_from / valid_until | 事实本身何时为真 |
| 学习时间 | learned_at / unlearned_at | 系统何时获知该事实 |
as_of 查询可以回溯历史状态:
as_of_kind='valid'→ "日期 X 时什么为真"as_of_kind='learned'→ "系统日期 X 时知道什么"
Git 感知摄取
快照模式 vs 完整模式
| 模式 | 行为 | 适用场景 |
|---|---|---|
snapshot | 仅摄取 HEAD | 快速初始化 |
full | 遍历每个提交 | 历史分析、时间旅行查询 |
GitWalker # 纯子进程实现,无原生依赖
# 每个实体记录其 commit_sha
差异查询
thought diff --from <sha1> --to <sha2>
# 输出: 新增实体列表 / 移除实体列表
配置与初始化
数据库初始化
thought init --db-path .thought/thought.db
# 创建数据库文件 + 配置文件 + CLAUDE.md
嵌入器选择
embedder: str = typer.Option(
"auto", # 自动选择 sentence-transformers 或确定性嵌入
)
扩展阅读
| 功能 | 文档 |
|---|---|
| CLI 命令参考 | CHANGELOG.md |
| 数据库后端 | SQLite 存储层 |
| 调用图构建 | call_graph.py |
| 演示用例 | demo.py |
资料来源:[src/thought/ingest/code/types.py:1-50]()
记忆模型与检索
Thought-MCP 的记忆模型与检索系统是一个双时态(bi-temporal)的知识图谱存储与查询引擎,旨在为 AI 代理提供持久化、可追溯的上下文记忆能力。该系统将实体(Entity)、关系(Edge)和向量嵌入(Embedding)统一存储在 SQLite 数据库中,支持时间旅行查询、自然语言查询和代码语义检索。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
Thought-MCP 的记忆模型与检索系统是一个双时态(bi-temporal)的知识图谱存储与查询引擎,旨在为 AI 代理提供持久化、可追溯的上下文记忆能力。该系统将实体(Entity)、关系(Edge)和向量嵌入(Embedding)统一存储在 SQLite 数据库中,支持时间旅行查询、自然语言查询和代码语义检索。
核心设计目标:
- 持久化记忆:让 AI 代理在不同会话之间保留关键上下文
- 双时态模型:区分"何时发生"(valid_time)和"何时学习"(learned_at)
- 语义检索:结合向量相似度和图关系的混合检索
- 代码理解:支持函数调用图、影响分析和代码追溯
资料来源:src/thought/memory.py:1-50
架构概览
graph TB
subgraph "数据摄取层"
CI[代码摄取 Pipeline]
GI[Git 历史摄取]
HI[Hook 事件摄取]
end
subgraph "存储层"
SQ[SQLite Backend]
EM[Embedding 存储]
end
subgraph "查询层"
REC[recall 召回]
ASK[ask 自然语言]
CODE[code 代码查询]
GRAPH[graph 图查询]
end
CI --> SQ
GI --> SQ
HI --> SQ
SQ --> EM
REC --> EM
ASK --> GRAPH
CODE --> GRAPH
GRAPH --> SQ核心组件关系
| 组件 | 职责 | 源码位置 |
|---|---|---|
Memory | 顶层 API 聚合器,协调各层 | memory.py |
SQLiteBackend | 数据库 CRUD 操作核心 | storage/sqlite/backend.py |
VectorLayer | 向量嵌入存储与相似度搜索 | layers/vector.py |
GraphLayer | 图关系查询与 PageRank | layers/graph.py |
TemporalLayer | 双时态时间旅行查询 | layers/temporal.py |
CodeLayer | 代码专用查询接口 | layers/code.py |
资料来源:[src/thought/memory.py:1-50]()
查询系统
查询系统(Query System)是 thought-mcp 的核心组件之一,负责将用户的自然语言查询转换为知识图谱查询并返回结果。该系统支持多种查询类型,包括直接记忆检索(recall)、自然语言到 Cypher 查询的翻译(ask)、代码图谱查询(callers/callees/impact)等场景。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
查询系统(Query System)是 thought-mcp 的核心组件之一,负责将用户的自然语言查询转换为知识图谱查询并返回结果。该系统支持多种查询类型,包括直接记忆检索(recall)、自然语言到 Cypher 查询的翻译(ask)、代码图谱查询(callers/callees/impact)等场景。
查询系统的设计目标是为用户提供透明的查询接口,无需了解底层图数据库的查询语言即可完成复杂的信息检索任务。系统采用分层架构,通过路由器(Router)进行意图分类,再交由对应的查询处理器执行。
资料来源:src/thought/query/ask.py:1-15
架构设计
系统分层
查询系统采用三层架构设计:
| 层级 | 组件 | 职责 |
|---|---|---|
| 路由层 | Router / Classifier | 解析用户意图,分类查询类型 |
| 转换层 | Ask / Cypher | 自然语言转 Cypher,查询验证 |
| 执行层 | Backend / Storage | 执行查询,返回结果 |
graph TD
A[用户自然语言查询] --> B[Router 意图分类]
B --> C{查询类型}
C -->|RECALL| D[recall 直接检索]
C -->|CODE| E[CodeLayer 代码图谱]
C -->|ASK| F[Ask 自然语言→Cypher]
C -->|HYBRID| G[组合查询]
D --> H[Backend 执行]
E --> H
F --> I[Cypher 验证]
I --> H
H --> J[返回结果]资料来源:src/thought/query/ask.py:1-15 资料来源:src/thought/router/classifier.py
核心模块
| 模块 | 文件路径 | 功能描述 |
|---|---|---|
ask | src/thought/query/ask.py | 自然语言到 Cypher 查询的翻译与执行 |
cypher | src/thought/query/cypher.py | Cypher 查询构建器与执行器 |
views | src/thought/query/views.py | 查询视图定义与数据结构 |
classifier | src/thought/router/classifier.py | 查询意图分类器 |
资料来源:src/thought/query/ask.py 资料来源:src/thought/query/cypher.py 资料来源:src/thought/query/views.py
自然语言查询转换(Ask 模块)
Ask 模块工作流程
Ask 模块是查询系统中最复杂的组件,它将自然语言问题转换为 Cypher 查询语句。其核心流程包括:
- 获取当前知识图谱的 schema 信息
- 构建包含约束的提示词(prompt)
- 调用 LLM 进行翻译
- 验证 Cypher 查询语法
- 执行查询或降级到 recall
graph LR
A[用户问题] --> B{配置了 LLM?}
B -->|否| C[recall 降级]
B -->|是| D[构建提示词]
D --> E[LLM 翻译]
E --> F{翻译成功?}
F -->|否| C
F -->|是| G[Cypher 验证]
G --> H{验证通过?}
H -->|否| C
H -->|是| I[执行查询]
I --> J[返回结果]资料来源:src/thought/query/ask.py:48-78
AskResult 数据结构
@dataclass
class AskResult:
cypher: str | None # 生成的 Cypher 查询
sql: str | None # 备用的 SQL 查询
rows: list[dict[str, Any]] | None # 查询结果行
fallback_used: bool # 是否使用了降级策略
fallback_reason: str | None # 降级原因
error: str | None # 错误信息
资料来源:src/thought/query/ask.py:30-37
Cypher 翻译约束
系统对生成的 Cypher 查询有严格的约束限制:
| 约束类型 | 说明 |
|---|---|
| 读写限制 | 只允许使用只读操作(MATCH, WHERE, RETURN, LIMIT, AS_OF) |
| 禁用操作 | 禁止使用 MERGE, CREATE, DELETE, SET, WITH |
| 路径限制 | 不支持可变长度路径 |
| Schema 限制 | 必须使用 Schema 中定义的有效实体类型和关系类型 |
资料来源:src/thought/query/ask.py:17-27
提示词模板
Ask 模块使用结构化的提示词模板来引导 LLM 生成正确的 Cypher 查询:
You translate English questions into Cypher queries against a memory database.
CONSTRAINTS (any violation will be rejected):
- Output a single Cypher query, no explanations, no markdown fences.
- Use ONLY these read-only Cypher features:
MATCH (var:Type {{prop:value}}) (-[:RELATION]-> (var:Type))? ...
WHERE expr (AND expr)* using = <> < > <= >= CONTAINS "STARTS WITH" IN
RETURN identlist
LIMIT N (optional)
AS_OF 'iso-date' (optional, for time-travel queries)
- Use ONLY entity types and relation types from the SCHEMA below.
- Never use MERGE / CREATE / DELETE / SET / WITH / variable-length paths.
SCHEMA:
entity types: {entity_types}
relation types: {relation_types}
QUESTION: {question}
CYPHER:
资料来源:src/thought/query/ask.py:16-38
降级策略
当 LLM 翻译失败或未配置 LLM 提供者时,系统会自动降级到 recall 函数执行简单的向量检索:
def ask(
memory,
question: str,
*,
llm_cfg: object | None = None,
scope: str = "all",
owner_id: str | None = None,
no_fallback: bool = False,
) -> AskResult:
provider = getattr(llm_cfg, "provider", None) or "none"
if provider == "none":
if no_fallback:
return AskResult(error="thought ask requires [llm] provider...")
rows = _recall_fallback(memory, question, scope=scope, owner_id=owner_id)
return AskResult(fallback_used=True, fallback_reason="no LLM provider configured")
资料来源:src/thought/query/ask.py:40-60
路由分类系统
查询类型分类
路由器根据用户输入的关键词和模式匹配将查询分为以下类型:
| 查询类型 | 触发条件 | 处理模块 |
|---|---|---|
RECALL | 一般自然语言问题 | recall 向量检索 |
CODE | 包含代码关键词 | CodeLayer 代码分析 |
CHANGE | 涉及变更历史 | Git 历史查询 |
HYBRID | CODE + CHANGE 组合 | 组合处理 |
ASK | 需要结构化查询 | Ask Cypher 翻译 |
资料来源:src/thought/router/classifier.py 资料来源:src/thought/router/rules.yaml
CODE 类型识别
CODE 查询类型的识别基于以下特征:
| 特征类型 | 关键词示例 | 识别方式 |
|---|---|---|
| 编程关键字 | function, class, method, interface | 精确匹配 |
| 代码操作 | caller, callee, impact, imports | 精确匹配 |
| 文件扩展名 | .py, .ts, .js, .rs, .php | 扩展名检测 |
| 标识符模式 | camelCase, snake_case | 正则匹配 |
| 版本引用 | since v1.0, before this commit | 模式匹配 |
资料来源:src/thought/router/classifier.py
自然语言调用
系统支持通过自然语言触发代码图谱查询,例如:
| 自然语言 | 解析结果 |
|---|---|
"who calls authenticate_user" | 调用者查询 |
"what does login do" | 被调用者查询 |
"impact of password_reset" | 影响分析 |
资料来源:src/thought/query/ask.py 资料来源:src/thought/router/classifier.py
代码图谱查询(CodeLayer)
功能概述
CodeLayer 是代码垂直领域的专用查询接口,提供面向程序员的自然词汇操作:
| 操作 | 方法名 | 说明 |
|---|---|---|
| 调用者查询 | callers_of(name) | 谁调用了这个函数(按 PageRank 排序) |
| 被调用查询 | callees_of(name) | 这个函数调用了什么(包内) |
| 影响分析 | impact_set(name) | 传递性调用者集合 |
| 文件定义 | defines_in_file(path) | 查找文件中定义的所有实体 |
资料来源:src/thought/layers/code.py:1-25
实体解析策略
调用图构建时,实体解析按以下优先级进行:
graph TD
A[解析函数调用] --> B{同文件唯一匹配?}
B -->|是| C[直接使用]
B -->|否| D{唯一 qualified 后缀匹配?}
D -->|是| C
D -->|否| E{跨文件 bare-name 匹配?}
E -->|是| C
E -->|否| F[创建 Stub]解析优先级:
- 同文件唯一匹配
- 唯一 qualified 后缀匹配(如
obj.method()→ClassName.method) - 跨文件 bare-name 匹配(顶级函数)
资料来源:src/thought/ingest/code/call_graph.py 资料来源:src/thought/ingest/code/pipeline.py
查询视图与数据结构
视图模块
views.py 定义了查询返回的标准化数据结构,确保不同查询类型的返回格式一致:
| 视图类型 | 用途 |
|---|---|
| RecallResult | 向量检索结果 |
| AskResult | Cypher 查询结果 |
| CodeResult | 代码图谱查询结果 |
资料来源:src/thought/query/views.py
实体模型
class Entity(BaseModel):
id: str
type: str
name: str
canonical_name: str
owner_id: str | None
scope: ScopeName
tier: Tier
importance: float # 0.0 - 1.0
valid_from: datetime
valid_until: datetime | None # None = 当前有效
learned_at: datetime
unlearned_at: datetime | None
created_at: datetime
last_accessed_at: datetime
access_count: int
attrs: dict[str, object]
配置与集成
LLM 提供者配置
查询系统支持多种 LLM 提供者:
| 提供者 | 配置值 | 说明 |
|---|---|---|
| Anthropic | anthropic | Claude 系列模型 |
| Ollama | ollama | 本地 Ollama 服务 |
| LM Studio | lmstudio | LM Studio 本地服务 |
| OpenAI 兼容 | openai-compat | 通用 OpenAI 兼容接口 |
配置方式:通过 thought.toml 中的 [llm] provider 字段指定。
资料来源:src/thought/query/ask.py:48-55
CLI 命令集成
| 命令 | 查询类型 | 功能 |
|---|---|---|
thought recall <query> | RECALL | 记忆检索 |
thought ask <question> | ASK | 自然语言查询 |
thought callers <name> | CODE | 调用者分析 |
thought impact <name> | CODE | 影响分析 |
thought diff --from <sha1> --to <sha2> | CHANGE | 变更对比 |
资料来源:src/thought/cli.py 资料来源:src/thought/layers/code.py
时间旅行查询
双时间模型
系统支持双时间(bi-temporal)查询模型:
| 时间维度 | 说明 | 查询参数 |
|---|---|---|
valid_from/valid_until | 事实的有效期 | as_of_kind='valid' |
learned_at/unlearned_at | 系统认识该事实的时间 | as_of_kind='learned' |
MATCH (e:Entity)
WHERE e.valid_from <= '2024-01-01'
AND (e.valid_until IS NULL OR e.valid_until > '2024-01-01')
RETURN e
使用场景
| 场景 | 查询方式 |
|---|---|
| 查询某日期的事实状态 | as_of='date' + as_of_kind='valid' |
| 查询系统当时的认知 | as_of='date' + as_of_kind='learned' |
| 事实纠正追踪 | 比较 valid 和 learned 时间差异 |
资料来源:src/thought/query/cypher.py 资料来源:src/thought/cli.py
错误处理与降级
错误处理策略
| 错误类型 | 处理方式 | 降级目标 |
|---|---|---|
| LLM 提供者未配置 | 自动降级 | recall 向量检索 |
| LLM 调用失败 | 自动降级 | recall 向量检索 |
| Cypher 翻译错误 | 自动降级 | recall 向量检索 |
| Cypher 验证失败 | 自动降级 | recall 向量检索 |
| 查询执行失败 | 返回错误 | - |
强制模式
当需要精确结果而不接受降级时,可使用 no_fallback=True 参数:
result = ask(memory, question, no_fallback=True)
if result.error:
# 处理错误,不使用降级
handle_error(result.error)
资料来源:src/thought/query/ask.py:60-78
最佳实践
查询优化建议
| 建议 | 说明 |
|---|---|
| 使用具体标识符 | 提供函数全名或类名可提高解析准确性 |
| 限制时间范围 | 使用 as_of 参数减少查询范围 |
| 利用 scope 过滤 | 适当使用 scope='private' 或 scope='shared' |
| 组合查询 | CODE + CHANGE 组合使用 HyBRID 类型 |
调试技巧
| 问题 | 调试方法 |
|---|---|
| 翻译结果不准确 | 检查 schema 中实体类型是否完整 |
| 解析失败 | 验证函数名符合标识符模式 |
| 性能问题 | 使用 db size 检查索引状态 |
相关文档
资料来源:[src/thought/query/ask.py:1-15]()
图形层与图遍历
图形层(Graph Layer)是 THOUGHT 项目的核心组件之一,负责对知识库中的实体和关系进行图查询操作。它封装了底层的 SQLite 存储后端,提供面向程序员的图遍历接口,支持调用链分析、影响范围计算和代码结构查询等高级功能。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述
图形层(Graph Layer)是 THOUGHT 项目的核心组件之一,负责对知识库中的实体和关系进行图查询操作。它封装了底层的 SQLite 存储后端,提供面向程序员的图遍历接口,支持调用链分析、影响范围计算和代码结构查询等高级功能。
图形层的设计目标是实现语义感知的代码导航:用户可以通过函数名、类名等标识符快速定位代码实体,分析代码间的调用关系和依赖关系,从而支持代码审查、影响分析和重构决策等场景。
架构设计
模块层次结构
┌─────────────────────────────────────┐
│ CLI / API 层 │
├─────────────────────────────────────┤
│ CodeLayer (代码层) │
│ - callers_of() │
│ - callees_of() │
│ - impact_set() │
│ - defines_in_file() │
├─────────────────────────────────────┤
│ GraphLayer (图形层) │
│ - 图遍历核心逻辑 │
│ - PageRank 排序 │
├─────────────────────────────────────┤
│ SQLiteBackend (存储后端) │
│ - 实体存储 │
│ - 关系存储 │
│ - 嵌入向量存储 │
└─────────────────────────────────────┘
CodeLayer 是 GraphLayer 的上层封装,专门针对代码场景优化。GraphLayer 负责底层的图遍历实现,支持多种查询模式和排序策略。
资料来源:src/thought/layers/code.py:24-27
数据模型
图形层操作的核心数据模型包括:
| 模型 | 说明 |
|---|---|
Entity | 实体节点,代表代码中的函数、类、模块等 |
CodeHit | 查询结果,包含实体和相关性评分 |
ScopeFilter | 作用域过滤器,用于限定查询范围 |
@dataclass(frozen=True)
class CodeHit:
entity: Entity
score: float
CodeHit 用于返回按 PageRank 评分排序的查询结果,支持 "who calls X" 等排名查询场景。
资料来源:src/thought/layers/code.py:21-23
核心功能
调用者查询 (callers_of)
callers_of 方法返回直接调用指定函数的实体列表,结果按 PageRank 评分降序排列。
def callers_of(name: str, *, ...) -> list[CodeHit]
使用场景:
- 分析某个函数被哪些模块调用
- 识别关键函数的依赖方
- 评估代码变更的影响范围
该方法通过双向 PageRank 遍历(HippoRAG 风格)实现,能够发现直接和间接的调用关系。
被调用者查询 (callees_of)
callees_of 方法返回指定函数直接调用的其他实体列表。
def callees_of(name: str, *, ...) -> list[CodeHit]
使用场景:
- 分析函数的依赖项
- 理解函数的实现逻辑
- 准备代码重构的影响评估
影响集计算 (impact_set)
impact_set 是最强大的图查询方法,计算指定实体的传递影响集:即所有可能受到该实体变更影响的实体集合。
def impact_set(name: str, *, ...) -> list[CodeHit]
该方法基于传递闭包算法,遍历指定实体的所有传递调用者路径,返回完整的受影响实体列表。
文件内定义查询 (defines_in_file)
defines_in_file 返回指定文件中定义的所有实体。
def defines_in_file(path: str, ...) -> list[CodeHit]
返回内容:
- 文件中的所有函数定义
- 文件中的所有类定义
- 文件中的所有模块级实体
图遍历实现
实体解析机制
图形层通过多层匹配策略解析实体名称:
- 精确匹配 - 按完全限定名查找
- 包内匹配 - 在同一作用域内查找
- 唯一后缀匹配 - 查找唯一的
ClassName.method形式 - 跨文件匹配 - 查找其他文件中同名的顶级函数
资料来源:src/thought/ingest/code/call_graph.py:1-40
作用域过滤
实体查询支持细粒度的作用域控制:
@dataclass
class ScopeFilter:
scope: ScopeName
owner_id: str | None
code_file: str | None
code_commit_sha: str | None
| 过滤条件 | 用途 |
|---|---|
scope | 多租户隔离,默认为 "shared" |
owner_id | 用户级隔离 |
code_file | 文件级隔离 |
code_commit_sha | Git 版本隔离 |
双时态查询支持
图形层支持双时态查询,能够查询知识库在特定时间点的状态:
valid_from/valid_until- 实体有效时间窗口as_of_kind='valid'- 查询历史上某时刻的事实as_of_kind='learned'- 查询系统在某时刻的知识状态
与其他模块的集成
代码提取器集成
图形层与代码提取器(Code Extractor)紧密配合:
代码文件 → 语言提取器 → CodeEntity/CodeEdge → SQLiteBackend → GraphLayer
| 提取器 | 支持语言 |
|---|---|
python_extractor | Python |
typescript_extractor | TypeScript/JavaScript |
rust_extractor | Rust |
go_extractor | Go |
java_extractor | Java |
php_extractor | PHP |
每个提取器生成 CodeEntity 和 CodeEdge,存储到后端后可通过图形层查询。
资料来源:src/thought/ingest/code/ast_extractor.py:1-50
存储后端集成
GraphLayer 依赖 SQLiteBackend 提供数据访问:
class CodeLayer:
def __init__(self, backend: SQLiteBackend) -> None:
self._backend = backend
self._graph = GraphLayer(backend)
存储后端管理实体、关系和嵌入向量的持久化,图形层在此基础上实现图遍历算法。
查询流程图
graph TD
A[CLI 命令] --> B[CodeLayer 方法]
B --> C{查询类型}
C -->|callers| D[GraphLayer 遍历调用者]
C -->|callees| E[GraphLayer 遍历被调用者]
C -->|impact| F[GraphLayer 计算传递闭包]
C -->|defines| G[GraphLayer 查询文件内实体]
D --> H[应用 PageRank 排序]
E --> H
F --> H
G --> H
H --> I[返回 CodeHit 列表]CLI 命令接口
图形层功能通过 CLI 命令暴露:
| 命令 | 功能 |
|---|---|
thought callers <name> | 查询调用者,PageRank 排名 |
thought impact <name> | 计算传递影响集 |
thought defines <file> | 查询文件内定义 |
配置与扩展
嵌入模型配置
图形层使用嵌入模型为实体生成语义向量,支持配置:
| 选项 | 说明 |
|---|---|
auto | 自动选择 sentence-transformers 或确定性嵌入器 |
sentence-transformers | 使用预训练模型 |
deterministic | 使用确定性哈希(无需外部依赖) |
图查询性能优化
- 部分索引 -
code_file、code_commit_sha等字段建立部分索引 - 身份唯一性 - 实体唯一性包含
(code_file, code_commit_sha) - 批量写入 - 单个文件的所有写入在同一事务内完成
总结
图形层是 THOUGHT 项目实现代码智能导航的核心基础设施。它通过封装 GraphLayer 提供语义感知的图遍历能力,支持调用链分析、影响范围计算等高级功能。与代码提取器和存储后端的紧密集成,使得用户能够对代码库进行深度的结构化分析和探索。
资料来源:[src/thought/layers/code.py:24-27]()
Agent集成与适配器
thought-mcp 提供了完整的 Agent 集成层,使 AI Agent 能够将项目知识库(Knowledge Base, KB)作为持久化记忆系统使用。该集成层包含两个核心组件:Claude SDK 适配器和Claude Code Hook 系统。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
1. 系统概述
Agent 集成模块让 AI Agent 在执行任务时能够:
- 检索与当前任务相关的上下文知识
- 将学习到的新知识持久化到知识库
- 增量扫描代码仓库以更新实体信息
- 通过钩子机制在交互会话的各个阶段自动触发记忆操作
这种设计使 Agent 具备长期记忆能力,避免每次会话都需要重新加载上下文信息。
2. Claude SDK 适配器
2.1 核心类:ThoughtMemoryProvider
ThoughtMemoryProvider 是专为 Claude Agent SDK 设计的即插即用记忆适配器,位于 src/thought/adapters/claude_sdk.py。
资料来源:src/thought/adapters/claude_sdk.py
该类实现了四个核心方法,完整覆盖 Agent 工作循环:
| 方法名 | 功能描述 | 返回值 |
|---|---|---|
context_for(target, role) | 获取指定角色和目标的工作上下文字典 | dict |
render_context(target) | 生成纯文本形式的系统提示增强内容 | str |
record(content) | 将 Agent 学到的知识持久化到知识库 | 无 |
scan(repo_path) | 对仓库进行增量扫描,更新实体信息 | 无 |
2.2 工作流程
graph TD
A[Agent 启动] --> B{选择集成方式}
B --> C[context_for<br/>获取工作上下文]
B --> D[render_context<br/>生成提示增强]
C --> E[Agent 执行任务]
D --> E
E --> F[record<br/>持久化新知识]
E --> G[scan<br/>增量扫描代码]
F --> H[知识库更新]
G --> H2.3 使用场景
在 src/thought/demo.py 中,Code 受众场景演示了 Agent 身份注册和工作上下文获取的完整流程:
资料来源:src/thought/demo.py:28-32
audiences = {
"code": Agent/developer flow — the 14-stage code-vertical
walkthrough including agent identity, thought scan,
working_context, 4 new-language extractors, and the
Claude Agent SDK adapter.
}
2.4 上下文检索机制
context_for 方法根据传入的 target(目标实体)和 role(角色)返回经过筛选的上下文信息。上下文内容来源于知识库的嵌入向量搜索,确保返回的信息与当前任务高度相关。
3. Claude Code Hook 系统
Hook 系统通过事件钩子实现 Claude Code 编辑器与 thought-mcp 的深度集成。
资料来源:src/thought/hooks/install.py:20-27
3.1 钩子类型与触发时机
| 钩子类型 | Claude Code 事件 | 触发命令 | 用途 |
|---|---|---|---|
recall | UserPromptSubmit | thought hook recall | 用户提交提示时检索相关记忆 |
write | Stop | thought hook write | 会话结束时保存学习到的知识 |
context | SessionStart | thought hook context | 会话启动时加载上下文 |
3.2 安装机制
Hook 安装器 (src/thought/hooks/install.py) 采用幂等设计,通过修改 .claude/settings.json 文件注册钩子:
资料来源:src/thought/hooks/install.py:1-20
_HOOK_SPEC: dict[HookKind, tuple[str, str]] = {
"recall": ("UserPromptSubmit", "thought hook recall"),
"write": ("Stop", "thought hook write"),
"context": ("SessionStart", "thought hook context"),
}
#### 安装结果状态
| 状态值 | 含义 |
|---|---|
installed | 首次安装成功 |
already_present | 钩子已存在,无需重复安装 |
error | 安装过程出错 |
3.3 幂等性保障
安装器在写入配置文件前会自动备份原始文件:
graph LR
A[读取 settings.json] --> B{检查钩子存在}
B -->|不存在| C[备份为 .bak 文件]
C --> D[合并钩子配置]
D --> E[写入 settings.json]
B -->|已存在| F[返回 already_present]备份文件命名为 <original>.thought.bak,确保配置修改可回滚。
3.4 作用域支持
支持两种安装作用域:
- 项目级 (
project):安装到.claude/settings.json,随仓库共享 - 用户级 (
user):安装到用户主目录,跨项目生效
资料来源:src/thought/hooks/install.py:34-39
4. 集成架构图
graph TD
subgraph Claude_Code
A[用户提示] --> B[UserPromptSubmit 事件]
A --> C[SessionStart 事件]
A --> D[Stop 事件]
end
subgraph Hook_System
B --> E[recall 钩子]
C --> F[context 钩子]
D --> G[write 钩子]
end
subgraph Thought_KB
H[SQLite 数据库]
I[嵌入向量存储]
J[实体/边图结构]
end
E --> H
F --> H
G --> H
H --> I
H --> J
subgraph Agent_SDK
K[ThoughtMemoryProvider]
K --> H
K --> L[Agent 上下文]
end5. 代码管道集成
Agent 集成与代码摄取管道紧密配合。当 Agent 通过 scan() 方法触发增量扫描时,后端调用 CodePipeline 进行代码解析:
资料来源:src/thought/ingest/code/pipeline.py:60-80
5.1 增量扫描流程
graph TD
A[scan(repo_path)] --> B[遍历代码文件]
B --> C{检测语言}
C --> D[Python Extractor]
C --> E[TypeScript Extractor]
C --> F[Go Extractor]
C --> G[Rust Extractor]
C --> H[Java Extractor]
C --> I[PHP Extractor]
D --> J[提取实体与边]
E --> J
F --> J
G --> J
H --> J
I --> J
J --> K[Upsert 到知识库]
K --> L[存储嵌入向量]5.2 支持的语言
系统通过 ast_extractor.py 的注册机制支持以下语言:
资料来源:src/thought/ingest/code/ast_extractor.py
| 语言 | 提取器模块 | 实体类型 |
|---|---|---|
| Python | python_extractor | module, class, function, method |
| TypeScript | typescript_extractor | module, class, function, method |
| Go | go_extractor | module, function, method |
| Rust | rust_extractor | module, function, impl method |
| Java | java_extractor | class, method |
| PHP | php_extractor | class, method |
6. 初始化与配置
在 CLI 初始化命令中,系统提供了 Agent 集成的自动配置选项:
@app.command()
def init(
config: Path = typer.Option("thought.toml"),
db_path: str = typer.Option(".thought/thought.db"),
embedder: str = typer.Option("auto"),
write_claude_md: bool = typer.Option(
True, "--write-claude-md/--no-claude-md",
help="Drop a CLAUDE.md so MCP clients learn how to use the tool."
),
quick: bool = typer.Option(False, "--quick"),
) -> None:
配置参数说明
| 参数 | 默认值 | 说明 |
|---|---|---|
config | thought.toml | 配置文件路径 |
db_path | .thought/thought.db | SQLite 数据库路径 |
embedder | auto | 向量化模型选择 |
write_claude_md | True | 自动生成 MCP 客户端使用文档 |
quick | False | 跳过首次嵌入器预热 |
7. 最佳实践
7.1 集成检查清单
- [ ] 使用
thought init完成基础配置 - [ ] 通过
thought hooks install注册 Claude Code 钩子 - [ ] 在 Agent 启动时调用
context_for()加载工作上下文 - [ ] 任务完成后调用
record()保存新知识 - [ ] 代码变更后调用
scan()更新实体索引
7.2 注意事项
- 幂等性:Hook 安装器支持重复运行,不会产生重复配置
- 备份机制:配置修改前自动备份,确保可回滚
- 作用域选择:建议使用项目级作用域 (
project) 以便团队共享 - 嵌入优化:首次初始化会预热嵌入模型,可使用
--quick跳过
8. 相关命令
| 命令 | 功能 |
|---|---|
thought init | 初始化数据库和配置文件 |
thought hooks install | 安装 Claude Code 事件钩子 |
thought hooks list | 列出已安装的钩子 |
thought hooks uninstall | 卸载钩子 |
thought recall | 检索相关记忆 |
thought scan <path> | 扫描代码仓库更新实体 |
资料来源:[src/thought/adapters/claude_sdk.py](https://github.com/RNBBarrett/thought-mcp/blob/main/src/thought/adapters/claude_sdk.py)
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
下游已经要求复核,不能在页面中弱化。
Pitfall Log / 踩坑日志
项目:RNBBarrett/thought-mcp
摘要:发现 8 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:配置坑 - 可能修改宿主 AI 配置。
1. 配置坑 · 可能修改宿主 AI 配置
- 严重度:medium
- 证据强度:source_linked
- 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
- 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
- 建议检查:列出会写入的配置文件、目录和卸载/回滚步骤。
- 防护动作:涉及宿主配置目录时必须给回滚路径,不能只给安装命令。
- 证据:capability.host_targets | github_repo:1238261514 | https://github.com/RNBBarrett/thought-mcp | host_targets=mcp_host, claude, claude_code, chatgpt
2. 能力坑 · 能力判断依赖假设
- 严重度:medium
- 证据强度:source_linked
- 发现:README/documentation is current enough for a first validation pass.
- 对用户的影响:假设不成立时,用户拿不到承诺的能力。
- 建议检查:将假设转成下游验证清单。
- 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
- 证据:capability.assumptions | github_repo:1238261514 | https://github.com/RNBBarrett/thought-mcp | README/documentation is current enough for a first validation pass.
3. 维护坑 · 维护活跃度未知
- 严重度:medium
- 证据强度:source_linked
- 发现:未记录 last_activity_observed。
- 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
- 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
- 证据:evidence.maintainer_signals | github_repo:1238261514 | https://github.com/RNBBarrett/thought-mcp | last_activity_observed missing
4. 安全/权限坑 · 下游验证发现风险项
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:下游已经要求复核,不能在页面中弱化。
- 建议检查:进入安全/权限治理复核队列。
- 防护动作:下游风险存在时必须保持 review/recommendation 降级。
- 证据:downstream_validation.risk_items | github_repo:1238261514 | https://github.com/RNBBarrett/thought-mcp | no_demo; severity=medium
5. 安全/权限坑 · 存在安全注意事项
- 严重度:medium
- 证据强度:source_linked
- 发现:No sandbox install has been executed yet; downstream must verify before user use.
- 对用户的影响:用户安装前需要知道权限边界和敏感操作。
- 建议检查:转成明确权限清单和安全审查提示。
- 防护动作:安全注意事项必须面向用户前置展示。
- 证据:risks.safety_notes | github_repo:1238261514 | https://github.com/RNBBarrett/thought-mcp | No sandbox install has been executed yet; downstream must verify before user use.
6. 安全/权限坑 · 存在评分风险
- 严重度:medium
- 证据强度:source_linked
- 发现:no_demo
- 对用户的影响:风险会影响是否适合普通用户安装。
- 建议检查:把风险写入边界卡,并确认是否需要人工复核。
- 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
- 证据:risks.scoring_risks | github_repo:1238261514 | https://github.com/RNBBarrett/thought-mcp | no_demo; severity=medium
7. 维护坑 · issue/PR 响应质量未知
- 严重度:low
- 证据强度:source_linked
- 发现:issue_or_pr_quality=unknown。
- 对用户的影响:用户无法判断遇到问题后是否有人维护。
- 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
- 防护动作:issue/PR 响应未知时,必须提示维护风险。
- 证据:evidence.maintainer_signals | github_repo:1238261514 | https://github.com/RNBBarrett/thought-mcp | issue_or_pr_quality=unknown
8. 维护坑 · 发布节奏不明确
- 严重度:low
- 证据强度:source_linked
- 发现:release_recency=unknown。
- 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
- 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
- 证据:evidence.maintainer_signals | github_repo:1238261514 | https://github.com/RNBBarrett/thought-mcp | release_recency=unknown
来源:Doramagic 发现、验证与编译记录