news 2026/9/6 20:20:49

AI编程本地持久记忆:无需Embeddings的轻量方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI编程本地持久记忆:无需Embeddings的轻量方案

平时用 AI Coding 工具写代码,最让人烦躁的往往不是模型能力不够,而是“它又忘了”。改完一个文件,重新开一轮对话,还要把项目背景、技术栈、刚才改到哪一步重新讲一遍。如果正在用多 Agent 协作的 AI 编程工作流,问题更明显:每个 Agent 各干各的,上下文互相不通,A Agent 刚确认过的技术方案,B Agent 又按自己的理解写了一遍,甚至把已经否决的方案重新实现出来。

最近在 Hacker News 上看到一个名为Llmem的项目,标题很直接:“Show HN: Llmem – Local persistent memory for AI coding, no embeddings”。核心卖点就三个词:本地、持久、不使用 embeddings。这篇文章不打算只做项目介绍,而是围绕“AI 编程的本地持久记忆”这个方向做一次系统拆解,包括它要解决什么问题、no-embeddings 方案为什么值得关注、以及一套不依赖向量库的参考实现,方便你理解这类工具的设计思路,也方便你在自己的 AI 编程工作流里动手试试。

阅读本文你会掌握:

  • AI Coding Agent 为什么需要“记忆”,它和上下文窗口有什么区别;
  • 带 embeddings 的记忆方案与不带 embeddings 的方案,各自的取舍是什么;
  • 如何用 SQLite 实现一个极简的本地持久记忆模块;
  • 把记忆模块接入 AI 编程工作流时,应该注意哪些坑和工程化建议。

1. AI Coding 工具的“记忆”瓶颈

1.1 什么是 AI Coding Agent 的“记忆”

要理解 Llmem 这类工具的价值,得先看 AI 编程工具目前的记忆方式。

当前主流 AI Coding 工具(包括各类 IDE 插件、CLI Agent、AutoGPT 风格的自主编程 Agent)大多采用“会话式上下文”工作模式。它的工作过程可以简化成三步:

  1. 接收用户的自然语言指令;
  2. 结合当前代码库、文件内容、对话历史组成上下文;
  3. 调用大模型生成代码或执行终端操作。

问题在于,这个上下文是临时的。对话轮次一旦结束、终端会话一旦关闭、或者 Agent 上下文长度超限被截断,模型就“失忆”了。下一次启动,它只能重新读取代码库,但无法记住:

  • 项目里哪些约定是团队刚定下来的;
  • 这个 bug 之前排查到哪一步、已经否定了哪些方案;
  • 用户偏好用 TypeScript 还是 JavaScript、测试框架选 Vitest 还是 Jest;
  • 上一次重构时哪些文件已经迁移完,哪些还没动。

这就是“记忆”和“上下文窗口”的本质区别:

  • 上下文窗口是短时记忆,容量有限,对话结束就清空;
  • 持久记忆是长时记忆,能跨会话保留,供后续请求反复读取。

AI 编程要从“能写代码”进化到“能持续维护项目”,缺少的就是长时记忆。

1.2 现有记忆方案的两条技术路线

目前业界做 AI 编程记忆,大体有两条路线。

第一条是无限上下文 / 超长上下文窗口。通过扩展模型的上下文长度,把所有历史信息一股脑塞进去。这种方式实现简单,但成本随上下文长度快速上升,且检索效率不高,历史信息混在一起,真正关键的决定容易被淹没。

第二条是外部存储 + 向量检索。把对话历史、代码片段、设计文档转换成 embedding 向量,存入向量数据库,查询时做相似度检索。这也是目前很多 AI 编程工具和 RAG 方案的主流做法。

但 embedding 方案并非没有代价:

  • 需要额外调用 embedding 模型,可能是远程 API,也可能是本地模型,都会增加延迟;
  • 需要维护向量数据库,引入新的基础设施;
  • 相似度检索的结果是“模糊的”,可解释性差,你很难说清楚它为什么召回这条记忆;
  • 在离线环境、内网环境或者本地资源有限的开发机上,部署一套 embedding + 向量库链路并不轻松。

