构建AI工作记忆系统:从向量数据库到智能编码助手的工程实践

📅 2026/8/2 10:26:35
构建AI工作记忆系统:从向量数据库到智能编码助手的工程实践
在实际 AI 应用开发中一个常见的痛点在于我们与 AI 工具如 Claude、GPT 等的每一次交互都是孤立的。你向它描述项目背景它给出建议你让它分析代码它提供优化方案。但下一次对话时它又回到了“白板”状态你需要重新解释上下文、项目结构、历史决策和你的个人偏好。这种重复劳动不仅低效也阻碍了 AI 成为真正理解你工作习惯的长期伙伴。Remio 正是为了解决这一问题而生的概念。它不是一个具体的、已发布的单一产品而是一种理念或一类工具的代表为 AI 工具打造持续积累的“个人工作记忆”。其核心思想是构建一个持久化的、结构化的上下文存储系统让 AI 能够记住跨会话、跨项目的关键信息从而实现更连贯、更个性化、更高效的辅助。本文将深入探讨 Remio 这一概念的技术实现路径涵盖其核心机制、环境搭建、与主流 AI 开发工具如 Claude Code、Codex的集成、实战应用以及关键的工程化考量。本文适合希望将 AI 深度集成到个人或团队工作流中的开发者、技术负责人以及对 AI Agent 架构感兴趣的工程师。我们将从零开始构建一个简化但完整的“工作记忆”系统原型并解释其与现有 AI 工具链的对接方式。1. 理解“工作记忆”从临时对话到持久化智能体在深入代码之前必须厘清“工作记忆”与普通聊天记录或项目文档的本质区别。1.1 什么是 AI 的工作记忆你可以将 AI 的工作记忆理解为一个专为 AI 交互设计的、高度结构化的知识库。它不仅仅是聊天历史的罗列而是经过提取、分类和索引的上下文信息。这些信息可能包括项目元数据项目名称、技术栈如 Spring Boot 3.2, Python 3.11、核心依赖版本、代码仓库地址。架构决策与约束例如“本项目禁止使用Thread.sleep必须采用响应式编程”、“数据库访问层统一使用 MyBatis-Plus”、“API 响应格式遵循{code, data, message}规范”。关键代码片段与模式频繁使用的工具类、自定义注解、异常处理模板、领域模型的核心关系。历史对话摘要过去关于某个模块如用户认证的讨论结论、已尝试但被否决的方案及其原因。个人/团队偏好代码风格缩进、命名、提交信息规范、常用的调试命令、部署流程。当 AI 处理新的请求时它可以主动从这个记忆库中检索相关上下文并作为系统提示System Prompt的一部分注入从而使其回答更具针对性和一致性。1.2 工作记忆 vs. 传统上下文窗口大型语言模型LLM本身有固定的上下文窗口如 128K tokens。直接将所有历史对话塞进上下文窗口是不可行的会导致成本高昂更长的上下文意味着更高的 API 调用费用和计算开销。信息过载无关的历史信息会干扰模型对当前问题的专注度。效率低下每次都需要传输大量重复数据。工作记忆系统的优势在于按需检索。它只将当前任务最相关的记忆片段提供给 AI实现了在超大“潜在”上下文下的高效聚焦。1.3 核心组件与工作流程一个典型的 Remio 式工作记忆系统包含以下组件记忆存储器持久化存储结构化记忆的地方可以是向量数据库如 Chroma, Pinecone、关系型数据库或文件系统。记忆提取器负责从对话、代码、文档中自动或半自动地提取关键信息并将其转化为结构化的记忆单元。记忆索引器为记忆单元创建索引如向量嵌入以便进行相似性检索。记忆检索器根据当前用户查询或任务从记忆库中查找最相关的记忆片段。上下文组装器将检索到的记忆、当前查询以及可能的其他指令组装成最终的提示Prompt发送给 AI 模型。其工作流程如下图所示概念性描述用户提问/任务 - 记忆检索器 - [从记忆库获取相关记忆] - 上下文组装器 - [构建增强提示] - AI 模型 - 生成回答 ^ | [记忆提取器] - 更新记忆库 ^ | 用户对话/代码变更2. 环境准备与核心依赖选择我们将使用 Python 作为原型开发语言因为它拥有最丰富的 AI 开发生态。这个示例将展示如何构建一个能与 Claude API 或 OpenAI API 协同工作的基础记忆系统。2.1 基础环境与 Python 包首先确保你的 Python 环境版本在 3.8 以上。然后安装核心依赖。# 创建并激活虚拟环境推荐 python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows # 安装核心依赖 pip install openai1.12.0 # 用于调用 OpenAI/Claude 兼容的 API pip install chromadb0.4.22 # 轻量级向量数据库用于存储和检索记忆 pip install langchain0.1.0 # 提供丰富的工具链简化 AI 应用开发可选但推荐 pip install python-dotenv1.0.0 # 管理环境变量 pip install tiktoken0.6.0 # 用于精确计算 token 数量注意版本号是撰写本文时的稳定版本。实际项目中应检查各库的最新版本和兼容性。langchain是一个强大的框架但为了理解底层原理我们初期会部分直接使用底层库。2.2 获取 AI 模型 API 密钥本示例需要接入一个大型语言模型。你可以选择OpenAI GPT访问 platform.openai.com 获取 API Key。Anthropic Claude访问 console.anthropic.com 获取 API Key。其他兼容 OpenAI API 的模型如 DeepSeek、Ollama 本地模型等需对应配置其 Base URL。将密钥保存在项目根目录的.env文件中切勿提交到代码仓库。# .env 文件内容示例 OPENAI_API_KEYsk-your-openai-key-here # 或者使用 Claude ANTHROPIC_API_KEYsk-ant-your-claude-key-here # 如果使用 DeepSeek 等兼容服务 DEEPSEEK_API_KEYyour-deepseek-key DEEPSEEK_API_BASEhttps://api.deepseek.com2.3 项目结构规划创建一个清晰的项目结构有助于管理复杂度。remio_agent_project/ ├── .env # 环境变量在.gitignore中 ├── requirements.txt # 依赖列表 ├── src/ │ ├── __init__.py │ ├── memory/ # 记忆系统核心模块 │ │ ├── __init__.py │ │ ├── storage.py # 记忆存储与检索 │ │ ├── extractor.py # 记忆提取逻辑 │ │ └── types.py # 数据类型定义如 MemoryItem │ ├── agents/ # AI 代理模块 │ │ ├── __init__.py │ │ └── coding_agent.py # 编码专用代理 │ ├── utils/ │ │ ├── __init__.py │ │ └── token_counter.py # Token 计算工具 │ └── main.py # 主程序入口 └── tests/ # 单元测试3. 构建核心记忆系统我们从定义记忆的数据结构开始然后实现存储和检索功能。3.1 定义记忆单元在src/memory/types.py中我们定义一个标准的记忆单元。from datetime import datetime from typing import Optional, Dict, Any from pydantic import BaseModel, Field class MemoryItem(BaseModel): 表示一条工作记忆的基本单元。 id: str Field(default_factorylambda: str(uuid.uuid4())) content: str # 记忆的文本内容如“项目使用Spring Boot 3.2.0” embedding: Optional[List[float]] None # 文本的向量表示 metadata: Dict[str, Any] Field(default_factorydict) # 附加信息 # 元数据示例 # - source: “conversation”, “code_file”, “document” # - project: “my-web-app” # - topic: “architecture”, “dependency”, “api_spec” # - timestamp: 创建时间 # - importance: 0.0 to 1.0 created_at: datetime Field(default_factorydatetime.now) last_accessed_at: Optional[datetime] None def to_dict(self) - Dict[str, Any]: 转换为字典便于存储。 return { id: self.id, content: self.content, metadata: self.metadata, created_at: self.created_at.isoformat(), last_accessed_at: self.last_accessed_at.isoformat() if self.last_accessed_at else None }3.2 实现向量存储与检索我们使用 ChromaDB 作为向量数据库。在src/memory/storage.py中实现记忆的增删改查。import chromadb from chromadb.config import Settings from typing import List, Optional import uuid from .types import MemoryItem class VectorMemoryStore: 基于向量数据库的记忆存储管理器。 def __init__(self, persist_directory: str ./chroma_db): # 初始化客户端设置持久化路径 self.client chromadb.PersistentClient( pathpersist_directory, settingsSettings(anonymized_telemetryFalse) ) # 获取或创建一个集合类似于数据库的表 self.collection self.client.get_or_create_collection( namework_memories, metadata{description: 存储AI代理的工作记忆} ) def add_memory(self, memory: MemoryItem, embedding: List[float]): 添加一条记忆及其向量嵌入。 memory.embedding embedding # ChromaDB 需要以列表形式添加 self.collection.add( documents[memory.content], metadatas[memory.metadata], embeddings[embedding], ids[memory.id] ) def search_similar(self, query_embedding: List[float], n_results: int 5, filter_metadata: Optional[dict] None) - List[MemoryItem]: 根据查询向量搜索最相似的记忆。 results self.collection.query( query_embeddings[query_embedding], n_resultsn_results, wherefilter_metadata # 可选的元数据过滤如 {project: my-web-app} ) memories [] # results 是一个字典包含 ids, documents, metadatas, distances if results[ids][0]: # 确保有结果 for i in range(len(results[ids][0])): mem MemoryItem( idresults[ids][0][i], contentresults[documents][0][i], metadataresults[metadatas][0][i], # 注意ChromaDB 返回的元数据中的时间可能是字符串需要转换 ) memories.append(mem) return memories def delete_memory(self, memory_id: str): 根据ID删除记忆。 self.collection.delete(ids[memory_id])3.3 集成文本嵌入模型为了进行相似性搜索我们需要将文本转换为向量嵌入。这里我们使用 OpenAI 的text-embedding-3-small模型它性价比高且效果不错。# src/memory/embedder.py from openai import OpenAI import os from dotenv import load_dotenv from typing import List load_dotenv() class EmbeddingGenerator: 文本嵌入生成器。 def __init__(self, model: str text-embedding-3-small): self.client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) self.model model def generate_embedding(self, text: str) - List[float]: 为单条文本生成嵌入向量。 response self.client.embeddings.create( modelself.model, inputtext, encoding_formatfloat # 确保返回浮点数列表 ) return response.data[0].embedding def generate_embeddings_batch(self, texts: List[str]) - List[List[float]]: 为一批文本生成嵌入向量更高效。 response self.client.embeddings.create( modelself.model, inputtexts, encoding_formatfloat ) return [item.embedding for item in response.data]4. 创建具备记忆的 AI 编码代理现在我们将记忆系统与 AI 模型结合起来创建一个有“记忆”的编码助手代理。4.1 代理的核心逻辑在src/agents/coding_agent.py中我们构建代理。它会在回答用户问题前先检索相关记忆。import os from openai import OpenAI from typing import List, Optional from dotenv import load_dotenv from ..memory.storage import VectorMemoryStore from ..memory.embedder import EmbeddingGenerator from ..memory.types import MemoryItem from ..utils.token_counter import count_tokens # 假设有一个token计数工具 load_dotenv() class CodingAgentWithMemory: 具备工作记忆的编码助手代理。 def __init__(self, model: str gpt-4-turbo-preview): self.model model # 初始化 OpenAI 客户端也可替换为 Claude 客户端 self.llm_client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) self.memory_store VectorMemoryStore() self.embedder EmbeddingGenerator() def _retrieve_relevant_memories(self, query: str, project_filter: Optional[str] None) - List[MemoryItem]: 根据查询检索相关记忆。 query_embedding self.embedder.generate_embedding(query) filter_metadata {project: project_filter} if project_filter else None relevant_mems self.memory_store.search_similar( query_embeddingquery_embedding, n_results3, # 检索前3条最相关的记忆 filter_metadatafilter_metadata ) return relevant_mems def _build_context_prompt(self, query: str, memories: List[MemoryItem]) - str: 构建包含记忆上下文的系统提示。 memory_context if memories: memory_context 以下是你之前了解过的关于当前项目/任务的信息请在处理当前请求时参考\n for i, mem in enumerate(memories, 1): memory_context f{i}. {mem.content}\n memory_context \n system_prompt f你是一个专业的软件开发助手拥有关于当前项目的持续记忆。 {memory_context} 请基于以上已知信息如果有回答用户关于编码、设计或调试的问题。 如果用户的问题与已知信息冲突以用户的最新输入为准。 请用清晰、专业的方式回答如果是代码请给出完整、可运行的示例。 return system_prompt def ask(self, query: str, project_context: Optional[str] None) - str: 向代理提问它会自动检索记忆并生成回答。 # 1. 检索相关记忆 relevant_memories self._retrieve_relevant_memories(query, project_context) # 2. 构建提示 system_prompt self._build_context_prompt(query, relevant_memories) # 3. 调用 LLM try: response self.llm_client.chat.completions.create( modelself.model, messages[ {role: system, content: system_prompt}, {role: user, content: query} ], temperature0.2, # 较低的温度使输出更稳定适合编码任务 max_tokens2000 ) answer response.choices[0].message.content # 4. 可选将本次交互的重要信息提取为新的记忆 self._maybe_create_memory(query, answer, project_context) return answer except Exception as e: return f调用模型时出错{e} def _maybe_create_memory(self, query: str, answer: str, project: Optional[str]): 一个简单的记忆提取策略如果回答中包含‘记住’或用户明确要求则创建记忆。 # 这是一个非常简单的示例。实际应用中你需要更复杂的逻辑来判断何时以及如何提取记忆。 # 例如可以使用另一个 LLM 来总结对话要点。 if project and (记住 in query or note in query.lower()): summary f用户要求记住{query[:100]}... # 简单截取 new_memory MemoryItem( contentsummary, metadata{source: conversation, project: project, topic: user_directive} ) embedding self.embedder.generate_embedding(summary) self.memory_store.add_memory(new_memory, embedding) print(f[记忆系统] 已创建新记忆{summary})4.2 运行一个完整示例创建一个主程序src/main.py来演示整个流程。from agents.coding_agent import CodingAgentWithMemory from memory.extractor import CodeExtractor # 假设我们有一个从代码中提取记忆的类 import os def main(): # 初始化代理 agent CodingAgentWithMemory(modelgpt-4-turbo-preview) # 模拟初始化项目记忆手动添加一些项目约束 print( 初始化项目记忆 ) initial_memories [ 本项目是一个使用 Spring Boot 3.2.0 和 Java 17 的微服务。, 数据库使用 PostgreSQL 15ORM 框架是 MyBatis-Plus。, API 统一返回格式为{code: 200, data: {}, message: success}。, 项目禁止在业务逻辑层直接使用 System.out.println必须使用 SLF4J 日志。, 用户认证采用 JWT 令牌令牌有效期为 2 小时。 ] # 这里需要调用一个方法来批量添加记忆我们简化处理假设已添加。 # 开始对话 print(\n 开始与有记忆的代理对话 ) project my-springboot-app # 第一轮提问 question1 帮我写一个用户登录的 Controller 方法接收用户名和密码。 print(f用户: {question1}) answer1 agent.ask(question1, project_contextproject) print(f代理: {answer1[:200]}...) # 打印前200字符 # 第二轮提问依赖之前的记忆 question2 好的那在刚才的登录方法里返回格式要符合我们项目的规范具体该怎么写 print(f\n用户: {question2}) answer2 agent.ask(question2, project_contextproject) print(f代理: {answer2[:300]}...) # 第三轮提问测试记忆检索 question3 我们项目用的是什么数据库和ORM print(f\n用户: {question3}) answer3 agent.ask(question3, project_contextproject) print(f代理: {answer3}) if __name__ __main__: main()运行这个程序你会看到代理在回答第二个和第三个问题时能够“回忆”起之前设定的项目规范API返回格式、数据库等从而给出更准确的答案。5. 与现有开发工具链集成Remio 的理念需要融入现有工作流才能发挥最大价值。以下是几个关键集成点。5.1 集成 Claude Code / VS Code 插件像 Claude Code 这样的 IDE 插件其核心是通过 API 与后台 AI 服务通信。我们可以通过中间代理或修改其配置的方式为其注入记忆上下文。思路开发一个本地的代理服务器作为 Claude Code 插件和 AI 模型 API 之间的桥梁。这个代理服务器负责拦截插件发出的请求。根据当前打开的项目、文件路径从记忆库中检索相关上下文。将检索到的记忆作为系统提示的一部分附加到原始请求中。将增强后的请求转发给真正的 AI API如 Anthropic 或 OpenAI。将响应返回给插件。简化配置示例修改 Claude Code 的 API 端点 假设你本地代理服务器运行在http://localhost:8000/v1/chat/completions并兼容 OpenAI API 格式。你可以在 Claude Code 设置中将 API Base URL 指向你的代理。# 本地代理服务器的简化配置示例 (使用 FastAPI) from fastapi import FastAPI, Request from typing import Dict, Any import httpx import os from .memory_integration import retrieve_context_for_project # 你的记忆检索函数 app FastAPI() OPENAI_BASE_URL https://api.openai.com/v1 app.post(/v1/chat/completions) async def proxy_chat_completions(request: Request): client httpx.AsyncClient() # 1. 获取原始请求体 body: Dict[str, Any] await request.json() messages body.get(messages, []) # 2. 从请求头或消息中提取项目上下文例如从自定义Header或第一个消息的元数据 project_context request.headers.get(X-Project-Context, default) # 3. 检索相关记忆 relevant_context retrieve_context_for_project(project_context) if relevant_context: # 4. 构建增强的系统提示 enhanced_system_prompt f{relevant_context}\n\n你是一个专业的编码助手。 # 确保系统提示存在并放在消息列表首位 if messages and messages[0][role] system: messages[0][content] enhanced_system_prompt \n messages[0][content] else: messages.insert(0, {role: system, content: enhanced_system_prompt}) # 5. 转发到真实API headers { Authorization: fBearer {os.getenv(OPENAI_API_KEY)}, Content-Type: application/json } body[messages] messages resp await client.post(f{OPENAI_BASE_URL}/chat/completions, jsonbody, headersheaders) return resp.json()5.2 集成 Codex 或类似代码补全工具对于 GitHub Copilot基于 Codex这类代码补全工具其上下文主要来自当前文件及相邻文件。集成工作记忆更具挑战性但可以通过以下方式增强项目级自定义提示某些工具允许设置项目级或文件夹级的自定义提示。你可以将最重要的项目记忆如架构规范、常用模式写成一个提示文件如.copilot/instructions.mdCopilot 会参考这些内容。开发专用插件为 IDE 开发一个插件监听代码编辑事件。当用户编写特定注释如// mem: 查询用户服务时插件自动从记忆库中检索关于“用户服务”的接口定义、数据结构等信息并以代码片段或注释的形式插入到编辑器中。5.3 自动化记忆提取手动添加记忆不可持续。需要自动化从日常工作中提取记忆。从 Git 提交信息中提取分析 Commit Message提取功能点、修复的问题、技术决策。从代码变更中提取使用 AST抽象语法树分析新增的类、方法、注解总结出新的模式或约束。从对话日志中提取使用一个轻量级 LLM 对 AI 对话历史进行总结提炼出决策点和关键信息。从文档中提取解析 README、设计文档提取项目目标和架构。# src/memory/extractor.py 示例简单的提交信息分析器 import subprocess import re class GitCommitExtractor: def extract_from_repo(self, repo_path: str, limit50): 从Git仓库提取最近的提交信息作为潜在记忆。 cmd [git, -C, repo_path, log, f--oneline, f-{limit}] result subprocess.run(cmd, capture_outputTrue, textTrue) commits result.stdout.strip().split(\n) memories [] for commit in commits: if commit: # 简单清洗实际应用可能需要更复杂的NLP处理 cleaned re.sub(r^[a-f0-9]{7,} , , commit) # 移除commit hash memories.append({ content: fGit提交: {cleaned}, metadata: {source: git_commit, project: repo_path} }) return memories6. 生产环境考量与最佳实践将个人工作记忆系统用于生产或团队协作需要解决更多工程问题。6.1 记忆的隐私、安全与权限敏感信息过滤记忆提取管道必须过滤掉密码、密钥、个人身份信息等敏感数据。可以在提取前使用正则表达式或专用模型进行扫描和脱敏。访问控制在团队场景中记忆需要权限分级。例如项目公共记忆对所有成员可见个人记忆仅自己可见。这需要在存储层实现基于用户/角色的访问控制列表。数据加密存储在向量数据库或磁盘上的记忆内容应进行加密尤其是使用第三方向量数据库服务时。6.2 记忆的质量与维护去重与合并避免存储大量重复或高度相似的记忆。在添加新记忆前可以进行相似度检索如果存在高度相似的旧记忆则选择更新或合并而非新增。记忆衰减与清理并非所有记忆都永久有效。可以为记忆设置“重要性”分数和“最后访问时间”。定期清理长时间未访问且重要性低的记忆或将其归档到“长期记忆”如传统数据库中。人工审核与修正提供界面让用户查看、编辑、删除或确认自动提取的记忆确保记忆库的准确性。6.3 性能优化嵌入模型选择对于文本检索text-embedding-3-small在速度和成本上是不错的选择。如果对精度要求极高可考虑text-embedding-3-large或开源模型如BGE-M3。向量索引优化ChromaDB 默认使用 HNSW 索引对于百万级以下的记忆条目性能足够。如果数据量极大需要考虑分片、分区或使用更专业的向量数据库如 Weaviate, Qdrant。缓存策略对于高频检索的记忆如项目核心规范可以缓存在内存中避免每次请求都查询向量数据库。6.4 常见问题排查在开发和运行过程中你可能会遇到以下问题问题现象可能原因检查与解决思路代理回答似乎没有用到记忆1. 记忆检索相关度阈值太高未返回结果。2. 系统提示构建错误记忆未被正确注入。3. 向量数据库连接或查询失败。1. 检查search_similar返回的记忆列表是否为空可临时降低n_results或调整过滤条件。2. 打印出最终发送给 LLM 的完整系统提示确认记忆文本是否在其中。3. 检查 ChromaDB 持久化目录权限查看是否有错误日志。添加记忆失败1. 嵌入模型 API 调用失败配额、网络。2. 向量数据库写入错误。1. 检查 API 密钥和环境变量确认嵌入模型服务可用。2. 检查 ChromaDB 集合名称是否正确磁盘空间是否充足。检索速度慢1. 记忆条目过多。2. 每次请求都重新生成查询嵌入。1. 考虑对记忆进行分区按项目减少单次检索范围。2. 对常见的查询模板或项目上下文可以预计算并缓存其嵌入向量。记忆内容混乱或无关1. 记忆提取逻辑过于粗糙抓取了无关信息。2. 没有进行记忆去重。1. 优化提取器使用更精准的规则或让小模型进行摘要总结。2. 实现去重逻辑在添加前检查相似度。7. 扩展方向与未来展望基于这个原型你可以向多个方向扩展打造更强大的个人或团队 AI 工作伴侣多模态记忆不仅存储文本还能存储图表截图、UI 设计稿的链接、音频会议纪要的关键点并能进行跨模态检索例如根据文字描述找到相关图表。主动记忆与提醒系统可以主动学习你的工作模式。例如当你多次修改同一个文件时它可能提示“检测到您频繁修改UserService.java这是上周讨论过的核心服务相关设计决策有...”。记忆图谱将记忆单元通过关系连接起来形成知识图谱。例如“登录接口”记忆关联到“JWT 工具类”记忆和“用户表结构”记忆实现更复杂的推理。团队共享记忆在团队版中成员可以贡献、订阅、投票确认记忆形成团队的集体智慧库加速新成员 onboarding 和统一技术规范。构建持续积累的工作记忆系统是将 AI 从“一次性的聪明工具”转变为“长期合作的智能伙伴”的关键一步。虽然完全自动化的、高度智能的 Remio 仍需技术发展但通过本文介绍的方法你现在就可以开始构建一个能够显著提升开发效率的原型系统。从为一个具体项目建立关键约束的记忆开始逐步迭代你会发现 AI 助手变得越来越懂你和你的项目。