ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

本地大模型长期记忆系统部署实战:向量库到跨会话召回

本地大模型长期记忆系统部署实战:向量库到跨会话召回

你现在问本地跑的大模型一句“上周我们定的那个方案叫什么来着”,它大概率会一本正经地给你编一个。不是模型笨,是它压根没有地方存东西:一次会话结束,上下文清零,下次对话从零开始。这篇文章要解决的就是这个很具体的问题——怎么让本地 AI 助手真的“铭记”你们之间定下的约定,把用户偏好、项目背景、历史结论这些东西跨会话留下来,而不是每次都要重新喂一遍。

这件事在云端产品里叫“记忆功能”,在本地部署场景里,对应的是长期记忆系统(Long-term Memory)。它不是一个单独的模型,而是一套组合:向量库负责存和检索、Embedding 模型负责把文本变成向量、LLM 负责抽取和合并事实、编排层负责决定“什么时候该记、该记什么、该忘什么”。本文会把这一整套跑在本地机器上,覆盖从零部署、接口调用、批量导入、效果验证到显存观察的完整链路。

硬件门槛这块先说清楚:记忆系统的存储层(向量库)本身很轻,吃的是内存和磁盘;真正吃显存的是背后的对话模型和 Embedding 模型。7B 级别的对话模型在 4bit 量化下通常能在 8G 显存级别跑起来,Embedding 模型体量更小,几百 MB 显存就够。如果你用 CPU 推理也能跑,只是检索和抽取的响应会慢一截。具体占用必须按你选的模型版本、量化方式和并发量实测,这篇文章不给你编数字。

适合读这篇的人:想把本地助手做成“有记忆的私人助理”的开发者、需要给内部知识助手加用户画像的团队、以及单纯想搞清楚 Mem0、Letta 这类记忆框架到底怎么落地的人。下面按“能力速览 → 架构选型 → 环境 → 部署 → 测试 → 接口 → 性能 → 排错 → 实践”的顺序走。

1. 长期记忆系统核心能力速览

先把关键信息摆出来,判断值不值得动手。

能力项说明
系统类型本地部署的 AI 长期记忆层,非单一模型
主要功能记忆写入、语义检索、事实抽取与合并、冲突更新、记忆删除、跨会话召回
推荐硬件对话模型 7B 量化级别建议 8G 显存以上,Embedding 模型显存占用低;CPU 推理可跑但延迟更高
显存占用取决于对话模型参数量、量化方式、Embedding 模型大小与并发数,需按本机实测
存储后端向量库(Qdrant / Chroma / Milvus / pgvector 等)+ 可选关系库存元数据
支持平台Windows / Linux / macOS 均可,生产环境建议 Linux
启动方式Docker 拉起向量库 + 命令行启动记忆服务 + FastAPI 暴露 HTTP 接口
是否支持 API是,通常以 REST 接口形式对外提供 add / search / delete
是否支持批量任务是,可通过 JSONL 批量导入 + 队列 + 重试机制实现
适合场景私人助理、客服机器人、项目知识沉淀、多轮业务系统、Agent 记忆
不适合场景要求毫秒级强一致的实时事务、无授权的大量用户隐私数据聚合

这张表里唯一需要你重点确认的是“显存占用”这一行。同一个 7B 模型,用 Q4 量化和用 FP16,显存差距是数量级的;Embedding 模型从 100M 参数换到 500M 参数,又是另一个量级。所以别信任何脱离模型规格的固定数字,包括别人博客里写的那些。

2. 适用场景与使用边界

先讲清楚这东西到底解决什么问题。大模型的上下文窗口再大,也有三个硬伤:一是贵,长上下文每次请求都要重新计费或重新算;二是慢,上下文越长首 token 延迟越高;三是跨会话不连续,关掉窗口就归零。长期记忆系统针对的正是第三点——它把“值得记住的东西”抽出来,落到外部存储里,下一轮对话按需检索回来,只占用很少的上下文预算。

具体适合谁?第一类是个人开发者,想让本地助手记住自己的技术栈偏好、常用路径、项目代号,不用每次开头都重新交代。第二类是团队内部的知识助手,把项目决策、接口约定、历史踩坑记录沉淀下来,新人问一句就能召回。第三类是 Agent 类应用,需要跨任务保存中间结论,避免每一步都从零开始推理。