正是在这种背景下,Llmem提出了一种更轻的思路:本地持久记忆不需要 embeddings,也能解决 AI 编程中的大部分记忆需求。

1.3 本地持久记忆要解决的核心问题

不管用不用 embedding,一个可用的本地持久记忆系统,都得回答下面四个问题:

问题说明
存什么哪些信息值得被记住,哪些只是噪音
什么时候写在对话的哪个节点把信息沉淀到存储中
怎么读用户或 Agent 如何快速找到与当前任务相关的记忆
怎么失效旧记忆怎么清理,避免信息过时和堆积

Llmem 这类 no-embeddings 方案的思路,是把其中“怎么读”这一步从向量相似度检索,替换成更轻量的结构化查询和关键词匹配。

2. Llmem 的核心思路:本地、持久、无 embeddings

2.1 “No embeddings”到底意味着什么

很多文章一提到“AI 记忆”,就默认必须做向量化。但 Llmem 的标题明确把“no embeddings”当成卖点,说明它刻意放弃了一条被认为“理所当然”的路线。

不使用 embeddings,意味着整个系统不依赖 embedding 模型,也不依赖向量数据库。具体来说:

  • 没有 embedding 接口调用,也就没有额外的网络依赖和费用;
  • 没有向量索引构建,写入记忆时不需要等待向量化完成;
  • 没有相似度计算的抽象黑盒,记忆的匹配逻辑直接可见、可调试;
  • 整个系统可以完全跑在本地,甚至跑在一台非常低配的开发机上。

它的取舍也很明确:放弃了语义相似检索的强大能力,换取了简单、可控、离线可用。

2.2 无 embedding 的本地记忆如何工作

如果不用 embedding,记忆检索怎么实现?答案是用结构化数据 + 关键词匹配 + 元信息过滤

举个例子。假设 AI 编程 Agent 完成了一次“修复用户登录时 token 过期导致 401”的任务,它可以把下面这段记忆写入本地存储:

{ "id": 1024, "content": "用户登录 token 过期时,后端返回 401,前端需要拦截并跳转 /login", "source": "auth_module_fix", "tags": ["auth", "token", "login", "401"], "importance": 0.8, "created_at": 1718000000 }

下次用户提问“登录又 401 了,怎么回事”,Agent 检索记忆时可以做两件事:

  1. 用关键词登录401token在记忆库里做匹配;
  2. 根据匹配度、创建时间、重要程度给候选记忆排序,挑出最相关的几条注入提示词。

这种方案检索不到“用户认证失败”这种完全不同的表述,但对于编程场景里大量明确、可枚举的专业术语来说,关键词匹配已经能解决很大一部分问题。这就是 Llmem 这类工具敢于去掉 embeddings 的底气。

2.3 从 Show HN 看 Llmem 的项目定位

“Show HN”是 Hacker News 上专门展示个人项目、开源作品的一个板块。作者把自己的工具发布上去,接受社区反馈。这通常意味着项目处于早期阶段,文档和 API 可能变化较快,但它代表了一个明确的产品趋势:AI 编程的记忆机制正在从“云端、重量级”走向“本地、轻量级”。

从标题提供的信息看,Llmem 面向的是 AI 编码场景,强调 local(本地)和 persistent(持久)。如果你想实际使用它,建议直接查看项目仓库的 README 和示例代码,重点确认三件事:

  • 支持哪些编程语言或框架接入;
  • 记忆条目如何定义和存储;
  • 与其他工具(如 Claude Code、Cline、Continue 等)的集成方式。

因为项目仍可能快速迭代,本文后面给出的示例不直接绑定 Llmem 的 API,而是实现一个与它同思路的迷你版本地持久记忆模块。理解了这个模块,你再去看 Llmem 的源码或文档,会轻松很多。

3. 环境准备与演示项目结构

在开始写代码前,先明确一下环境。

下面这个参考实现只使用 Python 标准库,不依赖第三方包。它的核心存储引擎是 SQLite,所以只需确认本机 Python 版本在 3.9 以上即可。如果你的电脑上还没有 Python,去官网下载安装后,通过下面命令验证:

python --version # 建议输出 Python 3.9 或更高版本

SQLite 是 Python 内置支持的轻量级数据库,不需要单独安装服务端,非常适合做本地开发工具的记忆存储。

