letta-ai/claude-subconscious
GitHub: letta-ai/claude-subconscious
为 Claude Code 添加持久记忆和后台观察能力的插件,让 AI 助手能够跨会话学习和积累上下文。
Stars: 2174 | Forks: 156
# Claude Subconscious
一个向 Claude Code 低语的后台 Agent。一个潜意识的 Agent,它监视你的会话,阅读你的文件,随着时间积累记忆,并将指导低语回馈给你。

## 这是什么?
Claude Code 在会话之间会忘记一切。Claude Subconscious 是一个在底层运行的第二个 Agent —— 观察、学习并低语回馈:
- **观察**每一个 Claude Code 会话记录
- **阅读你的代码库** —— 在处理记录的同时使用 Read、Grep 和 Glob 探索文件
- **记忆**跨越会话、项目和时间的过往
- **低语指导** —— 在每次提示前呈现上下文、模式和提醒
- **从不阻塞** —— 通过 [Letta Code SDK](https://docs.letta.com/letta-code/sdk/) 在后台运行
这不仅仅是一个记忆层 —— 这是一个拥有真实工具访问权限的后台 Agent,你用得越多它就越聪明。
使用 Letta 的 [Conversations](https://docs.letta.com/guides/agents/conversations/) 功能,单个 Agent 可以并行服务于多个 Claude Code 会话,并在所有会话间共享记忆。
## 工作原理
在每次响应之后,记录会通过 Letta Code SDK 发送给 Letta Agent。该 Agent 读取文件、搜索网络、更新它的记忆 —— 然后在下次提示前低语回馈。任何内容都不会写入 CLAUDE.md。
```
┌─────────────┐ ┌──────────────────────────┐
│ Claude Code │◄────────►│ Letta Agent (background) │
└─────────────┘ │ │
│ │ Tools: Read, Grep, Glob │
│ │ Memory: persistent │
│ │ Web: search, fetch │
│ └──────────────────────────┘
│ │
│ Session Start │
├───────────────────────►│ New session notification
│ │
│ Before each prompt │
│◄───────────────────────┤ Whispers guidance → stdout
│ │
│ Before each tool use │
│◄───────────────────────┤ Mid-workflow updates → stdout
│ │
│ After each response │
├───────────────────────►│ Transcript → SDK session (async)
│ │ ↳ Reads files, updates memory
```
## 安装
从 GitHub 安装:
```
/plugin marketplace add letta-ai/claude-subconscious
/plugin install claude-subconscious@claude-subconscious
```
### 更新
```
/plugin marketplace update
/plugin update claude-subconscious@claude-subconscious
```
### 从源码安装
克隆仓库:
```
git clone https://github.com/letta-ai/claude-subconscious.git
cd claude-subconscious
npm install
```
启用插件(在克隆的目录内):
```
/plugin enable .
```
或者为所有项目全局启用:
```
/plugin enable --global .
```
如果从不同目录运行,请使用克隆仓库的完整路径。
### Linux:tmpfs 变通方案
如果插件安装失败并提示 `EXDEV: cross-device link not permitted`,你的 `/tmp` 可能位于不同的文件系统上(在 Ubuntu、Fedora、Arch 上很常见)。设置 `TMPDIR` 以绕过这个 [Claude Code bug](https://github.com/anthropics/claude-code/issues/14799):
```
mkdir -p ~/.claude/tmp
export TMPDIR="$HOME/.claude/tmp"
```
添加到你的 shell 配置文件(`~/.bashrc` 或 `~/.zshrc`)以使其永久生效。
## 配置
### 必需项
```
export LETTA_API_KEY="your-api-key"
```
从 [app.letta.com](https://app.letta.com) 获取你的 API key。
### 可选项
```
export LETTA_MODE="whisper" # Default. Or "full" for blocks + messages, "off" to disable
export LETTA_AGENT_ID="agent-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export LETTA_BASE_URL="http://localhost:8283" # For self-hosted Letta
export LETTA_MODEL="anthropic/claude-sonnet-4-5" # Model override
export LETTA_CONTEXT_WINDOW="1048576" # Context window size (e.g. 1M tokens)
export LETTA_HOME="$HOME" # Consolidate .letta state to ~/.letta/
export LETTA_SDK_TOOLS="read-only" # Or "full", "off"
```
- `LETTA_MODE` - 控制注入内容。`whisper`(默认,仅消息),`full`(块 + 消息),`off`(禁用)。参见 [模式](#modes)。
- `LETTA_AGENT_ID` - 如果未设置,插件会在首次使用时自动导入一个默认的 "Subconscious" Agent。
- `LETTA_BASE_URL` - 用于自托管的 Letta 服务器。默认为 `https://api.letta.com`。
- `LETTA_MODEL` - 覆盖 Agent 的模型。可选 —— 插件会自动检测并从可用模型中选择。参见下方的 [模型配置](#model-configuration)。
- `LETTA_CONTEXT_WINDOW` - 覆盖 Agent 的上下文窗口大小(以 token 为单位)。当 `LETTA_MODEL` 设置为具有大上下文窗口且与服务端默认值不同的模型时很有用。示例:`1048576` 表示 1M tokens。
- `LETTA_HOME` - 插件状态文件的基础目录。创建 `{LETTA_HOME}/.letta/claude/` 用于存放会话数据和对话映射。默认为当前工作目录。设置为 `$HOME` 可将所有状态集中在一个位置。
- `LETTA_SDK_TOOLS` - 控制 Subconscious Agent 的客户端工具访问权限。`read-only`(默认),`full`,或 `off`。参见 [SDK Tools](#sdk-tools)。
### 模式
`LETTA_MODE` 环境变量控制将什么内容注入到 Claude 的上下文中:
| 模式 | Claude 看到的内容 | 用例 |
|------|-----------------|----------|
| **`whisper`**(默认) | 仅来自 Sub 的消息 | 轻量级 —— Sub 只在有事要说时才说话 |
| **`full`** | 记忆块 + 消息 | 完整上下文 —— 第一次提示时注入块,之后为差异 |
| **`off`** | 无 | 临时禁用 hooks |
Subconscious 在任何模式下都**从不写入 CLAUDE.md**。所有内容都通过 stdout 注入到提示上下文中。如果你现有的 CLAUDE.md 中包含来自旧版本的 `` 内容,它将被自动清理。
### Agent 解析顺序
1. **环境变量** - 如果设置了 `LETTA_AGENT_ID`
2. **保存的配置** - 如果存在 `~/.letta/claude-subconscious/config.json`
3. **自动导入** - 导入捆绑的 `Subconscious.af` Agent,保存 ID 以供将来使用
这意味着零配置安装:只需设置 `LETTA_API_KEY`,插件会处理其余部分。
### 多项目使用
**一个 Agent,多个项目。** Subconscious Agent 全局存储在 `~/.letta/claude-subconscious/config.json`。当你在不同的仓库中使用该插件时,它们都共享同一个 Agent 大脑。
```
~/.letta/claude-subconscious/config.json → ONE agent ID (shared brain)
↓
project-a/.letta/claude/ → Project A's conversation threads
project-b/.letta/claude/ → Project B's conversation threads
project-c/.letta/claude/ → Project C's conversation threads
```
每个项目中的 `.letta/claude/` 目录是**对话簿记**(将 Claude Code 会话映射到 Letta 对话),而不是独立的 Agent。记忆块在所有项目间共享。
要**为每个项目使用不同的 Agent**,请在 shell 中设置 `LETTA_AGENT_ID` 或通过 [direnv](https://direnv.net/) 设置:
```
# 项目目录中的 .envrc
export LETTA_AGENT_ID="agent-xxx-for-this-project"
```
### 模型配置
插件会**自动检测你的 Letta 服务器上的可用模型**并适当地配置 Agent:
1. **查询可用模型**从你的 Letta 服务器(`GET /v1/models/`)
2. **检查 Agent 的模型是否可用**于该服务器
3. **自动选择回退方案**如果当前模型不可用
#### 自动选择优先级
当 Agent 的模型不可用时,插件按以下顺序从可用模型中选择:
1. `anthropic/claude-sonnet-4-5`(推荐 —— 最适合 Agent)
2. `openai/gpt-4.1-mini`(良好的平衡,1M 上下文,便宜)
3. `anthropic/claude-haiku-4-5`(快速的 Claude 选项)
4. `openai/gpt-5.2`(旗舰级回退)
5. `google_ai/gemini-3-flash`(Google 的平衡选项)
6. `google_ai/gemini-2.5-flash`(回退)
7. 服务器上第一个可用的模型
#### 手动覆盖
要指定特定模型,设置 `LETTA_MODEL`:
```
export LETTA_MODEL="anthropic/claude-sonnet-4-5"
```
模型句柄格式为 `provider/model`。常见选项:
| 提供商 | 示例模型 |
|----------|----------------|
| `openai` | `gpt-5.2`, `gpt-5-nano`, `gpt-4.1-mini` |
| `anthropic` | `claude-sonnet-4-5`, `claude-opus-4-5`, `claude-haiku-4-5` |
| `google_ai` | `gemini-3-flash`, `gemini-2.5-flash`, `gemini-2.5-pro` |
| `zai` | `glm-5`(Letta Cloud 默认,免费)|
如果设置了 `LETTA_MODEL` 但在服务器上不可用,插件会警告你并回退到自动选择。
默认捆绑的 Agent 使用 `zai/glm-5`(在 Letta Cloud 上免费)。为了获得更好的工具使用和推理能力,请考虑切换到更强的模型。你可以随时通过 [Agent Development Environment](https://app.letta.com)(ADE)或通过设置 `LETTA_MODEL` 来更改模型。
**注意:** 确保你的 Letta 服务器已为你选择的提供商配置了相应的 API key(例如,OpenAI 模型需要 `OPENAI_API_KEY`)。
## 默认 Subconscious Agent
当没有配置 Agent 时,插件会自动导入一个专门为此用例设计的捆绑 "Subconscious" Agent。
### 它的功能
默认 Agent 是一个后台 Agent,它:
- **读取你的代码** —— 使用 Read、Grep 和 Glob 在处理记录的同时探索你的代码库
- **学习你的偏好** —— 从修正、明确陈述和模式中学习
- **追踪项目上下文** —— 架构决策、已知的陷阱、待处理项
- **提供指导** —— 当有有用的信息时通过 `` 块提供
- **搜索网络** —— 可以查找内容以增强其上下文
### 记忆块
默认 Agent Subconscious 维护 8 个记忆块:
| 块 | 用途 |
|-------|---------|
| `core_directives` | 角色定义和行为准则 |
| `guidance` | 下一次会话的主动指导(在每次提示前同步到 Claude Code)|
| `user_preferences` | 学习到的编码风格、工具偏好、沟通风格 |
| `project_context` | 代码库知识、架构决策、已知的陷阱 |
| `session_patterns` | 反复出现的行为、基于时间的模式、常见的困难 |
| `pending_items` | 未完成的工作、明确的 TODO、后续事项 |
| `self_improvement` | 随时间推移演进记忆架构的准则 |
| `tool_guidelines` | 如何使用可用工具(记忆、文件系统、网络搜索)|
如果你使用 `LETTA_AGENT_ID` 设置了替代 Agent,你的 Agent 将使用其现有的记忆架构。
### 沟通风格
Subconscious 被配置为:
- **观察性的** - "我注意到..." 而不是 "你应该..."
- **简洁的** - 技术性,无废话
- **存在但不突兀** - 空的指导是可以的;它不会捏造内容
### 双向沟通
Claude Code 可以在响应中直接与 Subconscious Agent 对话。Agent 可以看到记录中的所有内容,并可能在下次同步时响应。它旨在进行持续的对话,而不仅仅是单向观察。
## Hooks
插件使用四个 Claude Code hooks:
| Hook | 脚本 | 超时 | 目的 |
|------|--------|---------|---------|
| `SessionStart` | `session_start.ts` | 5s | 通知 Agent,清理旧的 CLAUDE.md |
| `UserPromptSubmit` | `sync_letta_memory.ts` | 10s | 通过 stdout 注入记忆 + 消息 |
| `PreToolUse` | `pretool_sync.ts` | 5s | 通过 `additionalContext` 进行工作流中间更新 |
| `Stop` | `send_messages_to_letta.ts` | 120s | 生成 SDK worker 发送记录(异步)|
### SessionStart
当新的 Claude Code 会话开始时:
- 创建一个新的 Letta 对话(或为该会话复用现有的)
- 发送带有项目路径和时间戳的会话开始通知
- 清理 CLAUDE.md 中任何旧的 `` 内容
- 保存会话状态供其他 hooks 引用
### UserPromptSubmit
在处理每个提示之前:
- 获取 Agent 当前的记忆块和消息
- 在 `full` 模式下:在第一次提示时注入所有块,在后续提示时注入差异
- 在 `whisper` 模式下:仅注入来自 Sub 的消息
### PreToolUse
在每次工具使用之前:
- 检查自上次同步以来是否有新消息或记忆变化
- 如果发现更新,通过 `additionalContext` 注入它们
- 如果没有任何变化则静默无操作
### SDK Tools
默认情况下,Subconscious Agent 现在通过 [Letta Code SDK](https://docs.letta.com/letta-code/sdk/) 获得**客户端工具访问权限**。Sub 不再局限于记忆操作,可以在处理记录的同时读取你的文件、搜索网络并探索你的代码库。
**通过 `LETTA_SDK_TOOLS` 配置:**
| 模式 | 可用工具 | 用例 |
|------|----------------|----------|
| `read-only`(默认)| `Read`, `Grep`, `Glob`, `web_search`, `fetch_webpage` | 安全的后台研究和文件读取 |
| `full` | 所有工具(Bash, Edit, Write, Task 等)| 完全自主 —— Sub 可以进行更改并生成子 Agent |
| `off` | 无(仅记忆)| 仅监听 —— Sub 处理记录但没有客户端工具 |
在 `full` 模式下,Sub 可以通过 `Task` 工具生成子 Agent —— 在 Claude Code 继续工作的同时派遣并行研究或将工作委托给其他 Agent。
### Stop
使用**异步 hook** 模式 —— 在后台运行而不阻塞 Claude Code:
1. 主 hook(`send_messages_to_letta.ts`)快速运行:
- 解析会话记录(JSONL 格式)
- 提取用户消息、助手响应、思考块和工具使用
- 将负载写入临时文件
- 生成分离的后台 worker
- 立即退出
2. 后台 worker(`send_worker_sdk.ts`)独立运行:
- 打开 Letta Code SDK 会话为 Sub 提供客户端工具
- Sub 处理记录并可以使用 Read/Grep/Glob 探索代码库
- 成功时更新状态
- 清理临时文件
Stop hook 作为异步 hook 运行,因此它从不阻塞 Claude Code。
## 状态管理
插件在两个位置存储状态:
### 持久状态(`.letta/claude/`)
保存在你的项目目录中(这是**对话簿记**,不是独立的 Agent —— 参见 [多项目使用](#multi-project-usage)):
- `conversations.json` - 将 Claude Code 会话 ID 映射到 Letta 对话 ID
- `session-{id}.json` - 每会话状态(最后处理的索引、缓存的对话 ID)
### 临时状态(`$TMPDIR/letta-claude-sync-$UID/`)
用于调试的日志文件:
- `session_start.log` - 会话初始化
- `sync_letta_memory.log` - 记忆同步操作
- `send_messages.log` - 主 Stop hook
- `send_worker_sdk.log` - SDK 后台 worker
## 你的 Agent 接收什么
### 会话开始消息
```
[Session Start]
Project: my-project
Path: /Users/you/code/my-project
Session: abc123
Started: 2026-01-14T12:00:00Z
A new Claude Code session has begun. I'll be sending you updates as the session progresses.
```
### 对话记录
完整的记录包含:
- 用户消息
- 助手响应(包括思考块)
- 工具使用和结果
- 时间戳
## Claude 看到什么
所有内容都通过 stdout 注入 —— 没有任何内容写入磁盘。Claude 接收的内容取决于模式。
### 消息(whisper + full 模式)
来自你的 Subconscious Agent 的消息在每次提示前注入:
```
You've asked about error handling in async contexts three times this week.
Consider reviewing error handling architecture holistically.
```
### 记忆块(仅限 full 模式)
在会话的第一次提示时,所有记忆块被注入:
```
Subconscious agent "herald" is observing this session.
Supervise: https://app.letta.com/agents/agent-xxx?conversation=conv-xxx
Prefers explicit type annotations. Uses pnpm, not npm.
Working on claude-subconscious plugin. TypeScript, ESM modules.
```
在后续提示中,只有变化的块显示为差异:
```
- Phase 1 test harness complete
+ Release prep complete: README fixed, .gitignore updated
```
## 首次运行
首次使用时,Agent 以最少的上下文开始。它需要几次会话才能有足够的信号提供有用的指导。给它时间 —— 它会读取你的代码,学习你的模式,观察得越多就越聪明。
## 使用案例
- **持久的项目上下文** —— Agent 读取你的代码库并跨会话记忆
- **学习的偏好** —— "这个用户总是想要显式的类型注解"
- **跨会话连续性** —— 从你停下的地方继续,带有完整的上下文
- **后台研究** —— Agent 可以在你工作时搜索网络和读取文件
- **模式检测** —— "你已经调试 auth 2 小时了,也许退后一步?"
- **主动的代码库感知** —— Agent 在看到你处理某个功能时探索相关文件
## 调试
如果 hooks 不工作,请检查日志文件。日志目录是用户特定的(`$TMPDIR/letta-claude-sync-$UID/`):
```
# 查看所有日志 (macOS/Linux)
tail -f /tmp/letta-claude-sync-$(id -u)/*.log
# 或特定日志
tail -f /tmp/letta-claude-sync-$(id -u)/send_messages.log
tail -f /tmp/letta-claude-sync-$(id -u)/send_worker_sdk.log
```
## API 说明
- 记忆同步需要 `?include=agent.blocks` 查询参数(Letta API 默认不包含关系字段)
- 所有记录传递使用 [Letta Code SDK](https://docs.letta.com/letta-code/sdk/) —— 没有用于消息发送的原始 API 调用
- SDK worker 在更新状态之前会流式传输 Agent 的完整响应
## 许可证
MIT
标签:Claude, Claude Code, CVE检测, DLL 劫持, Letta, LLM, MITM代理, RAG, Subconscious, Unmanaged PE, 上下文管理, 人工智能, 代码库分析, 会话持久化, 后台代理, 大语言模型, 威胁情报, 并行处理, 开发者工具, 提示词工程, 智能编程助手, 检索增强生成, 用户模式Hook绕过, 策略决策点, 网络调试, 自动化, 自动化攻击, 记忆系统, 长期记忆