不适合的场景也要说清楚。如果你的需求是“每次都要读到最新完整文档”,那你要的是 RAG(检索增强生成),不是记忆系统——RAG 索引的是静态知识库,记忆系统索引的是动态交互事实,两者的写入频率、更新策略、生命周期完全不同,别混为一谈。

使用边界这块必须单独强调。记忆系统天然会存下大量个人信息和业务信息,所以在做任何部署之前,先把这几条定下来:

  • 授权边界:只记录用户明确知晓并同意被记录的内容,不要把对话里的身份证号、手机号、住址、账号密码自动写进向量库。
  • 数据隔离:按user_id、agent_id、run_id做命名空间隔离,不同用户、不同业务线的记忆不能互相召回。
  • 删除权:必须提供按用户维度彻底删除记忆的能力,并且删除要落到向量库和元数据两边,不能只删一边。
  • 脱敏:写入前做正则或规则脱敏,把手机号、邮箱、密钥前缀这类内容替换掉,宁可记不住,也不要记错地方。
  • 审计:保留写入和检索日志,出问题时能追溯是哪条记忆导致的错误回答。

如果你是给第三方做系统,这些边界不是可选项,是设计前提。记忆系统一旦跑起来,数据的雪球会越滚越大,前期没做隔离,后期补的成本极高。

3. 系统架构与组件选型

记忆系统不是一个软件包,是四到五个组件的组合。下面这张表把每一层拆开,你可以按资源情况自由换件。

层级职责常见可选项选型建议
对话模型层生成回答、抽取事实、判断是否值得记Ollama、llama.cpp、vLLM、各类本地推理框架资源紧张用 Ollama 快速起步,追求吞吐再上 vLLM
Embedding 层把记忆文本转成向量bge 系列、nomic-embed-text、各类开源向量模型中文场景优先选中文效果好的 bge 系;显存紧张用小参数量版本
向量存储层存向量、做相似度检索Qdrant、Chroma、Milvus、pgvector单机起步 Qdrant 或 Chroma 足够;已有 PostgreSQL 可直接用 pgvector
记忆管理层抽取、去重、冲突合并、过期策略Mem0、Letta(原 MemGPT)、LangChain Memory、自研想快速验证用现成框架,要精细控制就自研
编排与接口层对外暴露 HTTP 接口、串流程FastAPI、Flask、Node 服务Python 生态首选 FastAPI,异步和文档生成都省事

架构上我建议先走最小闭环,别一上来就堆组件。最小闭环只需要三件东西:一个能跑的对话模型、一个 Embedding 模型、一个向量库。记忆管理逻辑先用最简单的规则版——直接存原文 + 检索 top_k,跑通了再上“事实抽取 + 冲突合并”的复杂逻辑。

这里解释一下为什么要分“原文记忆”和“事实记忆”两层。原文记忆保真度高,但噪声大、检索命中率低;事实记忆(比如“用户偏好使用 FastAPI”“项目代号叫 Orion”)紧凑、检索准,但抽取过程中会丢信息。实践里通常是两层都留,检索时先召回事实,事实不够再回退到原文片段。这个策略在后面的测试环节会具体验证。

还有一个容易被忽略的点:Embedding 模型必须和向量库的维度对齐。你换了 Embedding 模型,向量维度变了,旧集合直接不可用,必须重建索引。所以选型阶段就要把模型定下来,别中途随便换。如果确实要换,走“新集合双写 + 全量重建 + 灰度切换”的流程,别直接原地覆盖。

4. 本地部署环境准备

环境这块给一份通用检查清单,具体版本号按你实际装的时候的官方要求来,别硬套别人博客里的数字。

操作系统方面,Windows 10/11 能跑,但 Docker Desktop 的 WSL2 后端偶尔会在端口映射上出问题;Linux(Ubuntu 系)最省心;macOS 用 Apple Silicon 跑 Ollama 体验不错,但 Docker 网络层偶尔会有额外延迟。

基础依赖清单:

  • Python 3.10 及以上(多数记忆框架要求 3.10+,低于这个版本容易在依赖解析阶段就卡住)
  • pip 或 uv 作为包管理,建议用虚拟环境隔离,别往系统 Python 里装
  • Docker(用于拉起向量库),或者直接用向量库的嵌入式模式
  • GPU 驱动与 CUDA,只有在你要用 GPU 推理时才需要,CPU 模式不需要
  • 磁盘空间:向量库本身占用不大,但模型文件动辄几 GB,加上日志和快照,建议预留 30G 以上