3.1 项目目录结构

为了演示清晰,我们创建一个简单的项目结构:

local-memory-demo/ ├── memory_store.py # 记忆存储核心模块 ├── cli_demo.py # 命令行演示脚本 ├── memories.db # SQLite 数据库文件(运行时自动生成) └── README.md # 说明文档(可选)

当然,实际项目中你完全可以把memory_store.py改名为llmem_client.py或者嵌入到你自己的 Agent 工具代码库里。

4. 参考实现:no-embeddings 本地持久记忆模块

4.1 初始化数据库

首先实现存储模块的骨架。它的职责是:创建数据库表、支持写入记忆、按关键词检索记忆、清理过期记忆。

下面是memory_store.py的完整代码:

# memory_store.py import json import math import sqlite3 import time from pathlib import Path from typing import Dict, List, Optional class LocalMemoryStore: """ 一个极简的本地持久记忆存储模块。 不使用 embedding,使用 SQLite + 关键词匹配实现记忆读写。 """ def __init__(self, db_path: str = "memories.db"): self.db_path = Path(db_path) self._init_db() def _get_connection(self) -> sqlite3.Connection: conn = sqlite3.connect(self.db_path) conn.row_factory = sqlite3.Row return conn def _init_db(self) -> None: conn = self._get_connection() try: conn.execute( """ CREATE TABLE IF NOT EXISTS memory_entries ( id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT NOT NULL, source TEXT DEFAULT '', tags TEXT DEFAULT '[]', importance REAL DEFAULT 0.5, created_at REAL NOT NULL, last_accessed_at REAL, access_count INTEGER DEFAULT 0 ) """ ) conn.commit() finally: conn.close()

这里有几处设计值得注意:

  • tags字段用 JSON 数组存储标签,方便后续做精确匹配;
  • importance是人工或 Agent 写入记忆时标记的重要程度,取值范围建议 0 到 1;
  • created_at存 Unix 时间戳,体现“创建时间”;
  • last_accessed_ataccess_count用于记录记忆被访问的情况,后续可以做热度衰减。

4.2 写入记忆

写入记忆的方法如下:

def add_memory( self, content: str, source: str = "", tags: Optional[List[str]] = None, importance: float = 0.5, ttl: Optional[int] = None, ) -> int: """ 写入一条记忆。 :param content: 记忆内容 :param source: 来源,例如模块名、Agent 名称 :param tags: 标签列表 :param importance: 重要程度 0~1 :param ttl: 生存时间(秒),超过后检索时自动忽略 :return: 新记忆 id """ if not content or not content.strip(): raise ValueError("content 不能为空") conn = self._get_connection() try: cur = conn.execute( """ INSERT INTO memory_entries (content, source, tags, importance, created_at) VALUES (?, ?, ?, ?, ?) """, ( content.strip(), source, json.dumps(tags or [], ensure_ascii=False), float(importance), time.time(), ), ) conn.commit() return cur.lastrowid finally: conn.close()

注意ttl参数暂时还没有落到表结构里。要支持过期逻辑,有两种方式:

  1. 在表中增加expire_at字段,写入时计算过期时间;
  2. 在查询时用created_atttl一起判断。

为了简化演示,我们采用第二种方式:在检索时传入ttl_filter参数,由调用方决定多长时间以内的记忆才算有效。

4.3 关键词检索与排序

这就是 no-embeddings 方案的关键部分。我们不用向量相似度,而是把候选记忆取出来,在 Python 中计算一个简单的相关分。

