代码监视存储器
用于AI编码助手的代码感知观察记忆MCP服务器。
AI编码助手(Claude Code、Cursor、Windsurf)患有会话失忆症——在压缩或会话之间丢失上下文。现有的解决方案要么是框架锁定的(Mastra的Observational Memory需要他们的代理框架),要么是简单的(mcp内存保持器在没有智能压缩的情况下存储键值对)。
代码监视存储器 是一个MCP原生服务器,专门为编码工作流程实现观测内存。它使用廉价的LLM(Groq、Gemini Flash)作为观察者/反射者代理,将对话上下文压缩到结构化的观察日志中,存储在SQLite中,每个git分支都有作用域。
建筑
┌─────────────────────────────────────────────────────────────────┐
│ Claude Code / Cursor / Windsurf │
│ (MCP Client) │
└──────┬──────────────────┬──────────────────────┬────────────────┘
│ │ │
[Stdout/Stdin] [Hook: Stop/PreCompact] [Hook: UserPromptSubmit
(MCP Tools) (save observations) /SessionStart]
│ │ (recall context)
v v │
┌────────────┐ ┌──────────────────┐ v
│ MCP Server │ │ Hook Subprocess │ ┌──────────────────┐
│(stdio mode)│ │ --hook mode │ │ Recall Subprocess│
└─────┬──────┘ └────────┬─────────┘ │ --recall mode │
│ │ └────────┬─────────┘
│ 5 Tools │ Transcript │ FTS5 search
│ observe/recall/ │ parsing & │ keyword extraction
│ reflect/ │ observation │ (no LLM, ~50ms)
│ get_session_info│ extraction │
│ switch_context │ │
v v v
┌──────────────────────────────────────────────────────┐
│ Agents Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Observer │ │Reflector │ │ Categorizer │ │
│ │ extract │ │ compress │ │ classify │ │
│ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │
└───────┼──────────────┼───────────────┼───────────────┘
│ │ │
v v v
┌──────────────┐ ┌────────────────────────────┐
│ LLM Provider │ │ SQLite Database │
│ Groq (free) │ │ sessions / observations │
│ Google │ │ reflections / tasks │
│ OpenAI │ │ FTS5 full-text search │
└──────────────┘ └────────────────────────────┘运作原理
核心循环
Capture → Categorize → Store → Search → Compress三种操作模式:
- 挂钩模式 (
--hook)——每次AI响应后自动触发(Stop事件)和上下文压缩之前(PreCompact).从对话记录中读取最后20条消息,将其发送给廉价的法学硕士,并提取结构化的观察结果。无需手动调用工具。
- 召回模式 (
--recall)--着火了UserPromptSubmit(每个用户提示)和SessionStart(会话开始/恢复/压缩)。通过FTS5关键字提取搜索存储的观察结果,并注入相关上下文。纯数据库查询,无LLM——增加了约50ms的延迟。
- MCP服务器模式 --作为MCP服务器运行,带有5个工具,AI助手可以直接调用这些工具进行手动观察、回忆和压缩。
观测流程
Hook fires on Stop/PreCompact
→ Read last 20 transcript messages (JSONL)
→ Skip if < 50 tokens (trivial turn)
→ Skip if already processed (hash dedup)
→ Send to Observer LLM agent
→ Extract observations with priority + category
→ Store each in SQLite (FTS5 auto-indexed)
→ Update session stats
→ Check auto-reflect threshold (default 40K tokens)
→ If over: run Reflector with escalating compression召回流程(自动)
User types a prompt
→ UserPromptSubmit hook fires
→ Extract keywords from prompt (stop-word filtering, file paths, quoted phrases)
→ FTS5 search with OR query for broad recall
→ Fallback: individual keyword search → category heuristic
→ Inject matching observations as context (max ~1K tokens)
→ Claude sees relevant memories before processing the prompt召回流程(手动)
AI calls recall(query="authentication")
→ FTS5 full-text search on observations
→ Filter by category / priority / files / branch
→ Group by date with priority emojis
→ Include compressed reflections if requested
→ Include current task context
→ Return formatted observation log三个代理人
观察员代理人
从AI开发人员的对话中提取事实和决策。频繁运行(通过钩子执行每个Stop事件)。
- 温度:0.3(在措辞、事实方面有一些创意)
- 输入:最后20条对话消息
- 输出:具有优先级表情符号、节标题、时间戳的结构化观察
优先级系统:
- 高 (神圣的——在所有压缩中幸存下来):架构决策、用户偏好、错误根源、安全决策、破坏性更改
- 中等:实现细节、文件修改、依赖项添加、测试结果、API端点、架构更改
- 低 (首先压缩):探索性问题、次要格式、临时调试步骤、废弃方法
观察员遵循的关键规则:
- 区分断言和问题(“我应该使用Redis吗?”不是“我们使用Redis”)
- 保留特定值:文件路径、函数名、版本、错误消息
- 提取事实和决定,而不是推理
- 切勿捏造观察结果
反射剂
压缩观察结果,同时保留关键信息。很少运行(仅当令牌超过阈值时)。
- 温度:0(确定性,无幻觉)
- 输入:所有未经反映的意见
- 输出:目标令牌计数时的压缩观察日志
4个压缩级别,可升级:
| 级别 | 细节 | 减少 | 策略 |
|---|---|---|---|
| 0 | 10/10 | 0% | 仅重新组织--合并重复项,修复格式 |
| 1 | 8/10 | ~20% | 删除低优先级,合并惯例 |
| 2 | 6/10 | ~40% | 删除所有低优先级,按文件/模块合并 |
| 3 | 4/10 | ~60% | 段落摘要,仅最近日期保留单个条目 |
所有级别都能生存的神圣内容:
- 架构决策+基本原理(从不压缩)
- 用户偏好(永久)
- Bug修复根本原因(症状下降,修复持续)
- 代码库学习
升级: 如果压缩没有达到目标令牌计数,Reflector会自动尝试下一级,直到级别3。
分类程序
将观察结果分为8类。首先使用启发式关键字匹配(免费、即时)。只有当信心\<0.7时,才会回落到LLM。
观察类别
| 类别 | 描述 | 默认优先级 |
|---|---|---|
architecture | 设计决策、所选图案 | 高 |
user_preference | 用户的编码偏好、工作流选择 | 高 |
bugfix | 发现错误、根本原因、修复 | 中等 |
convention | 代码约定、命名模式 | 中等 |
dependency | 软件包选择、版本决定 | 中等 |
file_pattern | 重要文件位置、项目结构 | 中等 |
task_context | 当前任务目标、进度 | 中等 |
learning | 从代码库中学到的东西 | 媒介 |
快速入门(克劳德代码)
# 1. Add the MCP server
claude mcp add codewatch -- npx codewatch-memory
# 2. Set up automatic hooks (saves + recalls memory without manual tool calls)
npx codewatch-memory --setup
# 3. Set at least one LLM API key for the Observer agent
export GROQ_API_KEY=your-key # recommended (free tier)就是这样。每次响应后都会保存观察结果,并在您键入提示时自动调用。
安装
克劳德代码(CLI)
claude mcp add codewatch -- pnpx codewatch-memory
npx codewatch-memory --setup克劳德代码(VSCode)
添加 .vscode/mcp.json:
{
"servers": {
"codewatch-memory": {
"command": "pnpx",
"args": ["codewatch-memory"],
"env": {
"GROQ_API_KEY": "${input:groqApiKey}",
"CODEWATCH_LLM_PROVIDER": "groq"
}
}
}
}然后运行 npx codewatch-memory --setup 在您的项目中配置自动挂钩。
光标/风帆
添加到MCP配置(.cursor/mcp.json):
{
"mcpServers": {
"codewatch-memory": {
"command": "pnpx",
"args": ["codewatch-memory"],
"env": {
"GROQ_API_KEY": "your-key",
"CODEWATCH_LLM_PROVIDER": "groq"
}
}
}
}注:自动挂钩(--setup)目前只有克劳德代码。Cursor/Windsurf用户仍然可以手动使用MCP工具。
来源
git clone https://github.com/KlausAndrade/codewatch.git
cd codewatch
npm install
npm run build
claude mcp add codewatch -- node /path/to/dist/index.js
npx codewatch-memory --setup自动挂钩(克劳德码)
最强大的模式——自动保存观察结果 和 自动召回。无需手动调用工具。
添加 .claude/settings.local.json:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "npx codewatch-memory --hook",
"timeout": 30,
"async": true
}
]
}
],
"PreCompact": [
{
"hooks": [
{
"type": "command",
"command": "npx codewatch-memory --hook",
"timeout": 60,
"async": true
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "npx codewatch-memory --recall"
}
]
}
],
"SessionStart": [
{
"matcher": "startup|resume|compact",
"hooks": [
{
"type": "command",
"command": "npx codewatch-memory --recall"
}
]
}
]
}
}运作原理
保存(自动):
Stop每次克劳德回应后都会触发——钩子读取记录,并通过廉价的LLM提取观察结果PreCompact在上下文压缩之前触发——在上下文丢失之前捕获上下文- 观察钩子异步运行,因此它们永远不会阻止Claude
- 重复数据删除可防止对同一消息进行两次处理
- 跳过小转弯(\<50个标记)
召回(自动):
UserPromptSubmit当您键入提示时会触发——关键字将从您的消息中提取出来,并通过FTS5全文搜索与存储的观察结果进行匹配。在Claude处理您的提示之前,相关的观察结果会作为上下文注入。SessionStart在会话开始、恢复或上下文压缩后启动——注入一个简报,其中包含您当前的任务、高优先级的观察结果和最新的反思摘要。- Recall挂钩使用纯数据库查询(无LLM),因此会增加约50ms的延迟。
- 如果没有发现相关观察结果,则不会注入任何东西。
API密钥
观察者/反射者代理至少需要一个LLM API密钥:
# Groq (recommended — fast, free tier available)
export GROQ_API_KEY=your-key
# Google Gemini (cheapest paid option)
export GOOGLE_GENERATIVE_AI_API_KEY=your-key
# OpenAI
export OPENAI_API_KEY=your-keyMCP工具
observe --保存观察结果
content: "Chose repository pattern over active record for User module because team needs to swap DB later"
category?: "architecture" # auto-detected if omitted
priority?: "high" # auto-assigned if omitted
files?: ["src/repositories/UserRepository.ts"]
source_summary?: "user asked to refactor data access"recall --检索相关观察结果
query?: "authentication" # FTS5 full-text search
categories?: ["bugfix", "architecture"]
files?: ["src/auth/middleware.ts"]
priority_min?: "medium" # high, medium, or low
limit?: 50
include_reflections?: true
branch?: "feature/auth" # defaults to current branchreflect --手动压缩触发器
compression_level?: 0 # 0=reorganize, 1=light, 2=aggressive, 3=critical
branch?: "main"get_session_info --会话统计
返回观察计数、令牌使用情况、类别细分、当前任务和压缩历史。
switch_context --更改分支范围
branch: "feature/new-ui" # or "auto" to re-detect from git
carry_task?: true # carry current task description to new branch配置
| 环境变量 | 默认值 | 描述 |
|---|---|---|
CODEWATCH_LLM_PROVIDER | google | 初级法学硕士(谷歌、openai、groq) |
CODEWATCH_FALLBACK_PROVIDER | openai | 后备法学硕士(谷歌、openai、groq,无) |
CODEWATCH_GOOGLE_MODEL | gemini-2.5-flash | 谷歌模式 |
CODEWATCH_OPENAI_MODEL | gpt-4o-mini | OpenAI模型 |
CODEWATCH_GROQ_MODEL | llama-3.3-70b-versatile | Groq模型 |
GROQ_API_KEY | - | Groq API密钥 |
GOOGLE_GENERATIVE_AI_API_KEY | - | Google API密钥 |
OPENAI_API_KEY | - | OpenAI API密钥 |
CODEWATCH_REFLECT_THRESHOLD | 40000 | 自动反映触发器(令牌) |
CODEWATCH_DATA_DIR | ~/mcp-data/codewatch-memory/ | SQLite存储位置 |
CODEWATCH_AUTO_REFLECT | true | 启用自动反射 |
CODEWATCH_MAX_COMPRESSION | 3 | 最大压缩级别(0-3) |
CODEWATCH_LOG_LEVEL | info | 记录冗长 |
选择LLM提供者
Observer和Reflector代理使用廉价/快速的LLM,而不是您的主要编码模型。以下是需要考虑的事项:
| 提供程序 | 成本 | 速度 | 此任务的质量 |
|---|---|---|---|
| 格罗克 (llama-3.3-70b) | 自由层 | 最快 | 良好——很好地处理结构化提取 |
| 谷歌 (双生-2.5-flash) | ~0.001/次通话 | 快速 | 好——最便宜的付费选项 |
| 开放人工智能 (gpt-4o-mini) | ~0.003美元/次 | 中等 | 良好——可靠的回退 |
建议: 使用Groq作为主要(免费、快速),谷歌或OpenAI作为后备。
一个更昂贵的模型(GPT-4o,Claude Sonnet)将为观察者提供边际改进——结构化提取在较小的模型中效果良好。Reflector从模型质量中获益更多,但它很少运行。真正的质量提升来自快速调整,而不是模型升级。
存储
数据存储在 ~/mcp-data/codewatch-memory/codewatch.db (SQLite具有WAL模式)。数据库包括:
- 会话:作用域为git分支+项目目录
- 观察:个人事实/决定,可通过FTS5全文搜索
- 反思:压缩比的压缩观察总结
- 当前任务:坚持“我在做什么”的状态
- 配置:重复数据删除哈希和用户设置
架构亮点
- 观察内容、源代码摘要和引用文件上的FTS5虚拟表——通过INSERT/UPDATE/DELETE触发器保持同步
- 并发读/写的WAL模式(挂钩+MCP服务器可以共存)
- 强制使用外键,64MB缓存,5秒繁忙超时
- Git分支作用域隔离每个功能分支的内存
退化输出检测
Reflector包括3种策略来检测中断的LLM输出(重复/退化文本):
- 精确的重复行 --如果超过30%的行是重复的,则拒绝并升级
- 单词重叠 --如果连续3行共享超过80%的单词,则拒绝并升级
- 子循环重复 --如果任何50-200个字符的子字符串出现3次以上,则拒绝并升级
当检测到退化输出时,Reflector会自动在下一个压缩级别重试。
它与Mastra相比如何
| 功能 | 代码观察记忆 | Mastra观察记忆 |
|---|---|---|
| 协议 | MCP(适用于任何MCP客户端) | Mastra框架 |
| 捕获 | 基于钩子(每个触发器最后20条消息) | 中间件(100%的消息) |
| 分支范围 | 按git分支 | 不知道git |
| 类别 | 8个特定代码类别 | 通用 |
| 存储 | 本地SQLite+FTS5 | 可配置(Postgres等) |
| 压缩 | 4级升级,遵循神圣规则 | 2级代理压缩 |
| 成本 | 免费(Groq)或接近免费 | 取决于供应商 |
| 安装程序 | npx codewatch-memory | 需要Mastra框架 |
权衡: Mastra的中间件方法可以自动捕获100%的消息。codewatch内存的钩子方法捕获每个触发器的最后20条消息——对大多数编码会话有效,但可能会错过长会话早期的观察结果。
发展
npm install
npm run build # Compile TypeScript
npm run dev # Watch mode
npm test # Run tests
npm run test:watch # Watch mode tests项目结构
src/
├── index.ts # Entry point (MCP server, hook, or recall mode)
├── server.ts # MCP tool registration
├── config.ts # Environment config loading
├── hook.ts # Claude Code hook integration (save observations)
├── recall-hook.ts # Claude Code hook integration (auto-recall)
├── transcript.ts # JSONL transcript parser
├── agents/
│ ├── observer.ts # Observer agent (extract observations)
│ ├── reflector.ts # Reflector agent (compress observations)
│ ├── categorizer.ts # Heuristic + LLM categorization
│ └── prompts.ts # All agent prompt templates
├── storage/
│ ├── database.ts # SQLite schema + initialization
│ ├── observations.ts # Observation CRUD + FTS5 queries
│ ├── reflections.ts # Reflection storage
│ ├── sessions.ts # Session management
│ └── queries.ts # Current task queries
├── tools/
│ ├── observe.ts # MCP tool handler
│ ├── recall.ts # MCP tool handler
│ ├── reflect.ts # MCP tool handler
│ ├── get-session-info.ts
│ └── switch-context.ts
├── llm/
│ └── provider.ts # Multi-provider LLM with fallback
├── git/
│ └── branch.ts # Branch detection with 10s cache
└── utils/
├── tokens.ts # Token estimation (chars/4)
├── stdin.ts # Shared stdin reader for hooks
├── sanitize.ts # XML parsing, line truncation
└── repetition.ts # Degenerate output detection许可证
麻省理工学院