端口规划也要提前想好,别等到起冲突了再改。常见占用如下:

服务默认端口说明
Ollama11434本地推理服务
Qdrant6333 / 6334HTTP 接口 / gRPC 接口
Chroma8000独立服务模式下的默认端口
记忆服务(自建)8000 或 8080与 Chroma 默认端口冲突,注意错开

前置检查直接跑几条命令确认:

# 检查 Python 版本 python --version # 检查 Docker 是否可用 docker --version docker ps # 检查端口占用情况(Linux / macOS) lsof -i :11434 lsof -i :6333 # Windows 下用 netstat 检查端口 netstat -ano | findstr :6333

如果lsof显示某个端口已被占用,先确认占用进程是不是你自己之前没关干净的服务。记忆系统最常见的“启动失败”,八成是上一次进程残留占着端口,而不是配置写错了。

5. 部署与启动流程

按“向量库 → 推理服务 → 记忆服务”的顺序起,每一步都验证一遍再往下走。

5.1 启动向量库

以 Qdrant 为例,Docker 一行拉起,并把数据目录挂出来,避免容器一删数据全丢:

docker run -d \ --name qdrant \ -p 6333:6333 \ -p 6334:6334 \ -v $(pwd)/qdrant_storage:/qdrant/storage \ qdrant/qdrant

起完之后访问http://127.0.0.1:6333/dashboard,能看到管理界面就说明服务正常。如果你更想用 Chroma,也可以用它的 Docker 镜像或者嵌入式模式,嵌入式模式不需要单独起服务,直接在 Python 里PersistentClient指定目录即可,适合单机验证。

5.2 启动本地推理服务

用 Ollama 拉取对话模型和 Embedding 模型:

# 拉取对话模型(模型名按你实际选择的替换) ollama pull qwen2.5:7b # 拉取 Embedding 模型 ollama pull nomic-embed-text # 确认模型列表 ollama list

拉完之后先单独测一下模型能不能正常生成,别把问题留到上层:

curl http://127.0.0.1:11434/api/generate -d '{ "model": "qwen2.5:7b", "prompt": "用一句话说明什么是向量检索", "stream": false }'

能返回正常文本,说明推理层通了。如果这一步就超时,先看显存是不是被别的进程吃满,再确认模型名有没有拼错。

5.3 安装记忆框架

创建一个干净的虚拟环境再装依赖:

python -m venv venv source venv/bin/activate # Windows 用 venv\Scripts\activate pip install --upgrade pip pip install mem0ai qdrant-client fastapi uvicorn

安装完成后写一个最小配置文件,把向量库、LLM、Embedder 三块接起来。下面这份配置是通用结构,具体字段名以你安装版本的官方文档为准,不同版本在键名上会有差异:

# memory_config.py config = { "vector_store": { "provider": "qdrant", "config": { "host": "127.0.0.1", "port": 6333, "collection_name": "agent_memory" } }, "llm": { "provider": "ollama", "config": { "model": "qwen2.5:7b", "ollama_base_url": "http://127.0.0.1:11434" } }, "embedder": { "provider": "ollama", "config": { "model": "nomic-embed-text", "ollama_base_url": "http://127.0.0.1:11434" } } }

5.4 最小可运行验证脚本

在接 HTTP 接口之前,先用脚本确认“写入 → 检索”这条链路通不通:

# smoke_test.py from mem0 import Memory from memory_config import config memory = Memory.from_config(config) # 写入两条记忆,用 user_id 做隔离 memory.add("我习惯用 FastAPI 写后端接口,不喜欢 Flask", user_id="user_001") memory.add("这个项目的代号叫 Orion,数据目录统一放在 /data/orion", user_id="user_001") # 检索 results = memory.search("项目代号是什么", user_id="user_001") for item in results: print(item)

跑通的标准是:检索结果里能出现“Orion”相关的条目,并且没有把另一个用户的数据混进来。这一步如果失败,先别急着改代码,去看向量库的 collection 里到底有没有数据——很多时候是 Embedding 调用失败导致写入静默失败。

5.5 启动对外接口服务

用 FastAPI 包一层,把记忆能力暴露成 HTTP 接口:

# api_server.py from fastapi import FastAPI from pydantic import BaseModel from mem0 import Memory from memory_config import config app = FastAPI(title="Local Memory Service") memory = Memory.from_config(config) class AddRequest(BaseModel): text: str user_id: str class SearchRequest(BaseModel): query: str user_id: str limit: int = 5 @app.post("/memory/add") def add_memory(req: AddRequest): memory.add(req.text, user_id=req.user_id) return {"status": "ok"} @app.post("/memory/search") def search_memory(req: SearchRequest): results = memory.search(req.query, user_id=req.user_id, limit=req.limit) return {"status": "ok", "data": results} @app.delete("/memory/{user_id}") def delete_memory(user_id: str): memory.delete_all(user_id=user_id) return {"status": "ok"}

启动命令:

uvicorn api_server:app --host 127.0.0.1 --port 8080 --reload

注意--host不要随手写成0.0.0.0。记忆服务存的是隐私数据,本地验证阶段就绑127.0.0.1,等确认要做内网共享时再改,并且配合鉴权和访问控制一起上。

6. 功能测试与效果验证

部署跑通只是第一步,真正决定这套系统能不能用的是下面这几组测试。每一组都给出目的、输入、预期和判定标准,照着做就行。

6.1 跨会话召回测试

目的:验证关掉服务重启后,记忆是否还能被检索到。

输入:第一次启动时写入“我的主项目用 PostgreSQL 做向量存储”;然后停掉服务,重新启动;再提问“我的向量存储用的是什么”。

预期:能召回“PostgreSQL”这条记忆。

判定标准:回答中明确包含该事实,且不是模型自己编的(可以故意写一个不常见的词进去,看能不能原样召回)。

常见失败原因:向量库容器没做数据卷挂载,重启后数据清空;写入时用了不同的user_id,导致检索时命名空间不匹配。

6.2 记忆冲突更新测试

目的:验证用户改变主意后,系统是覆盖旧记忆还是并存。

输入:先写入“接口统一用 8080 端口”,再写入“接口端口改成 9090 了”。

预期:检索“接口端口”时,优先返回 9090,或者两条都返回但要能看出时间先后。

判定标准:不会出现只召回旧值、把新值丢掉的情况。

常见失败原因:框架默认只做追加不做合并;没有配置时间戳字段,导致排序失效。这类问题建议在写入时手动加created_at元数据,检索时按时间加权。

6.3 用户隔离测试

目的:验证不同用户的记忆不串。

输入:user_001写入“我偏好深色主题”,user_002写入“我偏好浅色主题”,然后分别以两个身份检索。

预期:各自只拿到自己的偏好。

判定标准:交叉查询时不能返回对方的条目。

常见失败原因:检索时忘记传user_id,或者向量库的过滤条件写成了must之外的模式,导致过滤失效。这个问题在多租户场景里是致命错误,必须测。

6.4 记忆删除测试

目的:验证删除是彻底删除,不是标记删除。

输入:写入三条记忆,调用删除接口,再检索。

预期:检索结果为空,且向量库里对应条目确实消失。

判定标准:不只是接口返回成功,还要去向量库确认条目数变化。

常见失败原因:只删了向量没删元数据,或者只删了元数据没删向量,导致“幽灵记忆”。

6.5 长对话压缩测试

目的:验证多轮对话后,系统能否把零散信息聚成稳定事实。

输入:连续写入 10 到 20 条碎片信息,例如“我在做一个爬虫”“用的语言是 Python”“目标站点需要限速”“每天跑一次”。

预期:检索“我的爬虫项目”时,能召回多条相关事实,最好还能聚成一条概括。

判定标准:召回结果的相关性排序合理,不相关的碎片不会被顶上来。

常见失败原因:Embedding 模型对短文本区分度不够;top_k设置过大,噪声涌入。

6.6 批量导入测试

目的:验证批量任务下系统的稳定性。

输入:准备一个 JSONL 文件,每行一条记忆,200 条起。

预期:全部导入成功,失败条目有日志可查。

判定标准:导入完成后统计条数与源文件一致,向量库条目数对应。

常见失败原因:单条失败导致整批中断;没有限速把推理服务打满;没有断点记录,失败后只能全量重跑。批量这块下一节单独展开。

7. 接口 API 与批量任务实现

接口这块,最小可用集合就是三个:写入、检索、删除。上面的 FastAPI 代码已经把框架搭好了,这里补调用示例和批量处理逻辑。

7.1 接口调用示例

写入:

curl -X POST http://127.0.0.1:8080/memory/add \ -H "Content-Type: application/json" \ -d '{"text": "生产环境数据库统一用 pgvector,版本以运维提供为准", "user_id": "user_001"}'