def search_memory( self, query: str, limit: int = 5, ttl_filter: Optional[int] = None, ) -> List[Dict]: """ 按关键词检索记忆。 匹配规则:content 包含任意查询词,或 tags 包含任意查询词。 """ # 把查询拆成关键词 words = [w.strip() for w in query.replace(",", " ").replace(",", " ").split()] words = [w for w in words if w] if not words: return [] conn = self._get_connection() try: # 先从数据库里挑出候选 conditions = [] params = [] for word in words: conditions.append("(content LIKE ? OR tags LIKE ?)") pattern = f"%{word}%" params.append(pattern) params.append(pattern) where_clause = " OR ".join(conditions) rows = conn.execute( f""" SELECT * FROM memory_entries WHERE {where_clause} ORDER BY created_at DESC LIMIT ? """, [*params, limit * 5], ).fetchall() # 在 Python 里做二次打分排序 now = time.time() scored = [] for row in rows: content = row["content"] tags = json.loads(row["tags"] or "[]") created_at = row["created_at"] importance = row["importance"] # TTL 过滤 if ttl_filter is not None and (now - created_at) > ttl_filter: continue # 基础分:内容命中多少词 hit_count = sum(1 for w in words if w in content) tag_hit = sum(1 for w in words if w in tags) if hit_count == 0 and tag_hit == 0: continue # 时间衰减系数,24 小时为半衰期 age_hours = (now - created_at) / 3600 time_decay = math.exp(-age_hours / 24) score = (hit_count * 2 + tag_hit * 1.5) * importance * time_decay scored.append( { "id": row["id"], "content": content, "source": row["source"], "tags": tags, "importance": importance, "created_at": created_at, "score": round(score, 4), } ) scored.sort(key=lambda x: x["score"], reverse=True) return scored[:limit] finally: conn.close()

这段代码体现了三个关键思路:

  1. 先粗筛,再精排。先用 SQL 的 LIKE 减少数据量,再用 Python 计算排序分,避免在数据库里写复杂函数;
  2. 时间衰减math.exp(-age_hours / 24)让记忆在 24 小时后相关度减半,避免很久以前的碎片长期占据高位;
  3. 重要程度参与排序。同样命中的记忆,人工标记为高优先级的会更先被读取。

4.4 清理与统计

记忆系统不能只进不出。我们提供一个简单的清理方法:

def cleanup_expired(self, max_age_hours: float = 24 * 30) -> int: """ 清理超过指定小时数且从未被再次访问的旧记忆。 返回删除条数。 """ deadline = time.time() - max_age_hours * 3600 conn = self._get_connection() try: cur = conn.execute( """ DELETE FROM memory_entries WHERE created_at < ? AND access_count = 0 """, (deadline,), ) conn.commit() return cur.rowcount finally: conn.close() def stats(self) -> Dict: conn = self._get_connection() try: total = conn.execute("SELECT COUNT(*) AS c FROM memory_entries").fetchone()["c"] return {"total": total} finally: conn.close()

这里的清理策略是“超过 30 天且从未被访问过的记忆直接删除”。如果一个记忆被多次读取,说明它仍然活跃,即使旧一些也值得保留。更复杂一点的系统可以根据记忆的access_count做热度分级,这里为了保持代码简洁,不做过度设计。

4.5 命令行演示

为了让上面的模块可以直接运行,我们再写一个简单的cli_demo.py

# cli_demo.py from memory_store import LocalMemoryStore def main(): store = LocalMemoryStore("memories.db") # 写入几条示例记忆 store.add_memory( content="用户登录 token 过期时,后端返回 401,前端需要拦截并跳转 /login", source="auth_module_fix", tags=["auth", "token", "login", "401"], importance=0.9, ) store.add_memory( content="项目测试框架使用 Vitest,不使用 Jest", source="team_standard", tags=["test", "vitest", "standard"], importance=0.8, ) store.add_memory( content="订单状态变更后需要发送 WebSocket 通知", source="order_service", tags=["order", "websocket"], importance=0.6, ) print("当前记忆量:", store.stats()["total"]) # 检索测试 print("\n--- 查询:登录 401 ---") for item in store.search_memory("登录 401", limit=3): print(item["score"], item["content"]) print("\n--- 查询:测试框架 ---") for item in store.search_memory("测试框架", limit=3): print(item["score"], item["content"]) if __name__ == "__main__": main()

运行结果期望类似这样:

当前记忆量: 3 --- 查询:登录 401 --- 1.7951 用户登录 token 过期时,后端返回 401,前端需要拦截并跳转 /login 0.0 项目测试框架使用 Vitest,不使用 Jest --- 查询:测试框架 --- 0.799 项目测试框架使用 Vitest,不使用 Jest

不同的机器、不同时间的运行结果会因时间衰减稍有差异,但排序逻辑直观可见。

