关于 Vectr
Vectr 是面向 AI 编码编辑器的本地守护进程,将语义代码搜索与持久工作记忆结合。它以代码结构辅助检索,并可通过会话钩子自动提供相关记忆。
主要功能
- 01基于 AST 的代码索引
- 02语义与 BM25 混合搜索
- 03符号与调用图导航
- 04持久工作记忆
- 05通过会话钩子自动注入记忆
- 06本地嵌入模型,无需 API 密钥
适用场景
- 01在陌生代码库中查找行为实现
- 02上下文重置后继续实现任务
- 03在多个编码会话间复用发现
MCP 相关
Vectr 通过 HTTP 或 stdio 向 MCP 客户端提供代码搜索和记忆工具。`vectr start` 可写入编辑器的 MCP 配置;支持会话钩子的宿主还可自动接收记忆。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Vectr
交付,而非存储。 一个本地守护进程,为 AI 代码编辑器提供代码库语义搜索,以及能在相关时自动呈现的工作记忆。
版本 1.12.0 · 上次更新于 2026-09-03 · 更新日志
30 秒了解
你的 AI 代码编辑器会为相同的知识付费两次。它会重新读取昨天读过的文件,重新 grep 已经找到的符号,并且在对话被压缩时丢失第 5 轮发现的确切签名。Vectr 是一个本地进程,可同时解决这两部分问题:
- 理解代码的检索。 支持 AST 的代码块、符号和调用图,以及结合语义与 BM25 的混合排序。描述某种行为,一次调用即可获取完整函数,无需反复 grep 和盲目读取三个文件。
- 主动交付的工作记忆。 只需保存一次发现。它会在 50 毫秒内原样返回;对于提供会话钩子的编辑器,它会在内容适用时自动呈现,无需 Agent 主动询问。
- 本地运行、无需密钥、零配置。 只需一次
pip install,再执行一次vectr start。嵌入模型在你的机器上运行。不会向任何地方传输数据,也不需要 API 密钥。
pip install vectr && cd /path/to/your/project && vectr start
这就是全部设置过程。Vectr 会为你的编辑器写入 MCP 配置,然后在后台建立索引。
vectr 与其他 AI Agent 记忆工具的区别
AI Agent 的通用记忆层是一个成熟的类别,其中优秀的工具能很好地解决实际问题。Vectr 最常被拿来与这类工具比较,因此我们在这里直截了当地说明区别。左列描述的是这类工具通常共有的设计,而非某一款产品;各工具有所不同,请查看你正在考虑的那款工具。
| 典型记忆层 | Vectr | |
|---|---|---|
| 记忆如何传递给模型 | Agent 或开发者调用显式的存储与检索 API,即 add() 和 search() 或同等接口。只有在某个环节决定发起查询时,记忆才会送达。 | 每条笔记都带有 {path, symbol, semantic, event, temporal} 触发条件。在支持会话钩子的编辑器中,运行框架会确定性地评估这些条件,并注入匹配内容。Agent 无需记得主动查询。 |
| 领域 | 通用对话记忆,面向助手和应用,而非专门针对源代码。笔记是关于用户或会话的字符串。 | 原生面向代码。符号图、AST 分块、语义代码搜索和工作记忆融合在一个守护进程中,因此笔记可以关联到真实的符号或路径,而不只是字符串。 |
| 推理 | 通常通过 LLM 提取笔记,并通过提供商 API 生成嵌入,因此设置时需要 API 密钥和提供商账户。 | 按设计,不进行任何内部 LLM 调用。使用本地嵌入模型,无需提供商账户,也无需 API 密钥。 |
| 部署 | 通常是库或可自托管的服务,并且经常同时提供托管云版本。 | 每个工作区运行一个绑定到 127.0.0.1 的本地守护进程。可选择启用团队模式。 |
为什么第一行最重要。 存储不是瓶颈。真正的问题在于检索需要 Agent 主动调用,而它基本不会调用。在我们的受控评估中,即使存储中预先放入了与任务直接相关的知识,Agent 在 114 轮中也执行了 0 次记忆操作。在每次配备注入机制的运行中,确定性注入都成功送达;审计日志记录的触发条件评估中,误报触发次数为零。在反复压缩的情况下,仅保留在对话中的 10 条事实,在 108 次强制压缩中的 106 次未能保留;而同样的 10 条事实从运行框架管理的存储中注入后,在 138 次紧凑恢复中全部完整送达。
完整方法与结果:Delivery, Not Storage: Cue-Anchored Working Memory as a Harness Property for Coding Agents(arXiv:2607.20972)。
成本与节省
这是实测数据,而非假设。 使用 vectr_recall 在一次工具调用中回忆 3 条已存储的笔记,耗费 360 个 token。在同一个包含 182 个文件的 Python 仓库中,用 grep 加 Read 重新推导相同的 3 条事实,则需要约 2,060 个 token 和 6 次工具调用。这意味着 token 用量约减少 5.7 倍,工具调用次数减少 6 倍,耗时不到 50 毫秒(按字符数除以 4 估算 token 数,完整明细见实测成本,坦诚公开)。
笔记持久化到磁盘,而非保存在对话中,因此无论经过 /compact 还是开启全新会话,都能继续使用。会话边界并不重要:第 5 轮保存、第 15 轮回忆,与 3 天后回忆使用的是同一套机制。
适用场景: 不熟悉或规模较大的代码库、需要恢复的工作,以及轮数较多的长会话。
不适用场景: 对你已经非常熟悉的代码进行一次性 grep。此时请改用 grep,并参阅 vectr 何时会适得其反。
基准测试
公开结果位于 benchmarks/。以下语料之所以选用,是因为它们规模大,而且模型不熟悉,仅此而已。
在大型且陌生的 C 代码库上完成六项任务的冲刺,模拟一周的功能开发工作。一次研究会话使用 vectr_remember 保存发现。六个相互隔离的实现会话均从冷启动开始,并调用 vectr_recall。
仅实现会话,合计 6 项任务:
| 指标 | Vanilla | Vectr | 差值 |
|---|---|---|---|
| 成本 | $2.50 | $1.97 | -21% |
| 耗时 | 17.6 min | 13.5 min | -24% |
| 轮次 | 123 | 94 | -24% |
| Read + Bash 调用 | 102 | 62 | -39% |
每项任务的重新探索(首次写入前的 Read 和 Bash 调用):
| 任务 | Vanilla | Vectr | 差值 |
|---|---|---|---|
debug_gc_finalizer | 16 | 6 | -62% |
feature_dict_pop_last | 13 | 3 | -77% |
cross_session_set_cartesian | 23 | 9 | -61% |
debug_descriptor_priority | 6 | 6 | 0% |
cross_session_bytes_find_all | 13 | 2 | -85% |
cross_session_list_rotate | 21 | 16 | -24% |
0% 这一行是真实结果,并且是有意保留的:模型仅凭训练知识就已经能处理该任务。
如实说明研究与实现的区别。 研究阶段只付费一次,使用 vectr 的成本更高(+94%),因为保存丰富的代码桩和签名会产生输出 token。实现阶段会对每项任务重复进行,成本更低,因为调用记忆取代了重新探索。大约复用 8 项任务的笔记后,额外开销即可打平。
| 阶段 | Vanilla | Vectr | 原因 |
|---|---|---|---|
| 研究(1 个会话,仅付费一次) | $1.36 | $2.63 | 保存笔记会消耗输出 token |
| 实现(6 个会话,重复进行) | $2.50 | $1.97 | 笔记取代重新探索 |
| 冲刺总计 | $3.86 | $4.60 | 约 8 项任务后,结果转为净收益 |
此前在一个包含 5,856 个文件的 Java 语料上进行的测试显示:实现成本降低 58%、实现工具调用减少 72%、耗时缩短 39%。
如实衡量成本
每次调用的 token 成本(中位数,182 个文件的 Python 仓库,按字符数除以 4 估算 token):
| 工具 | token 中位数 | 范围 |
|---|---|---|
vectr_search | ~2,320 | 1,437 to 3,091 (n=8) |
vectr_locate | ~192 | |
vectr_trace | ~720 | |
vectr_recall (index tier) | ~180 |
坦率地说,这种取舍是:对于小型、已经熟悉的仓库中的单次精准查找,grep 更省成本。在 5 项单事实任务中,Vectr 的 token 中位成本高出 60%,而且速度也更慢,因为一次 vectr_search 往返需要 1.7 到 3.6 秒,而 grep 约需 28ms。Vectr 并不以单次调用成本取胜。它的优势在于工具调用次数(一次往返而非多次)、答案完整度(返回整个符号,而非部分文件内容),以及工作记忆中的所有信息;在这些场景中,5.7 倍的记忆调用成本返还会随着每次恢复任务而累积。
补充说明:工具响应中附带的自动淘汰和提醒横幅也会消耗 token。始终开启的重新获取页脚约需 27 个 token,轻量提醒约需 89 个 token,而升级后的“需要采取行动”横幅(只有在未保存且同时超过块数和 token 阈值后才会触发)会从约 480 个 token 增至 535 个 token,之后趋于稳定。
快速开始
本地安装(推荐)
python3.14 -m venv ~/.vectr-env
source ~/.vectr-env/bin/activate # Windows: ~/.vectr-env/Scripts/activate
pip install vectr
cd /path/to/your/project
vectr start
需要 Python 3.14+。 安装方式:
- macOS:
brew install [email protected] - Ubuntu/Debian:
sudo add-apt-repository ppa:deadsnakes/ppa && sudo apt install python3.14 python3.14-venv - Windows:python.org/downloads
vectr start 会立即返回。索引会在后台运行,因此请运行 vectr status 查看进度。首次运行时,嵌入模型会下载一次(约 290 MB)。重启一次 AI 代码编辑器,以加载新的 MCP 配置。
Docker(CI 和服务端)
git clone https://github.com/swapnanil/vectr
cd vectr
docker-compose up api
会开放端口 8765。Docker 不会自动写入 IDE 配置文件,因此 IDE 集成请使用本地安装。
连接到 AI 代码编辑器
vectr start 会自动为你的编辑器写入 MCP 配置。重启编辑器一次即可。
| 编辑器 | 配置 | 状态 |
|---|---|---|
| Claude Code | 自动:.claude/settings.json、指导文件和会话钩子(记忆会在会话开始时、每次提示词时,以及读取或编辑文件前自动注入) | 已验证 |
| Cursor | 自动:.cursor/mcp.json | 实验性 |
| VS Code / GitHub Copilot | 自动:.vscode/mcp.json | 实验性 |
| Windsurf | 手动,见下文 | 实验性 |
| Cline | 手动,见下文 | 实验性 |
| Continue | 手动,见下文 | 实验性 |
| Codex CLI | 自动:.codex/config.toml、AGENTS.md 指导文件和 .codex/hooks.json(vectr init --hooks) | 实验性 |
“已验证”表示已端到端测试完整集成(配置、指导文件和钩子)。“实验性”表示已写入 MCP 配置且可以正常工作,但尚未经过相同的验证流程。
记忆能否自动传递,取决于宿主是否提供会话钩子。对于不提供会话钩子的宿主,以下所有工具仍可按需通过 MCP 使用。
手动设置
Claude Code,.claude/settings.json:
{ "mcpServers": { "vectr": { "type": "http", "url": "http://localhost:8765/mcp" } } }
Cursor,.cursor/mcp.json:
{ "mcpServers": { "vectr": { "url": "http://localhost:8765/mcp" } } }
VS Code / GitHub Copilot(1.99+),.vscode/mcp.json:
{ "servers": { "vectr": { "type": "http", "url": "http://localhost:8765/mcp" } } }
Windsurf,~/.codeium/windsurf/mcp_settings.json:
{ "mcpServers": { "vectr": { "serverUrl": "http://localhost:8765/mcp" } } }
Continue.dev,.continue/config.json:
{ "mcpServers": [{ "name": "vectr", "transport": { "type": "http", "url": "http://localhost:8765/mcp" } }] }
Codex CLI,项目范围的 .codex/config.toml(由 vectr start 自动写入):
[mcp_servers.vectr]
url = "http://localhost:8765/mcp"
Codex 首次在工作区运行时,会显示一次性交互式提示,要求信任此项目,然后才会加载项目范围的配置。如果你还运行了 vectr init --hooks,Codex 会再显示一次性提示,要求信任钩子命令。这两项在接受一次后会一直生效;配置写入器无法替你清除这些提示,因为这会削弱你的安全保障。
Stdio 传输
上述编辑器通过 HTTP 连接(vectr start 加 POST /mcp)。对于会将服务作为子进程启动,并通过其 stdin 和 stdout 而非建立 HTTP 连接来传输 MCP 的 MCP 客户端和托管平台,请运行:
vectr mcp-stdio [WORKSPACE]
无需端口,也无需守护进程:单个前台进程以换行符分隔的 JSON-RPC 2.0 格式传输数据(stdin 和 stdout 中每行一个 JSON 对象,不带 Content-Length 标头)。initialize 和 tools/list 会立即响应,而嵌入模型加载和初始索引会在后台线程中进行。在这些操作完成前调用 tools/call,会收到友好的“仍在启动”响应,而不会一直等待。Stdout 只传输协议 JSON,所有日志都会写入 stderr。stdin 遇到 EOF 时,进程会正常退出。--memory-only 和 --search-only 的行为与 vectr start 中相同。
工作原理
- 感知 AST 的分块。 tree-sitter 会解析每个文件,并在函数、类和方法的边界处分块。不会在逻辑中途切分。
- 代码嵌入。
ibm-granite/granite-embedding-english-r2(本地运行、CPU 处理速度快、可覆盖)会将自然语言查询映射到代码符号,因此搜索“JWT 验证”会找到verify_jwt_token。BM25 负责处理精确的符号名称。 - 混合搜索。 将向量相似度与 BM25 结合,并根据代码库特征分配权重。大型且不熟悉的代码库更侧重语义搜索;小型且文档完善的代码库更侧重 BM25。
- 符号图。 提取并存储调用边、导入链和 HTTP 路由(Flask、FastAPI、Express、Spring)。
vectr_locate通过 6 种策略依次查找名称:精确匹配、后缀、同一模块、导入链、子串,然后是模糊匹配。模糊匹配结果始终会明确标示为不精确,而不会被当作可靠匹配呈现,因为自信地给出错误符号比找不到更糟。 - 工作记忆。
vectr_remember会将结构化笔记存储到 SQLite 和 ChromaDB。vectr_recall会对笔记进行语义搜索,而非使用 SQL LIKE,因此多词查询仍能找到相关上下文。 - 触发条件评估。 守护进程会在生命周期节点确定性地检查每条笔记的条件,并使用按会话记录的触发台账和注入预算,因此笔记会在适用时准确地再次出现,且在同一时间窗口内不会重复出现。
- MCP 协议。 通过 HTTP 提供 23 个工具。任何兼容 MCP 的 AI 代码编辑器都能连接,无需插件。
23 个 MCP 工具
vectr start 会将一份包含此表的指导文件写入你的工作区,让 AI 代码编辑器知道该使用哪个工具,无需你提示。
搜索工具,用于从索引中检索代码:
| 情况 | 工具 |
|---|---|
| 你知道某个概念或行为,但不知道名称 | vectr_search("description") |
| 你知道符号名称,但不知道它所在的文件 | vectr_locate("SymbolName"),支持多策略回退链,并可选传入 caller_file |
| 你需要查找某个符号的调用方或被调用方 | vectr_trace("symbol_name") |
| 你需要了解架构概览 | vectr_map() |
| 你想保存综合后的映射摘要 | vectr_map_save(summary) |
| 你有要注入的运行时调用数据 | vectr_ingest_traces([{caller, callee}]) |
| 你需要查看索引健康状况或笔记数量 | vectr_status() |
记忆工具,用于跨会话存储和回忆信息:
| 情况 | 工具 |
|---|---|
| 存在之前会话留下的笔记 | vectr_recall(query),使用语义向量搜索,而非子字符串匹配;采用双层结构(默认显示精简索引,可用 note_id=N 展开一条笔记,或用 detail='full' 展开所有正文) |
| 无论查询内容如何,都必须在每次召回时保留一条笔记 | vectr_pin(note_id=N),将笔记放入 Tier 0,使其在每次 vectr_recall(query=...) 调用时都会注入。容量有限,请谨慎固定。vectr_remember(..., pin=true) 可在写入时执行相同操作 |
| 发现值得保留的信息 | vectr_remember(content, tags, priority, kind, title, agent)。kind 控制交付方式:directive 会在每个会话中无条件触发,task 保存当前工作状态,gotcha 会在涉及对应文件时重新显示,operational 涵盖构建和环境信息,finding(默认值)按相关性排序,reference 用于提供指针,decision 用于记录架构决策,可通过 vectr_recall(kind="decision", sort_by="chronological") 按时间顺序以 ADR 风格的时间线召回。title 为索引输出中的笔记添加标签,agent 用于注明负责的子 Agent 或协调 Agent |
| 发现已存储的笔记涉及未声明的文件 | vectr_anchor(note_id=N, anchors=[...]),为现有笔记附加文件锚点,而无需重新存储。此操作幂等,在写入时进行哈希处理,且不会发出生命周期事件,因此笔记历史保持干净(CLI 中也可使用 vectr anchor --id N PATH...) |
| 已存储的笔记锚定到了错误的文件,或锚定文件已不再相关 | vectr_unanchor(note_id=N, anchors=[...]),与 vectr_anchor 相反。此操作会从笔记的锚点集合中移除文件路径;移除锚点只会使其不再成为过时候选项,绝不表示笔记有误。此操作幂等;对于笔记从未锚定过的路径,会将其报告出来,而非视为失败 |
| 开始会话,想从上次中断处继续 | vectr_resume(),通过一次调用返回最近的任务笔记、最新快照,以及带有文件锚点的未解决注意事项(CLI 中也可使用 vectr resume) |
| 上下文快满了 | vectr_evict_hint(),用于识别 vectr 可以重新检索的区块,并提供精确的重新获取 ID |
| 之前显示的区块已不在上下文中 | vectr_fetch(ids=[...]),通过 ID 确定性地逐字节重新获取,不会重新搜索或重新读取文件。如果索引本身存储的是截断后的区块,则会标记截断警告 |
| 长会话结束,想创建检查点 | vectr_snapshot("label") |
| 查找之前的检查点 | vectr_snapshot_list() |
| 大规模重构后,笔记已过时 | 对每条笔记使用 vectr_forget(note_id=N),或使用 vectr_forget(all=true) 清空 |
| 自动捕获的笔记已审核且仍然有效 | vectr_promote(note_id=N),将其信任级别从 auto 提升一级至 agent。提升至 human 仅限用户侧界面,Agent 不能执行此操作 |
| 正在等待处理自动捕获的失败转成功记录 | vectr_distill(),用于呈现待审核的过程记录(命令执行失败,随后经编辑后成功)。使用 vectr_remember(..., distilled_from=[arc_id]) 保存经验,或使用 vectr_distill(dismiss=[...], reason) 忽略 |
| 发现已存储的笔记有误 | vectr_revoke(note_id=N, reason),不会删除笔记,而是将其保留并标记为警示(“之前曾认为……,现已撤销……”),以免错误被悄然重新推导出来。vectr_remember(contradicts=N) 可一步完成纠正和撤销 |
| 笔记只是过时了,并非有误 | vectr_supersede(note_id=N, successor_note_id=M),用更新的笔记取代该笔记,而不采用 revoke 中“已证实有误”的表述。审计记录会明确区分事后退役和写入时的取代,且可通过 vectr_reinstate 撤销此操作 |
| 已撤销的笔记原来是正确的 | vectr_reinstate(note_id=N),恢复原始内容 |
触发器:交付层
这些 kind 值带有合理的默认设置。笔记也可以在 vectr_remember 上声明显式的逐笔记 triggers:
| 维度 | 触发时机 |
|---|---|
path | glob 匹配当前生命周期时刻所针对的文件 |
symbol | 目标文件定义或引用了该符号;解析时严格使用与 vectr_locate 相同的符号图,绝不模糊匹配 |
semantic | 提示词相似度超过固定的逐类型阈值 |
event | 发生生命周期时刻:session-start、prompt-submit、pre-edit、pre-run、pre-commit 或 post-compaction |
command | 即将运行的 shell 命令的规范化动词匹配 glob |
| temporal | not_before、expires_visibility 和 cooldown 限制条件;它们只会修改触发,不会单独触发 |
同一条目内的条件以 AND 组合,不同条目之间以 OR 组合。每次触发都会附带一行说明,指出匹配了哪个触发条件。注入内容受预算限制(每轮硬性上限,由所有界面共同消耗),并会按笔记 ID 在一轮内的所有界面去重,同时标明来源,因此未经审核的自动捕获笔记绝不会被呈现得像是你设定的常驻规则。笔记不会被部分截断:它会完整呈现为索引级别的一行,否则就不会呈现。
工作区范围的笔记还可作为多 Agent 工作流的共享总线。编排器及其子 Agent 都读取和写入同一个笔记存储,因此子 Agent 可以在结束前调用 vectr_remember(..., agent="coder-2") 保存发现,编排器随后即可检索这些内容,而不必重新阅读子 Agent 的完整对话记录。agent 参数绝不会通过推断获得。它是显式归属信息,并会作为标签显示在 vectr_recall 的索引输出中。
CLI 参考
vectr start # index + start daemon for current dir
vectr start /project/api # positional workspace: a directory or .code-workspace file
vectr start --path /project/api # specific workspace (repeatable, multi-root)
vectr start --memory-only # working memory + hooks only, no code index, no watcher
vectr status # index health, chunk count, notes count
vectr status --all # all running instances
vectr stop /project/api # stop one instance (same positional as start)
vectr stop --path /project/api # stop one instance (equivalent --path form)
vectr stop --all # stop all instances
vectr index --path . # re-index without restarting daemon
vectr fetch src/auth.py:10-42 # re-fetch a chunk by exact id, verbatim
vectr resume # most recent task note, latest snapshot, open gotchas
vectr init --path . # write guidance file + MCP config without starting
vectr init --exclude vendor # exclude directories from indexing
vectr forget --path . # delete all working-memory notes
vectr memory export # render the working-memory store as a greppable, git-diffable markdown file (default MEMORY.md)
vectr memory export --path notes.md # write the export to a specific file
vectr memory export --disable # stop the auto-refresh that keeps the export file in sync
vectr memory edit # open the working-memory store in your $EDITOR, one block per note
vectr memory import # bring existing on-disk memory files into the working-memory store (see below)
vectr memory import --path NOTES.md # import a specific file instead of the default discovery list
vectr memory import --dry-run # preview what would be created (kind, title, source file, line range), change nothing
vectr cache prune # remove empty per-workspace cache dirs (live instances skipped)
vectr cache prune --dry-run # preview what would be removed, delete nothing
vectr proxy # experimental: localhost API proxy (see below)
vectr mcp-stdio # foreground stdio MCP transport, no port or daemon (see above)
导入现有记忆
vectr memory export 和 vectr memory edit 分别是单向导出路径和签出/签入路径。vectr memory import 则是单向导入路径:无需手动重新录入,即可将磁盘上已有的记忆导入工作记忆存储。这为已经写下记忆的新用户提供了入门途径。
发现。 如果不指定 --path,导入器会遍历工作区根目录中一组固定的默认候选文件:MEMORY.md、CLAUDE.md、AGENTS.md、.cursorrules 和 .github/copilot-instructions.md。传入 --path(可重复指定)即可指向其他文件或目录;目录会递归遍历其中的 *.md 和 *.mdc 文件。不存在的文件会被报告,但不会导致报错,因为大多数工作区都不会包含所有默认文件。
粒度。 一个源文件既不会作为一条笔记,也不会按每行拆分成一条笔记。它会在 Markdown 标题边界(^#{1,6}\s+)处分割,方式与人们浏览 MEMORY.md 时相同。没有标题的文件会成为一条笔记。围栏代码块和 HTML 注释块中的标题会被跳过,因此代码示例或导出文件的头部注释不会成为章节边界。通过 `` 标头检测到由 vectr memory export 导出的文件后,会使用 vectr memory edit 的同一套块语法进行解析,将每个原始块还原为一条笔记,并沿用其声明的 kind、priority、tags 和 provenance。
试运行。 --dry-run 会准确打印将要创建的内容(种类、标题、源文件、源行范围、来源),且不做任何更改。记忆是用户难以重建的资源,因此应优先进行试运行:
vectr memory import --dry-run
# + [finding/auto] 'Project conventions' (MEMORY.md:12-34)
# + [operational/agent] 'Test runner' (CLAUDE.md:5-9)
# DRY RUN: would create 2 note(s), skip 0 already-imported, ...
幂等性。 每条导入的笔记都会带有 src:、src-sha: 和 src-lines: 这组三个标签。对未更改的源文件重新运行 vectr memory import 时,会识别这些标签,不会创建任何新笔记。如果编辑源文件中的某个章节,其正文哈希将与已存储的哈希不匹配,因此会成为一条新笔记,而旧笔记会保持不变,因为在用户不知情的情况下悄悄删除先前导入的内容,正是设计在导出侧要防范的无声丢失。
来源。 导入的笔记带有源文件标签(imported 和 src:FILENAME,其中 FILENAME 是源文件的基本名称),因此,在列出带有 imported 的笔记时,用户会知道“这条内容来自文件,而不是本次会话中的观察”。笔记的 provenance 默认为 auto,因为机器捕获且未经审阅判断的事实本来就带有此类别;对于解析器而言,手写的 MEMORY.md 在结构上与生成器的输出无法区分。例外范围狭窄,且依据结构而非语义判断:正文包含命令式规则标记(固定关键词集合 MUST、MUST NOT、NEVER、ALWAYS、DO NOT、DON'T、REQUIRED、FORBIDDEN)的笔记会被归类为 kind="directive",并将 provenance 升级为 agent。这是因为 remember() 在写入时会进行 auto + directive 防护:未经审阅的常驻规则自相矛盾,而导入的规则恰好属于这种情况。升级为 agent 是对 auto 的最小偏离,刚好足以通过防护;用户审阅后可通过 vectr_promote 进一步提升。
排除路径
在项目根目录中创建 .vectrignore(语法与 .gitignore 相同):
vendor/
node_modules/
*.pb.go
dist/
或者在初始化时传入 --exclude:
vectr init --exclude vendor --exclude dist
排除规则既适用于初始索引遍历,也适用于实时文件监视器,因此将目录添加到 .vectrignore 后,正在运行的实例也会停止为其重新建立索引。下一次索引还会清理因文件现已被排除或已删除而留存的分块,因此无需从头重建。如果需要彻底重建,例如更改嵌入模型后,请强制执行:
vectr index --path . --force # ignore the incremental cache, re-embed everything
支持的语言
| 语言 | 分块方式 | 符号图 |
|---|---|---|
| Python | AST(函数、类) | 是 |
| JavaScript | AST(函数、类、箭头函数) | 是 |
| TypeScript | AST | 是 |
| Go | AST | 是 |
| Rust | AST | 是 |
| Java | AST | 是 |
| C | AST | 是 |
| C++ | AST | 是 |
| Zig | AST | 是 |
| 其他所有语言 | 200 行窗口,重叠 50 行 | 否 |
HTTP 路由(Flask 和 FastAPI 装饰器、Express app.get()、Spring @GetMapping)会作为符号提取,并可通过 vectr_locate("GET /api/users") 搜索。
成本
| 成本 | |
|---|---|
| 嵌入模型 | $0.00,一次性下载约 290 MB,缓存于 ~/.cache/vectr/ |
| 重新索引(首次运行,10k 个文件) | CPU 上约 10 分钟,后续运行不到 5 秒(mtime 缓存) |
| 每个变更文件的增量重新索引 | 约 0.5 秒 |
| vectr_search / vectr_recall | $0.00,仅本地推理 |
安全性
默认设置保持不变,核心原则依然是:供个人设备上的独立开发者使用,本地运行、无需 API 密钥、零配置。开箱即用时,守护进程仅绑定到 127.0.0.1,CORS 仅允许 localhost 来源,每个工作区都有各自隔离的数据库目录、端口和进程(POSIX 系统上权限为仅所有者可访问的 0700),索引和笔记保存在本地 ~/.cache/vectr/ 中。
以下功能均为可选启用。不启用任何功能,就不会有任何变化。
身份验证。 设置 VECTR_API_KEY 后,所有发往 /v1/* 和 /mcp 的请求都必须携带该密钥(使用 X-Api-Key: <key> 或 Authorization: Bearer <key>,采用恒定时间比较;/v1/health 除外,该端点保持开放以供存活探测)。使用 vectr key 生成密钥。如果启动时已设置密钥,vectr 写入的编辑器 MCP 配置会自动包含该请求头。这些文件(.mcp.json、.cursor/mcp.json、.vscode/mcp.json)会以明文保存密钥,因此请将其视为机密,并避免将它们提交到共享或公开的版本控制中。
静态加密。 设置 VECTR_ENCRYPT_KEY,或将密码短语存储在操作系统密钥链中(服务名为 vectr,用户名为 encrypt-key,需要 pip install vectr[encryption]),即可使用 Fernet 和 PBKDF2 派生密钥加密笔记内容、笔记标题和快照载荷。需要说明的是:代码索引不会加密,因为搜索引擎需要可读的代码块文本和向量。请使用操作系统全盘加密来保护它。笔记标签和元数据仍以明文保存;笔记嵌入向量(笔记文本的有损投影)也会保留,以便进行语义检索,除非设置 VECTR_ENCRYPT_DISABLE_NOTE_VECTORS=1。
保留与审计。 笔记会一直保留,直到你将其删除。设置 VECTR_NOTES_TTL_DAYS,即可在启动时自动清除超过指定天数的笔记。vectr_forget(all=true) 和 vectr forget --all 会删除笔记、快照和笔记向量,因此会删除所有内容。设置 VECTR_AUDIT_LOG=<path>,即可记录索引、搜索、记忆存储和回忆事件,并在本地轮换日志(默认关闭;日志会记录查询文本,这正是其用途,且绝不会被传输)。完整策略:docs/data-handling.md。
团队模式(共享实例)。 一台中央守护进程即可为团队提供对一个仓库的服务。在服务器上运行 VECTR_API_KEY=<key> vectr start --host 0.0.0.0(绑定到非回环地址时,没有密钥将拒绝启动),然后在每个客户端上运行 vectr connect --url http://<host>:<port> --api-key <key> --label <you>,将编辑器指向该服务。工作记忆是共享的:一个 Agent 存储的笔记,所有已连接的 Agent 都可以回忆;--label 会标注笔记和审计日志行。笔记 ID 由中央存储按写入到达顺序分配,因此多个客户端并发使用时,你的笔记 ID 不会连续,而会与其他客户端的 ID 交错。写入操作返回的 Stored note #N 行是该笔记的权威引用,因此不要假设下一个 ID 也属于你。明确来说:使用同一个共享密钥意味着每个持有者都是权限相同且可信的对等方(没有角色或按用户划分的权限);服务器运营者可以读取所有内容;搜索结果引用的是服务器上的工作副本,可能与你本地的代码树不同;vectr 使用明文 HTTP,因此如果网络不可信,请通过反向代理或隧道配置 TLS。
主动上下文(实验性,仅限 localhost)
基于拉取的回忆意味着 Agent 必须主动询问。主动上下文通过直接介入通信链路,为没有会话钩子的宿主提供确定性内容传递。此功能为实验性功能,且仅限 localhost。从 1.6.0 版本起,本地实例默认启用主动传递(proactive.enabled;设置 VECTR_PROACTIVE=0 可将其关闭)。下方的通信链路由启动时的授权决定,而非由该开关控制:启动代理并将 Agent 指向代理即表示选择启用;停止代理或取消设置基础 URL 即表示选择退出。
vectr proxy 命令会在 Agent 和模型 API 之间运行一个小型本地代理:
vectr proxy # starts a localhost proxy (default :8785)
export ANTHROPIC_BASE_URL=http://127.0.0.1:8785 # point your agent at it
以下是它的功能与限制,直言不讳:
- 默认透明。 它会将每个请求转发到真实 API,流式响应和工具调用也会逐字节原样通过。你的 API 密钥会原样转发,绝不会被存储或记录。
- 确定性注入。 工作区守护进程运行时,它会在最后一个提示词缓存断点之后,将匹配的工作记忆笔记附加到请求中,因此绝不会使提示词缓存失效。触发条件是相似度阈值加精确的结构匹配,而非猜测关键词;同时设有严格的每请求预算,确保只有在提示信息值得消耗这些令牌时才会注入。
- 故障时放行。 如果智能层响应缓慢或出错,请求仍会原样通过。要完全绕过代理,请取消设置基础 URL:
unset ANTHROPIC_BASE_URL。代理位于请求路径上,因此如果代理不可用,请取消设置该变量,直接与 API 通信。 - 仅限独立模式和 localhost。 它会读取你的对话来计算上下文,因此拒绝绑定任何非回环地址,并且不能与团队模式同时使用。
- **关于使用非第一方基础 URL 的注意事项,**依据宿主自身的文档:除非设置
ENABLE_TOOL_SEARCH=true且代理转发工具引用块,否则 MCP 工具搜索会被禁用;而在非api.anthropic.com的基础 URL 上,Remote Control 会被禁用。
全组织缓存(团队模式)。 使用中央共享实例时,vectr 可以缓存自身开销较大的产物,即语义搜索和回忆结果,并以精确身份和当前索引状态作为键,因此重新索引或笔记变更会自动使缓存失效,所有连接的开发者都能从中受益。此功能默认关闭(proactive.cache);vectr status 会报告缓存命中率和预计节省的令牌数,以便衡量实际效果,而不是空口断言。Vectr 不会跨相似请求缓存大模型响应,只会在本地、经用户选择启用的情况下缓存字节完全相同的响应,因为错误的缓存命中会悄无声息地破坏对话。
vectr 可能带来的负面影响
代码库变动后笔记过时。 笔记会在写入时记录文件路径。进行大规模重构后,vectr_recall 会用 [STALE] 标记引用的已变更文件。采取行动前请重新核实;使用 vectr_forget(note_id=N) 删除过时笔记,或使用 vectr_forget(all=true) 清除所有笔记。
对熟知的 API 过度检索。 如果模型在训练中已深入了解某个框架,vectr 的研究开销可能超过其带来的节省。上方的基准测试准确展示了这种情况:在 debug_descriptor_priority 任务中,仅凭训练知识就足以完成导航。
架构概览过时。 通过 vectr_map_save 保存的架构护照描述的是索引时的架构。模块重命名或入口点重构后,内容可能看似可靠实则错误,因此 vectr_map 会显示过时警告,你应重新运行 vectr_map_save。
广泛回忆会消耗令牌。 不带查询调用 vectr_recall() 会返回所有内容。请传入有针对性的查询;如果不确定是否需要回忆,先检查 vectr_status()。
构建所用技术
Python 3.14 · FastAPI · sentence-transformers · tree-sitter · ChromaDB · BM25 · Docker
作者
Swapnanil Saha · swapnanilsaha.com
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。