检索:

curl -X POST http://127.0.0.1:8080/memory/search \ -H "Content-Type: application/json" \ -d '{"query": "生产环境向量库用什么", "user_id": "user_001", "limit": 3}'

Python 调用:

import requests BASE = "http://127.0.0.1:8080" resp = requests.post( f"{BASE}/memory/add", json={"text": "接口超时统一设置为 30 秒", "user_id": "user_001"}, timeout=60 ) print(resp.status_code, resp.json()) resp = requests.post( f"{BASE}/memory/search", json={"query": "接口超时设置多少", "user_id": "user_001", "limit": 3}, timeout=60 ) print(resp.json())

调用时注意两点:一是超时时间别设太短,本地模型首 token 延迟可能到秒级;二是检索接口的limit不要贪大,3 到 5 条通常够用,给多了反而干扰模型判断。

7.2 批量导入设计

批量任务的核心不是“循环调用”,而是“可断点、可重试、可观测”。下面这份脚本把三件事都做了:

# batch_import.py import json import time import logging import requests logging.basicConfig( filename="batch_import.log", level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s" ) BASE = "http://127.0.0.1:8080" SOURCE = "./memory_input.jsonl" DONE = "./done_ids.txt" # 读取已完成的 id,支持断点续跑 try: with open(DONE, "r", encoding="utf-8") as f: done_ids = set(line.strip() for line in f if line.strip()) except FileNotFoundError: done_ids = set() def add_with_retry(text, user_id, retries=3): for attempt in range(1, retries + 1): try: resp = requests.post( f"{BASE}/memory/add", json={"text": text, "user_id": user_id}, timeout=90 ) if resp.status_code == 200: return True logging.warning("status=%s attempt=%s", resp.status_code, attempt) except Exception as e: logging.error("exception=%s attempt=%s", e, attempt) time.sleep(2 * attempt) return False with open(SOURCE, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line: continue item = json.loads(line) item_id = item["id"] if item_id in done_ids: continue ok = add_with_retry(item["text"], item["user_id"]) if ok: with open(DONE, "a", encoding="utf-8") as done_f: done_f.write(item_id + "\n") logging.info("success id=%s", item_id) else: logging.error("failed id=%s", item_id) # 简单限速,避免把推理服务打满 time.sleep(0.2)

输入文件格式:

{"id": "m001", "user_id": "user_001", "text": "项目使用 Python 3.10 作为运行时"} {"id": "m002", "user_id": "user_001", "text": "部署环境统一用 Ubuntu 22.04"}

这套设计的价值在于:任何一条失败都不会拖垮整批,重跑时直接跳过已完成的,日志里能定位到具体哪条出的问题。批量导入时建议先在 20 条的小样本上跑一遍,确认耗时和失败率,再放大到全量。如果全量有几千条,还得考虑分批提交,别一次性把向量库和推理服务同时压死。

8. 资源占用与性能观察方法

性能这块不给你编数字,只给你观察方法和影响因子。

显存占用怎么观察:Linux 下用nvidia-smi循环刷新,Windows 下用任务管理器的“专用 GPU 内存”或者nvidia-smi命令行。启动记忆服务、跑一次写入、跑一次检索,分别记录三个时间点的显存值,就能看出各组件的大致占比。

# 每秒刷新一次,观察推理过程中的显存波动 nvidia-smi --query-gpu=memory.used,memory.total,utilization.gpu --format=csv -l 1

CPU 推理和 GPU 推理的差别主要在延迟上。CPU 模式下写入和检索能跑,但单次请求可能要几秒到十几秒;GPU 模式下通常能压到秒级以内。如果你的场景是后台异步写入、用户侧只做检索,CPU 模式完全可以接受。

影响性能的几个关键因子:

  • 模型参数量与量化方式:这是最大变量,换模型比调参有效得多。
  • top_k取值:检索条数从 3 提到 20,向量库侧压力不大,但下游 LLM 的上下文变长,生成延迟会明显上升。
  • 批量写入的并发数:并发太高会把推理服务排队打满,反而更慢。建议串行加小间隔,或者用 2 到 4 个 worker。
  • 向量库索引参数:Qdrant 在小数据量下默认配置够用,数据量到十万级以上再考虑调 HNSW 参数。
  • Embedding 模型的上下文长度:单条记忆文本过长会被截断,截断后语义丢失,检索命中率下降。建议写入前就把单条压到几百字以内。