4.6 如何与 AI Coding 工作流结合

上面的LocalMemoryStore只是存储与检索基础模块。真正接入 AI 编程工作流时,还需要一个“调度层”,负责决定何时读取记忆、何时写入记忆。

一个可参考的接入流程:

  1. 用户发起新任务;
  2. Agent 先从本地记忆库中检索与任务描述最相关的 3~5 条记忆;
  3. 将这 3~5 条记忆追加到系统提示词中,再调用大模型;
  4. 任务结束后,Agent 把本次任务中值得沉淀的信息(关键决策、踩坑结论、用户偏好)写入记忆库;
  5. 定期运行cleanup_expired,防止记忆库无限膨胀。

关键点在第 2 步:记忆检索应该发生在模型调用之前,而不是之后。你可以把它理解为“给模型开场前塞小抄”,而不是“让模型自己翻笔记本”。

在具体实现上,如果接入的是 Claude Code、Cline 这类已有 Agent 框架的项目,通常可以通过自定义插件或工具调用的方式实现上述流程。Llmem 这类项目很可能就是在扮演这个“记忆底座”的角色。

5. embeddings 方案与 no-embeddings 方案对比

5.1 一张表看清差异

关于 Llmem 出现的背景,最好用一个表格对比两种方案在不同维度上的差异:

对比维度Embeddings + 向量库No-embeddings(Llmem 思路)
数据存储向量数据库 + 元数据存储本地数据库 / JSON / 文本文件
写入成本需要调用 embedding 模型生成向量直接写入,零额外计算
检索能力语义相似检索,能处理近义表述关键词/标签匹配,依赖术语一致性
可解释性较差,向量相似度难以解释较好,可明确看到命中词和排序规则
离线支持依赖 embedding 模型和向量库部署天然离线可用
维护复杂度中等偏高
隐私保护取决于 embedding 服务部署位置数据完全本地
适用项目规模中大型、记忆量大、语义模糊场景个人开发机、中小项目、术语固定场景

5.2 什么时候选 no-embeddings 方案

结合 AI 编程的实际场景,下面这些情况更适合 Llmem 这类轻量方案:

  1. 本地开发环境。开发者电脑上资源有限,不想为了一个记忆功能再启一个向量数据库容器。
  2. 离线或内网环境。不允许把代码片段、业务信息发送到外部 embedding 服务。
  3. 记忆以“明确术语”为主。编程场景中的关键词通常很固定:函数名、文件名、框架名、报错信息、接口路径,这些内容用关键词匹配效果不差。
  4. 希望记忆行为可控、可调试。开发过程中如果发现记忆检索不准,向量方案往往要调 embedding 模型、调向量库参数,很玄学;而关键词方案可以直接查看排序逻辑,改起来明确。

5.3 什么时候还是要用 embeddings

当然,no-embeddings 并不是万能的。如果遇到下面这些情况,还是建议考虑 embedding 方案:

  • 记忆条目非常多(比如上万条),关键词检索很难覆盖所有表述;
  • 用户提问方式高度口语化,和存储的术语相差很远;
  • 需要跨语言的语义匹配,例如英文文档、中文提问混合;
  • 需要根据语义聚类、推荐,而不只是精确检索。

实际工程中,两种思路并不互斥。你完全可以用一个混合方案:关键词检索作为第一层快速过滤,语义检索作为第二层兜底,两条路径的结果做加权融合。Llmem 提供的 no-embeddings 思路,正好可以作为这套混合方案里最轻量的前置通道。

6. 常见问题与排查思路

6.1 记忆写入并发冲突

SQLite 同一时刻只允许一个写事务。如果多个 Agent 或 IDE 插件进程同时写入记忆库,可能出现database is locked报错。

排查和解决思路:

  • WAL模式可以减少读写锁冲突;
  • 写入逻辑尽量集中到一个进程;
  • 如果并发写入频繁,可以加一层带重试机制的写入封装。

6.2 关键词检索召回率低

用户提问“用户认证失败”,但存进去的记忆写的是“登录 token 过期”。两者语义一致,表述不同,关键词匹配就不灵了。

