1. 项目概述:一个能记住对话的AI聊天机器人
最近在GitHub上看到一个挺有意思的项目,叫memUBot,来自NevaMind-AI这个组织。光看名字就能猜个大概——“记忆”和“机器人”的结合。没错,这玩意儿本质上是一个AI聊天机器人,但它的核心卖点,或者说它试图解决的核心痛点,是让AI拥有“记忆”能力。
我们平时用ChatGPT、Claude这类大模型聊天,最头疼的是什么?就是它记不住事儿。你让它帮你写个代码,改了三版,最后你说“还是用第一版吧,但把那个按钮颜色改成蓝色”,它很可能已经忘了第一版长啥样了。或者你跟它聊了半小时自己的项目背景、技术选型,然后问一个具体问题,它给你的回答可能完全脱离了之前半小时建立的上下文。这种“金鱼记忆”在需要连续、深度协作的场景下,体验非常割裂。
memUBot瞄准的就是这个问题。它不是简单地做一个聊天界面套个API,而是设计了一套机制,试图让AI能够理解、存储并在后续对话中主动回忆起与“你”(用户)相关的关键信息。你可以把它想象成一个数字化的、永远在线的、且记忆力超群的伙伴,它记得你的偏好、你的项目细节、你上次聊到哪儿了。这对于开发者、创作者、研究者,或者任何需要与AI进行长期、有上下文连续性的对话的人来说,吸引力是巨大的。
这个项目目前还处于比较早期的阶段,但从其架构设计和目标来看,野心不小。它不满足于做一个玩具,而是想成为未来人机交互中的一个基础组件。接下来,我就结合自己的经验,拆解一下这个项目的核心思路、技术实现可能遇到的坑,以及如果你也想动手做一个类似的“记忆型AI助手”,可以从哪里开始。
2. 核心思路与架构设计拆解
要让一个AI拥有“记忆”,听起来很科幻,但拆解开来,其实就是一套复杂的数据工程和提示词工程。memUBot的架构,我推测(基于常见的此类项目设计模式)会围绕以下几个核心模块展开。
2.1 记忆的存储:向量数据库是基石
AI模型本身(比如GPT-4)的参数是固定的,它无法动态写入新的长期记忆。因此,所有关于用户和对话的历史信息,都必须存储在模型之外。最主流、最高效的方案就是使用向量数据库。
为什么是向量数据库?传统数据库按关键字搜索,比如你问“我上周二提到的那个开源项目”,如果对话里没有“上周二”和“开源项目”这两个词精确匹配,就找不到了。但向量数据库不同,它存储的是文本的“语义向量”(即嵌入向量)。当你提出一个问题时,问题本身也会被转换成向量,然后在向量数据库里寻找“语义上最相似”的历史片段。即使你的提问方式和当初存储时的表述不同(例如,“我上次说的那个画图工具” vs. “之前讨论的用于生成图表的软件”),向量搜索也能大概率找到相关的记忆。
memUBot很可能会采用如ChromaDB、Pinecone、Weaviate或Qdrant这类专门的向量数据库。对于自托管和开源项目,ChromaDB因其轻量和易用性,可能是首选。
注意:向量数据库的选择不是拍脑袋定的。ChromaDB适合快速原型和中小规模数据;如果你的预期是海量用户和记忆条目,Pinecone或Weaviate的托管服务在性能和运维上更有优势,但会有成本。Qdrant则在性能和自定义距离度量上表现突出。需要根据项目规模和团队运维能力权衡。
2.2 记忆的生成:如何决定记住什么?
这是最具挑战性的部分。不可能也没必要记住每一句对话。想象一下,你和朋友聊天的每一句话都被逐字记录并反复提起,那将是灾难。“你好”、“吃了吗”这种信息毫无价值。我们需要的是摘要和关键信息提取。
memUBot需要一套“记忆生成策略”。我猜测其流程可能是这样的:
- 对话分割:将连续的对话流,按主题或时间窗口分割成有意义的“块”。
- 重要性评估:对每个“块”,使用AI模型(可能是一个较小的、专门调优的模型,或者就是主模型本身)进行评估,判断其是否包含需要长期记忆的信息。例如:
- 事实性信息:“我的项目用的是Python和FastAPI。”
- 偏好声明:“我不喜欢用递归函数,觉得难读。”
- 任务与承诺:“明天需要完成用户登录模块的代码。”
- 决策与原因:“选择SQLite而不是PostgreSQL,因为这是个轻量级原型。”
- 记忆格式化:将判定为重要的信息,从自然语言对话中,结构化地提取出来,并存储。例如,不是存储原句“我用FastAPI写后端”,而是存储类似
{"entity": "user", "attribute": "tech_stack", "value": "Python, FastAPI", "context": "project_backend"}的结构化数据。同时,原始对话的文本和其向量嵌入也会被存入向量库,用于基于语义的回忆。
2.3 记忆的召回:在何时以何种方式想起?
记忆存好了,怎么用?有两个关键问题:何时触发回忆和如何注入回忆。
触发时机:
- 显式触发:用户直接说“记得我之前说的XX吗?”。
- 隐式触发:这是体验好坏的关键。系统需要实时分析用户当前输入,通过向量相似度检索,自动找出可能相关的历史记忆。这里有一个权衡:召回太多无关记忆会干扰模型,召回太少则记忆形同虚设。通常需要设置一个相似度阈值,并且可能只取Top-K个最相关的记忆片段。
注入方式: 检索到的记忆不能直接扔给用户看,那样很生硬。标准的做法是,将当前问题+相关的记忆片段+系统指令,三者一起组合成最终的提示词,送给大模型(如GPT-4)去生成回答。系统指令会告诉模型:“以下是用户的一些历史背景信息,请你在回答时酌情参考这些信息。”这样,模型就能在生成回答时,自然而然地引用或基于这些记忆进行推理。
2.4 记忆的管理:更新、合并与遗忘
记忆不是一成不变的。今天我说“我最喜欢的颜色是蓝色”,明天我可能说“其实我现在觉得绿色更舒服”。一个好的记忆系统需要能更新记忆。 更复杂的是信息的合并。用户可能在多次对话中,零散地补充了同一个项目的细节。系统需要能识别这些信息属于同一个主题(例如“我的A项目”),并将它们合并成一份更完整、更一致的档案。 最后,还有遗忘。有些记忆可能过期了,或者被明确要求删除。系统需要提供相应的管理机制。在向量数据库方案中,这通常意味着从数据库中删除对应的向量和元数据条目。
3. 技术栈选型与实操要点
基于以上架构,我们可以勾勒出memUBot可能的技术栈,并讨论每个环节的实操要点。
3.1 后端框架与模型接入
框架选择: 对于Python技术栈,FastAPI几乎是当前AI应用后端的事实标准。它异步性能好,自动生成API文档,与Python的AI生态无缝集成。如果团队更熟悉Node.js,Express或NestJS也是不错的选择,但需要处理与Python AI库的通信(可能通过子进程或微服务)。
模型接入:
- 云端API:最快速的方式是接入OpenAI的GPT系列、Anthropic的Claude,或国内的一些大模型API。优点是稳定、能力强,缺点是持续产生费用,且数据需要出境(需考虑合规性)。
- 本地模型:为了数据隐私和成本控制,可以部署开源模型。例如,使用Ollama来本地运行Llama 3、Qwen等模型,或者使用vLLM、Text Generation Inference来部署更大型的模型。这需要较强的GPU硬件和运维能力。
实操心得:起步阶段强烈建议从云端API开始,快速验证核心的“记忆-回忆”逻辑。待流程跑通后,再考虑成本和数据隐私问题,逐步迁移到本地模型。直接上手本地模型,可能会在模型部署、调试上耗费大量精力,偏离项目核心目标。
3.2 向量数据库集成与优化
以ChromaDB为例,集成非常简单:
import chromadb from chromadb.config import Settings # 创建或连接到数据库 client = chromadb.PersistentClient(path="./chroma_db") # 获取或创建一个集合(类似于表),用于存储记忆 memory_collection = client.get_or_create_collection(name="user_memories")存储记忆时,需要生成文本的嵌入向量。你可以使用OpenAI的text-embedding-ada-002,或者开源的句子转换器模型,如all-MiniLM-L6-v2。
# 假设使用OpenAI的嵌入模型 from openai import OpenAI embed_client = OpenAI(api_key="your_key") def get_embedding(text): response = embed_client.embeddings.create(model="text-embedding-3-small", input=text) return response.data[0].embedding # 存储一条记忆 memory_text = "用户喜欢用Dark Mode主题编程。" memory_embedding = get_embedding(memory_text) memory_collection.add( documents=[memory_text], embeddings=[memory_embedding], metadatas=[{"user_id": "alice", "memory_type": "preference", "timestamp": "2023-10-01"}], ids=["memory_001"] )检索时:
def retrieve_memories(query, user_id, top_k=3): query_embedding = get_embedding(query) results = memory_collection.query( query_embeddings=[query_embedding], n_results=top_k, where={"user_id": user_id} # 过滤特定用户的记忆 ) return results['documents'][0] # 返回最相关的文本列表优化要点:
- 元数据过滤:务必为每条记忆添加丰富的元数据,如
user_id、session_id、memory_type(fact, preference, task)、timestamp。检索时通过where条件过滤,能极大提升准确性和效率。 - 嵌入模型一致性:存储和检索必须使用同一个嵌入模型,否则向量空间不一致,检索结果毫无意义。
- 分块策略:过长的文本块会导致嵌入质量下降。需要根据标点、句子或固定长度(如500字符)进行智能分块。对于代码片段,要按函数或逻辑块分割。
3.3 记忆生成策略的实现细节
这是项目的“大脑”。一个简单的实现可以基于现有大模型的函数调用能力。
- 定义记忆的“模式”。
memory_schema = { "name": "extract_user_memory", "description": "从对话中提取需要长期记忆的用户信息。", "parameters": { "type": "object", "properties": { "memory_statements": { "type": "array", "items": { "type": "object", "properties": { "information": {"type": "string", "description": "提取出的需要记忆的信息,用简洁完整的句子陈述。"}, "category": {"type": "string", "enum": ["personal_fact", "preference", "skill", "ongoing_task", "project_detail"], "description": "信息类别。"}, "confidence": {"type": "number", "description": "提取信息的置信度,0-1。"} }, "required": ["information", "category"] } } }, "required": ["memory_statements"] } }- 在每轮对话或每隔N轮对话后,将最近的对话历史发送给大模型,要求其根据模式进行提取。
- 对提取出的信息进行置信度过滤(例如,只保留
confidence > 0.7的),然后存入向量数据库。
踩坑记录:初期不要试图让模型一次从很长的历史中提取记忆,这容易导致信息遗漏或混淆。更好的做法是采用“流式”处理:每次用户发送新消息后,将“上一轮模型回答 + 本轮用户提问”这个配对作为一个分析单元,来判断其中是否产生了新的可记忆点。这样处理更及时,负担也更轻。
3.4 前端与交互设计考量
虽然memUBot可能主要提供API,但一个演示性的前端能极大提升体验。可以考虑使用:
- Streamlit:极速构建数据科学应用,适合快速原型。
- Gradio:专为机器学习模型设计,交互组件丰富,部署简单。
- 现代Web框架(React/Vue):如果需要高度定制化的聊天界面和记忆管理面板(如允许用户查看、编辑、删除自己的记忆),这是更专业的选择。
在前端,需要设计交互来体现“记忆”的存在:
- 记忆提示:当AI的回答引用了某条记忆时,可以在回答旁用一个不起眼的小图标提示,鼠标悬停可显示“根据您之前提到的XX信息”。
- 记忆管理页面:提供一个页面,以卡片或列表形式展示AI“记住”的关于用户的各项信息,并允许用户修正或删除。这至关重要,它赋予了用户控制感,并建立了信任。
4. 核心流程实现与代码剖析
让我们串联起上述模块,实现一个最简可用的memUBot核心流程。这里假设使用FastAPI后端和OpenAI的API。
4.1 系统初始化与配置
首先,定义核心的数据模型和配置。
# models.py from pydantic import BaseModel from typing import List, Optional from datetime import datetime class Message(BaseModel): role: str # "user" or "assistant" content: str class Conversation(BaseModel): user_id: str messages: List[Message] = [] updated_at: datetime = datetime.utcnow() class MemoryFragment(BaseModel): id: str user_id: str content: str # 记忆的文本内容 embedding: Optional[List[float]] = None category: str metadata: dict = {} created_at: datetime = datetime.utcnow() # config.py import os from dotenv import load_dotenv load_dotenv() class Config: OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") EMBEDDING_MODEL = "text-embedding-3-small" CHAT_MODEL = "gpt-4-turbo-preview" CHROMA_DB_PATH = "./chroma_db" MEMORY_COLLECTION_NAME = "user_memories"4.2 记忆的存储与检索服务
这是一个核心服务类,封装所有向量数据库操作。
# memory_service.py import chromadb from chromadb.config import Settings from openai import OpenAI from models import MemoryFragment import uuid class MemoryService: def __init__(self): self.client = chromadb.PersistentClient(path=Config.CHROMA_DB_PATH) self.collection = self.client.get_or_create_collection( name=Config.MEMORY_COLLECTION_NAME, metadata={"hnsw:space": "cosine"} # 使用余弦相似度 ) self.embed_client = OpenAI(api_key=Config.OPENAI_API_KEY) def _get_embedding(self, text: str) -> List[float]: """获取文本的嵌入向量""" response = self.embed_client.embeddings.create( model=Config.EMBEDDING_MODEL, input=text ) return response.data[0].embedding def store_memory(self, memory: MemoryFragment): """存储一条记忆""" if not memory.embedding: memory.embedding = self._get_embedding(memory.content) self.collection.add( documents=[memory.content], embeddings=[memory.embedding], metadatas=[{ "user_id": memory.user_id, "category": memory.category, **memory.metadata }], ids=[memory.id] ) def retrieve_relevant_memories(self, query: str, user_id: str, top_k: int = 5) -> List[str]: """检索与查询相关的用户记忆""" query_embedding = self._get_embedding(query) results = self.collection.query( query_embeddings=[query_embedding], n_results=top_k, where={"user_id": user_id} ) # results['documents'] 是一个列表的列表,如 [["mem1", "mem2"]] return results['documents'][0] if results['documents'] else []4.3 对话处理与记忆增强循环
这是主逻辑,处理一次完整的用户请求。
# chat_service.py from openai import OpenAI from memory_service import MemoryService from models import Conversation, MemoryFragment import json class ChatService: def __init__(self): self.openai_client = OpenAI(api_key=Config.OPENAI_API_KEY) self.memory_service = MemoryService() self.conversation_store = {} # 简单内存存储,生产环境需用数据库 def _extract_memories_from_turn(self, user_input: str, ai_response: str, user_id: str): """从最新一轮对话中提取记忆""" prompt = f""" 请从以下最新一轮对话中,提取出关于用户“{user_id}”的、值得长期记住的信息。 用户说:{user_input} 助手说:{ai_response} 请以JSON格式输出一个列表,每个元素是一个记忆对象,包含`information`(信息内容)和`category`(类别)字段。 类别可以是:personal_fact, preference, skill, ongoing_task, project_detail。 如果没有值得记忆的信息,输出空列表 []。 """ try: response = self.openai_client.chat.completions.create( model="gpt-3.5-turbo-1106", # 用便宜模型做提取即可 messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"} ) memory_data = json.loads(response.choices[0].message.content) memories = memory_data.get("memories", []) for mem in memories: memory_fragment = MemoryFragment( id=str(uuid.uuid4()), user_id=user_id, content=mem["information"], category=mem["category"] ) self.memory_service.store_memory(memory_fragment) print(f"已存储记忆: {mem['information']}") except Exception as e: print(f"记忆提取失败: {e}") def generate_response(self, user_id: str, user_message: str) -> str: # 1. 检索相关记忆 relevant_memories = self.memory_service.retrieve_relevant_memories(user_message, user_id) memory_context = "\n".join([f"- {mem}" for mem in relevant_memories]) if relevant_memories else "无相关记忆。" # 2. 获取当前对话历史(简化版,只保留最近5轮) if user_id not in self.conversation_store: self.conversation_store[user_id] = Conversation(user_id=user_id) conv = self.conversation_store[user_id] conv.messages.append(Message(role="user", content=user_message)) # 构建系统提示词,注入记忆 system_prompt = f"""你是一个有帮助的AI助手,并且你拥有关于用户的长期记忆。 以下是关于当前用户的一些背景信息(记忆): {memory_context} 请你在回答时,自然地参考这些记忆信息,使其回答更个性化、更连贯。 如果记忆信息与当前问题无关,则忽略它。 当前对话历史(最近几轮): {self._format_recent_messages(conv.messages[-10:])} # 只送最近10条消息,避免token超限 """ # 3. 调用大模型生成回答 try: response = self.openai_client.chat.completions.create( model=Config.CHAT_MODEL, messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_message} ], temperature=0.7 ) ai_response = response.choices[0].message.content except Exception as e: ai_response = f"抱歉,我遇到了一些问题:{e}" # 4. 将AI回答加入历史 conv.messages.append(Message(role="assistant", content=ai_response)) # 5. (异步)从最新一轮对话中提取新记忆 # 注意:这里为了简化是同步的,生产环境应放入后台任务队列 self._extract_memories_from_turn(user_message, ai_response, user_id) return ai_response def _format_recent_messages(self, messages): return "\n".join([f"{msg.role}: {msg.content}" for msg in messages])4.4 API端点暴露
最后,用FastAPI创建一个简单的API。
# main.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel from chat_service import ChatService app = FastAPI(title="memUBot API") chat_svc = ChatService() class ChatRequest(BaseModel): user_id: str message: str @app.post("/chat") async def chat_endpoint(request: ChatRequest): if not request.user_id or not request.message: raise HTTPException(status_code=400, detail="user_id and message are required") try: response = chat_svc.generate_response(request.user_id, request.message) return {"response": response} except Exception as e: raise HTTPException(status_code=500, detail=str(e)) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)现在,运行python main.py,一个具备基础记忆功能的聊天机器人API服务就启动了。你可以向http://localhost:8000/chat发送POST请求(Body:{"user_id": "alice", "message": "你好,我是Alice,我喜欢用Python做数据分析。"})进行测试。
5. 部署、优化与常见问题排查
让一个原型跑起来是一回事,让它稳定、可靠、高效地服务则是另一回事。
5.1 部署方案选择
- 本地/开发环境:如上所述,直接用
uvicorn运行。适合调试。 - 云服务器(VPS):使用Docker容器化你的应用。编写
Dockerfile和docker-compose.yml,将应用、ChromaDB等依赖打包。然后用Nginx做反向代理,Gunicorn(配合Uvicorn Worker)作为ASGI服务器处理并发。这是中小型项目最经典的部署方式。 - Serverless/容器平台:如果你想更省心,可以考虑Railway、Fly.io或Hugging Face Spaces。它们对Python应用和Docker支持友好,能自动处理扩缩容。但需要注意,ChromaDB的持久化存储在这些平台上可能需要额外配置(通常是挂载Volume)。
- Kubernetes:如果预期有非常大的用户量和复杂的微服务架构,可以考虑K8s。但对于大多数个人或小团队项目,过早引入K8s会带来巨大的运维复杂度,不推荐。
部署心得:第一个生产版本,强烈推荐Docker Compose + 一台靠谱的VPS(如Linode, DigitalOcean, 或国内的阿里云/腾讯云ECS)。这给了你完全的控制权,并且所有问题都有海量的社区解决方案。在
docker-compose.yml里,你可以定义两个服务:一个是你的memUBot应用,另一个是ChromaDB服务(如果它需要独立运行的话,但上述例子是嵌入式的,所以不需要)。
5.2 性能优化关键点
向量检索速度:
- 索引选择:ChromaDB默认使用HNSW索引,在速度和精度之间取得了很好平衡。对于千万级以下的向量数据量,通常没问题。
- 过滤先行:务必在元数据(
where子句)中做好过滤(如user_id)。先过滤,再在子集中做向量搜索,比全量搜索快几个数量级。 - 批量操作:存储记忆时,尽量批量
add,而不是单条插入。
大模型Token与成本控制:
- 上下文窗口管理:记忆上下文和对话历史都会消耗Token。需要设计一个优先级策略:最重要的记忆(如用户明确声明的偏好)和最近的对话优先放入上下文。可以设置一个总Token上限,采用类似“滑动窗口”的机制,淘汰最旧或最不相关的信息。
- 模型分级:像前面代码所示,记忆提取这种对创造力要求不高的任务,完全可以用更便宜的模型(如GPT-3.5-Turbo)。只有最终生成回答时,才使用能力更强的模型(如GPT-4)。
- 缓存:对频繁被检索的“热点”记忆,或者对相同问题的回答,可以考虑加入缓存层(如Redis),直接返回结果,避免重复调用昂贵的模型。
记忆质量优化:
- 去重:在存储记忆前,检查向量数据库中是否已存在高度相似(余弦相似度>0.95)的记忆,避免重复存储。
- 置信度与人工反馈:记忆提取的置信度阈值可以动态调整。更重要的是,结合用户反馈。如果用户对某个基于记忆的回答点了“踩”,那么触发这条回答的记忆片段,其权重或置信度应该被降低,甚至被标记为待审查。
5.3 常见问题与排查实录
在实际运行中,你几乎一定会遇到下面这些问题:
问题1:AI的回答完全忽略了检索到的记忆。
- 排查:首先检查系统提示词。是不是提示词里没有明确指令模型去“使用”记忆?比如,你的提示词是“以下是用户信息:...”,但模型可能认为这只是背景参考。尝试更强烈的指令,如“你必须参考以下关于用户的记忆来形成你的回答,这至关重要。”
- 检查记忆相关性:打印出检索到的记忆内容。它们真的和当前问题语义相关吗?可能是嵌入模型不合适,或者相似度阈值设得太低,召回了一堆无关记忆,反而干扰了模型。
- 检查Token长度:如果记忆上下文太长,被放在了上下文的末尾,模型可能会“忽略”它。尝试把记忆放在系统提示词中更靠前的位置。
问题2:记忆提取模块总是提取不出信息,或者提取错误。
- 排查:这是提示词工程问题。你的提取指令不够清晰。给模型更具体的例子(Few-shot Learning)。例如,在提取指令中附带两个示例:
示例对话: 用户:“我这个周末打算开始学React。” 助手:“很棒!React是前端流行的框架。” 应提取的记忆:[{"information": "用户计划在周末开始学习React。", "category": "ongoing_task"}] 用户:“我讨厌下雨天,它让我心情低落。” 助手:“我理解,阳光确实让人愉悦。” 应提取的记忆:[{"information": "用户讨厌下雨天,因为这会使其心情低落。", "category": "preference"}] - 调整模型:如果用了太弱的模型(如较小的开源模型),可能能力不足。换用更强大的模型(如GPT-4)进行提取,虽然成本高,但准确率提升后,可以再尝试用强模型的结果去微调一个较小的专用模型。
问题3:随着对话轮数增加,响应速度越来越慢。
- 排查:这通常是上下文膨胀导致的。每次都将全部历史对话发给模型,Token数线性增长,导致API调用变慢、成本飙升。
- 解决:实现对话总结功能。每隔一定轮数(如10轮),或者当历史Token数接近上限时,触发一个总结任务:让模型将之前的对话历史总结成一段精简的“摘要”,然后用这个摘要代替冗长的原始历史,作为新的上下文起点。这样既能保留关键信息,又能控制长度。
问题4:向量数据库检索返回的结果不准确。
- 排查:
- 嵌入模型:确认存储和检索使用的是同一个嵌入模型。不同模型产生的向量不在同一个空间,无法比较。
- 文本清洗:存储前对文本进行简单的清洗(去除多余空格、换行符、特殊字符)。用户输入和记忆文本的清洗方式要一致。
- 相似度阈值:默认返回Top-K个结果,但其中可能包含相似度很低的不相关结果。可以设置一个最低相似度阈值(如0.7),过滤掉低质量结果。
- 元数据滥用:不要把所有过滤条件都指望向量搜索。像
user_id、time_range这种精确匹配的条件,一定要用元数据过滤(where参数),这能极大缩小搜索范围,提升精度和速度。
问题5:如何处理冲突或变化的记忆?
- 场景:用户先说“我喜欢狗”,后来又说“我其实更爱猫”。
- 策略:这是记忆系统的进阶问题。一个简单的策略是时间戳优先:总是保留最新的记忆。在存储新记忆时,检查是否有同一类别(
category)且主题高度相似的旧记忆,如果有,可以将其标记为“过时”或直接删除。更复杂的策略可以引入“记忆强度”或“置信度”,通过用户交互(如确认、修正)来动态调整。
构建一个真正好用的memUBot,技术实现只是一半,另一半是对人机交互和心理的深刻理解。记忆应该是助手,而不是负担;它应该让对话更顺畅,而不是更诡异。这需要大量的测试、迭代和用户反馈。从这个小原型出发,你可以不断加入更多功能:记忆的分类管理、基于记忆的主动提问、多模态记忆(记住用户上传的图片或文档中的信息)等等。这条路很长,但每一步都让机器离“理解”我们更近一点。