降低显存占用的常规手段:换更小的量化模型、把 Embedding 换成小参数量版本、降低并发、把向量库放到内存充足的机器上而把推理放到 GPU 机器上分离部署。最后这个方案在团队场景里很常见——向量库和推理服务本来就不该绑在一起。

进程残留是另一个常见坑。Docker 容器停了但端口没释放、uvicorn 用--reload起了多个子进程、Ollama 后台常驻占着显存,这些都会让下一次启动莫名其妙失败。养成习惯:改配置前先docker ps和端口检查走一遍。

9. 常见问题与排查方法

问题现象可能原因排查方式解决方案
启动报端口被占用上次进程未退出或容器残留lsof -i :端口或docker ps杀掉残留进程或换端口
写入接口返回成功但检索不到Embedding 调用失败导致静默写入失败查向量库 collection 条目数补日志,确认 Embedding 服务可用
检索结果跨用户串数据未传user_id或过滤条件失效用两个身份交叉检索验证检索强制带命名空间过滤
依赖安装报版本冲突全局环境混装检查pip list用独立虚拟环境重装
显存不足报 OOM模型过大或并发过高nvidia-smi观察峰值换量化模型、降并发、拆分部署
批量任务中途卡住单条超时未设上限查批量日志最后一条加超时、加断点、加重试
召回结果相关性差top_k过大或 Embedding 不适配中文缩小top_k看结果变化换中文效果更好的向量模型
重启后记忆全丢向量库未挂载数据卷检查容器挂载配置重新挂载持久化目录
删除后仍能召回只删了一侧数据分别查向量库和元数据补全删除逻辑
接口响应偶发超时推理服务排队看服务端日志时间戳加队列或提高超时阈值

排查顺序建议固定下来:先看服务是否真的起来了(端口、健康检查),再看单个组件能不能通(直接 curl 推理服务、直接查向量库),最后看编排层逻辑。绝大多数问题出在第一步和第二步,别一上来就怀疑代码写错了。

10. 最佳实践与使用建议

第一,先跑最小闭环,再上复杂逻辑。原文存储加检索这条链路能跑通,就已经能解决 80% 的“记不住”问题。事实抽取、冲突合并、摘要压缩这些是优化项,不是启动项。

第二,目录结构从一开始就分开。模型文件、配置文件、输入素材、向量库数据、日志,各放各的目录。等数据量上来再整理,迁移成本很高。尤其是向量库的数据目录,一定要挂载到宿主机,别留在容器内部。

第三,记忆写入前做一层过滤。不是所有对话都值得记。建议至少过滤三类:寒暄类无信息量的内容、包含敏感字段的内容、明显是模型自己生成而非用户陈述的内容。写入质量直接决定检索质量,垃圾进垃圾出在记忆系统里体现得特别明显。

第四,给记忆加时间维度和来源标记。每条记忆带上created_at、source、confidence,检索时按时间衰减加权。这样用户改变主意后,新记忆自然压过旧记忆,不需要手动清理。

第五,接口服务一定要限制访问范围。本地验证绑127.0.0.1,内网共享加鉴权和 IP 白名单,别图省事开成公网可访问。记忆库里存的东西,泄露一次的代价远高于省下的那点配置时间。

第六,合规动作前置。涉及个人信息、通话录音、聊天记录、客户资料的内容,写入前必须确认你有权处理;给他人做系统时,要能明确回答“数据存在哪、谁能访问、怎么删除”这三个问题。这已经不是技术问题,是能不能上线的门槛。

第七,建立回归测试集。准备 30 到 50 条固定的“问题—期望记忆”对,每次换模型、换 Embedding、调参数之后跑一遍,看召回率有没有下降。没有回归集,你根本不知道这次优化是变好还是变差。

最后说下一步可以往哪扩。跑通基础版之后,比较自然的三个方向是:把记忆层接到自己的 Agent 框架里做跨任务状态保持;加一层摘要压缩,把长对话定时聚成稳定事实;做一套记忆管理界面,让用户能看到、编辑、删除自己的记忆。这三个方向都不需要换技术栈,只是在现有闭环上加模块。

真要给个优先级,我建议先做第三个——可视化和可删除。因为一旦你能看见系统到底记了什么,前面那些检索不准、召回混乱的问题,很多会自己暴露出来,改起来也有的放矢。

返回列表