解决这个问题,不一定要上 embedding,可以先尝试两个简单手段:

  1. 在写入时增加同义词标签,例如“登录”和“认证”都写成标签;
  2. 在读取时做查询改写,先让大模型把用户问题改写成多个可能的关键词组合,再用这些组合做检索。

第二种方式比全量 embedding 成本低很多,效果提升也很明显。

6.3 记忆噪音太多

随着使用时间变长,记忆库会积累大量低价值记录,比如“今天把按钮颜色改成蓝色”。这类一次性信息对后续任务没有帮助。

建议的做法是:写入时降低importance,定期执行cleanup_expired,或者人工把重要的记忆固定为“置顶知识”。从实现上说,可以在表里加一个pinned字段,置顶记忆不参与时间衰减。

6.4 数据隐私和误用

本地记忆库保存的是开发过程中的对话和代码结论。如果电脑被多人使用,或者代码仓库被同步到第三方平台,这些记忆可能被泄露。

建议遵守以下边界:

  • 不要写入任何密码、Token、密钥;
  • 不要把客户敏感数据写进记忆库;
  • 如果记忆库文件放在项目目录下,记得加入.gitignore
  • 对记忆库文件设置较严格的文件系统权限。
问题现象常见原因解决思路
database is locked多进程并发写开启 WAL、集中写入、加重试
检索不到相关记忆表述不一致增加同义词标签、查询改写
记忆越积越多缺少过期机制设置 TTL、定期清理
敏感信息泄露风险把密钥写入记忆禁止写入凭据、加 .gitignore

7. 最佳实践:给本地记忆系统加工程化护栏

如果你准备把 no-embeddings 本地记忆方案用到真实项目中,下面这些建议值得参考。

7.1 记忆条目要“原子化”

一条记忆只保存一个结论。不要把“今天完成了登录模块、修了 401、顺便调整了按钮样式”写成一条。拆成三条独立记忆,检索时才能精确命中。原子化也让去重和更新变得更加容易。

7.2 给记忆带上来源和可信度

记忆库会同时保存 Agent 自动生成的记录和人工手动整理的知识,它们的可信度不同。建议在表结构中增加sourceconfidence两个字段:

  • source:记录来源,比如agent_autouser_manualcode_review
  • confidence:可信度,比如 0~1。

检索时,如果结果条数过多,可以优先返回人工知识标记的记录。

7.3 设计“更新”而不是“追加”

同一个主题的记忆可能会更新。比如项目一开始定下“用 Jest 做测试框架”,两周后改成“用 Vitest”。如果只追加不更新,检索时会同时出现两条相反结论。

建议在写入前做一次检索,如果发现相似记忆已经存在,就更新旧记录的内容而不是插入新记录。可以用(source, tags)作为去重键,也可以由调用方传入replace_id

7.4 记忆库文件必须纳入版本管理范围之外

如果记忆库文件放在代码仓库内部,务必将它加入.gitignore

# .gitignore 示例 memories.db memories.db-journal memories.db-wal memories.db-shm

记忆是开发者的私密上下文,不应被同步到公共仓库。

7.5 检索逻辑要可测试、可回放

记忆系统的难点不在写入,而在“检索准确性”。建议给检索模块编写确定性测试:

  • 准备一份固定的测试记忆集;
  • 写一批固定的查询词;
  • 断言排序结果是否符合预期;
  • 修改排序算法后,能通过回归测试验证效果没变差。

这套测试能把记忆系统的行为“锁住”,避免以后优化时误伤已有场景。

7.6 在 Agent 工作流中明确记忆读取位置

记忆不是万能的,也不是所有任务都必须读记忆。建议按任务类型区分:

  • 涉及项目整体架构、既有实现时,优先读记忆;
  • 纯算法写作、一次性脚本生成,可以不读记忆,节省 token;
  • 超过一定轮次的对话,在每轮开始前重新检索一次记忆,避免信息过期。

把记忆读取设计成“按需注入”而不是“全部塞入”,信息密度更高,模型专注度也会更好。

8. 总结与后续学习路线

本文从一个开源项目标题出发,拆解了 AI 编程场景下“本地持久记忆”的需求背景,也解释了 Llmem 为什么把“no embeddings”当作卖点。随后用 Python 标准库实现了一个迷你版本地记忆模块,覆盖了写入、关键词检索、时间衰减排序和过期清理,并探讨了它与 embedding 方案的边界和取舍。

核心收获可以归纳为三点:

  • AI 编程工具的长时记忆,不一定要靠向量数据库才能实现;
  • 结构化字段、关键词匹配、时间衰减,足以覆盖大量编程语境下的记忆场景;
  • 老工具、老思路在 AI 时代仍然有实用价值,关键是你理解业务约束是什么。

如果你对这个方向感兴趣,下一步可以沿着三条线继续深入:

  1. 读 Llmem 的源码,看你能否找到与本文实现对应的设计决策;
  2. LocalMemoryStore接入一个开源 Agent 工具,做一个“带记忆的代码审查助手”练手;
  3. 在检索层做一次升级:加入查询改写和 TF-IDF 加权,看看在不引入 embedding 的情况下,检索精度能提升多少。

记忆系统没有银弹,最合适的方案永远是结合你的数据量、硬件条件、离线需求和隐私约束综合权衡的结果。希望这篇文章能给你一条新的思考路径,也欢迎在评论区聊聊你正在使用的 AI 编程记忆方案。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 11:53:19

TensorFlow与CNN猫狗识别实战:从数据到模型部署完整指南

毕业设计选“猫狗识别”这个题目的人很多&#xff0c;但它确实是最适合入门卷积神经网络的选题之一&#xff1a;公开数据集好找、任务就是二分类、模型可以做得不大、普通笔记本甚至 CPU 也能训练。这次我们就把一套基于 TensorFlow CNN 的猫狗二分类实现完整过一遍&#xff0…

作者头像 李华
网站建设 2026/9/6 20:20:26

C++ STL函数对象与算法精解:从仿函数到高效编程实践

1. 从“可调用”到“可定制”&#xff1a;理解STL中的函数对象在C的日常开发里&#xff0c;尤其是和STL&#xff08;Standard Template Library&#xff09;打交道时&#xff0c;我们经常听到“函数对象”或者“仿函数”这个词。很多初学者&#xff0c;包括当年的我&#xff0c…

作者头像 李华
网站建设 2026/8/31 11:36:25

Codex CLI 自动化科研指南:从安装到数据建模绘图全流程

这次我们来看 Codex CLI&#xff0c;OpenAI 开源的终端编程智能体。它最直接的用法是在终端里用自然语言指挥 AI 改代码、跑命令&#xff0c;但放到科研流程里&#xff0c;价值会被放大&#xff1a;数据清洗、统计摘要、训练脚本、图表绘制、结果汇总&#xff0c;这些占掉科研日…

作者头像 李华
网站建设 2026/9/2 9:33:01

自动驾驶算法岗笔试题解析:哈希表、滑动窗口与区间合并

最近在整理自动驾驶公司算法岗的校招笔试题&#xff0c;翻到小马智行 pony.ai 的2019校招真题&#xff08;二&#xff09;时&#xff0c;发现这套题放在今天看依然很有代表性。它没有太偏门的题目&#xff0c;三题全是面试笔试里最高频的考点&#xff1a;哈希表处理几何问题、滑…

作者头像 李华
网站建设 2026/9/2 10:10:00

SSM+JSP进销存系统实战:Java Web三层架构教学与落地

简介&#xff1a;进销存系统是企业信息化的基础应用&#xff0c;其本质是采购、销售、库存三类业务状态的协同流转与数据闭环。理解其原理需回归Web开发底层脉络&#xff1a;HTTP请求如何经Controller接收、Service事务控制如何保障账实一致、MyBatis手写SQL如何实现精准报表、…

作者头像 李华
网站建设 2026/9/2 11:07:31

插值与拟合:从核心原理到MATLAB/Python实战,避坑指南全解析

1. 项目概述&#xff1a;从“猜”数据到“造”模型 在数学建模和数据分析的世界里&#xff0c;我们常常会遇到一个非常现实的问题&#xff1a;手头的数据要么不够用&#xff0c;要么不听话。不够用&#xff0c;指的是数据点太稀疏&#xff0c;比如你只有某条河流几个断面的水质…

作者头像 李华