如果只看应用层,很多 AI 智能体项目已经可以做多轮对话、调用工具、写代码片段,但一旦落到真实业务里,还是经常被吐槽“不靠谱”。问题往往不在模型本身,而在知识供给。模型再聪明,如果它回答问题时没有可靠的知识来源,没有长期记忆,没有可追溯的出处,那它就只是一个“看起来懂很多”的聊天窗口,不是一个真正可用的智能体。
“第二大脑”这个概念最近在技术社区被反复讨论,包括一些高质量技术播客也在用它来解释智能体知识架构的设计思路。它本质上不是让你多建一个知识库,而是给 AI 智能体搭一个可持续更新、可检索、可追溯、可遗忘的外部记忆系统。本文会从概念、架构、选型、代码实现到生产环境注意事项,完整拆解一套可落地的“第二大脑”构建方案。
读完你可以自己动手搭建一个最小可用的智能体知识底座,并知道下一步该往哪个方向优化。
1. 这篇文章真正要解决的问题
先看一组典型场景。你给智能体接入了企业内部的运维手册、产品文档和客服话术,结果用户问一句“订单超时应该怎么处理”,智能体回答得模棱两可,甚至把两个不同版本的流程混在一起。又或者你做了一个个人知识库助手,第一天效果不错,第二天发现它回答的还是旧版规则,因为文档更新了,但它不知道。
这些问题的根因不是模型能力不够,而是智能体缺少三样东西:
- 知识供给:模型训练时并不知道你的私有数据,也不会因为你临时丢给它一段话就“记住”。
- 记忆机制:智能体默认是无状态的,多轮对话之间不共享上下文,更不会长期记住用户的偏好和历史结论。
- 来源追溯:没有检索过程,模型只能凭概率生成内容,无法告诉用户“我这么回答是因为哪一份资料”。
这篇文章要解决的就是这三个问题。我会把“第二大脑”拆成知识层、索引层、记忆层三层架构,然后给出一个可以直接运行的示例,帮助你构建一个具备知识检索和长期记忆能力的 Agent。
如果你正在做客服机器人、企业知识问答、个人助理、文档阅读助手,或者只是想把 AI 接入自己的笔记系统,这篇文章都适合你。如果你只是想把文档丢给大模型然后祈祷效果好,那更值得读完,因为你会发现问题出在架构上,而不是提示词上。
2. 第二大脑到底是什么:从笔记工具到智能体基础设施
“第二大脑”最早的方向是个人知识管理,比如用笔记软件来组织工作记录、阅读笔记、项目文档,本质是“人脑的外部存储”。但你要让 AI 智能体也能用这套系统,要求就完全不一样了。
传统知识管理面向“人”,核心操作是分类、打标签、目录树;AI 智能体面向“程序”,核心操作是检索、匹配、组装上下文。人看文档时可以慢慢翻目录,Agent 不行,它需要在几百毫秒内从几万条知识里找到最相关的几条,并放到模型上下文里,让模型据实回答。
所以,智能体可用的“第二大脑”至少包含三层:
| 层级 | 作用 | 典型实现 |
|---|---|---|
| 知识层 | 存放原始内容:Markdown、PDF、数据库记录、API 返回 | 文件目录、对象存储、业务库 |
| 索引层 | 让知识可以被快速、语义化地搜索 | 向量数据库、关键词索引、混合检索引擎 |
| 记忆层 | 记录对话历史、用户画像、长期事实 | 会话存储、向量记忆库、KV 存储 |
很多人做智能体时只做了前两层,而且经常把“向量化 + 相似度检索”当成全部。但第二大脑要想真正“可用”,记忆层同样关键。没有记忆层,用户每次对话都是重新开始;没有知识层,Agent 就只能靠模型参数里那点通用知识硬撑;没有索引层,知识再多也只是“存着”,而不是“用得上”。
一个更直观的类比是:模型像是员工,第二大脑是这个员工的笔记本和档案柜。员工聪明不聪明是一回事,但他能不能快速查到正确的资料、能不能记住客户之前说过的话,决定了他能不能真正独立干活。
3. 技术选型:为什么需要向量数据库,而不是一张表
构建第二大脑时,最核心的存储选型是向量数据库。很多人不理解:为什么不能像传统业务系统一样,把文档存到 MySQL,再用 LIKE 或者全文索引去查?
因为文档检索不是精确匹配问题。你问“订单超时怎么办”,文档里可能写的是“超过支付时限未支付如何处理”,关键词完全不一致,但语义相近。传统 SQL 的 LIKE 查不到这种语义匹配;全文索引(如 Elasticsearch 的 BM25)能解决部分字面匹配问题,但对同义词、近义词、长句语义理解仍然有限。
向量检索的思路是把文本映射成高维向量,用余弦相似度或欧氏距离计算语义距离。它的价值在于:即使查询词和文档用词完全不同,只要语义相近,向量距离也会比较近,从而被检索出来。
实际工程里更推荐“混合检索”,即向量检索 + 关键词检索结合,再通过 RRF(Reciprocal Rank Fusion)等方式合并排序结果。原因也很简单:向量检索擅长语义相似,但遇到专有名词、代号、型号时容易翻车;关键词检索能精确命中“ABC-001”这种编号,但无法理解同义表达。两者互补。
3.1 常见向量存储方案对比
| 方案 | 部署方式 | 适合场景 | 备注 |
|---|---|---|---|
| Chroma | 本地轻量 | 个人知识库、原型验证 | 简单,Python 直接调用 |
| FAISS | 库 / 本地 | 中小规模向量检索 | 无内置持久化和过滤需要自己实现 |
| Qdrant | 单机 / Docker | 生产级混合检索 | 支持过滤、payload、BM25 实验功能 |
| Milvus | 集群 | 海量数据、高并发 | 运维成本高,适合团队使用 |
| pgvector | PostgreSQL 扩展 | 团队已有 PG 体系 | 与业务数据放在同一个库,便于事务 |
如果你只是学习和验证,Chroma 是最快的路径;如果要上生产,我更推荐 Qdrant 或 pgvector,因为它们在元数据过滤、数据更新和可观察性上更成熟。选型时不要只看向量检索性能,还要看事务、过滤、备份和权限控制能力,这些才是生产环境真正要命的点。
4. 环境准备与前置条件
本文示例以 Python 3.10+ 为基础,使用 OpenAI 的 Embedding 模型做向量化,使用 Chroma 做向量存储。其他 embedding 服务和向量库的接入方式是等价的,代码逻辑可以复用。
需要安装的依赖:
pip install openai chromadb python-dotenv如果你需要使用 PDF 解析,可以额外安装pypdf或pdfplumber,本文示例先用 Markdown 和 TXT 文件跑通流程。
准备一个项目目录:
second-brain/ ├── data/ # 原始知识文档目录 ├── scripts/ │ ├── chunking.py # 文本分块 │ ├── ingest.py # 摄取并写入向量库 │ ├── search.py # 检索模块 │ ├── agent.py # Agent 调用示例 │ ├── memory.py # 长期记忆示例 │ └── eval.py # 简单效果评估 └── index/ ├── chroma_db/ # 知识向量库 └── memory_db/ # 记忆向量库还需要配置 OpenAI API Key。建议放在环境变量或.env文件中,不要硬编码到代码里。
export OPENAI_API_KEY="your-api-key"注意:不同库、不同模型的 API 参数可能存在版本差异,如果运行时报参数错误,请以你安装版本对应的官方文档为准。本文代码演示的是通用思路,不绑定某个精确版本。
5. 知识摄取:把散落文档变成 AI 可用的数据
知识摄取是整个第二大脑的入口。这一步做不好,后面检索和生成都会出问题。摄取流程通常包括三件事:数据清洗、文本分块、向量化入库。
5.1 数据清洗与文本分块
原始文档里往往有大量噪音:页眉页脚、表格标记、重复模板、乱码换行。如果不清理,检索出来的片段可能是一堆没头没尾的垃圾。摄取前可以做一些基础清洗,比如去掉空行、压缩连续空白、过滤无意义字符。
分块为什么重要?因为模型上下文窗口有限,而一份文档可能几万字。直接把整份文档丢进上下文太浪费,检索时也无法精准定位。我们需要把文档切成适合检索的“知识块”。
分块没有一个万能参数。太短,语义不完整;太长,检索精度下降且占用上下文。经验上,中文场景里 300 到 800 个字符一个有重叠的块,是一个比较通用的起步范围。
下面是一个简单的递归分块示例:
# 文件路径:scripts/chunking.py import re from typing import List def split_text( text: str, chunk_size: int = 500, overlap: int = 50 ) -> List[str]: """ 简单的中文文本分块器: 1. 先把连续空白压缩成单空格。 2. 按固定窗口切块,尽量在句号处断开。 3. 相邻块之间保留 overlap 字符的重复内容,避免信息断裂。 """ text = re.sub(r"\s+", " ", text.strip()) if not text: return [] chunks: List[str] = [] start = 0 n = len(text) while start < n: end = start + chunk_size chunk = text[start:end] # 如果不是最后一块,尝试在中文句号处截断 if end < n: cut = chunk.rfind("。") if cut > chunk_size * 0.5: chunk = chunk[: cut + 1] end = start + cut + 1 chunks.append(chunk) start = max(end - overlap, start + 1) return chunks实际项目中,分块的策略往往需要结合结构化信息来设计。比如 Markdown 文档可以按##标题分块,PDF 可以按段落编号分块,表格可以每行单独成一个知识块并保留表头。不要指望一个通用函数解决所有格式。
5.2 向量化入库
分块完成后,把每个块交给 Embedding 模型转成向量,再写入向量数据库。这里每一步都要记录来源:哪个文件、哪个块、什么时间入库,这直接影响后续排查。
# 文件路径:scripts/ingest.py import glob import os import chromadb from openai import OpenAI from chunking import split_text DATA_DIR = "../data" DB_DIR = "../index/chroma_db" COLLECTION_NAME = "second_brain" EMBED_MODEL = "text-embedding-3-small" BATCH_SIZE = 64 client = OpenAI() # 读取 OPENAI_API_KEY 环境变量 chroma_client = chromadb.PersistentClient(path=DB_DIR) collection = chroma_client.get_or_create_collection(name=COLLECTION_NAME) def read_md_or_txt(path: str) -> str: with open(path, "r", encoding="utf-8") as f: return f.read() def collect_files() -> list: files = glob.glob(os.path.join(DATA_DIR, "**", "*.md"), recursive=True) files += glob.glob(os.path.join(DATA_DIR, "**", "*.txt"), recursive=True) return files def embed_batch(texts: list) -> list: resp = client.embeddings.create(model=EMBED_MODEL, input=texts) return [item.embedding for item in resp.data] def upsert_batch(ids, texts, metadatas): embeddings = embed_batch(texts) collection.upsert( ids=ids, embeddings=embeddings, documents=texts, metadatas=metadatas, ) def main(): files = collect_files() all_chunks = [] all_metas = [] all_ids = [] for fp in files: content = read_md_or_txt(fp) chunks = split_text(content) for idx, chunk in enumerate(chunks): all_chunks.append(chunk) all_metas.append({"source": fp, "chunk_idx": idx}) all_ids.append(f"{fp}::chunk::{idx}") if not all_chunks: print("没有找到需要入库的文档。") return for i in range(0, len(all_chunks), BATCH_SIZE): batch_ids = all_ids[i : i + BATCH_SIZE] batch_chunks = all_chunks[i : i + BATCH_SIZE] batch_metas = all_metas[i : i + BATCH_SIZE] upsert_batch(batch_ids, batch_chunks, batch_metas) print(f"已写入 {min(i + BATCH_SIZE, len(all_chunks))}/{len(all_chunks)} 个知识块") print("摄取完成。") if __name__ == "__main__": main()运行方式:
cd scripts python ingest.py这个脚本会在index/chroma_db目录下建立本地向量库。你可以先把几篇自己的 Markdown 文档丢进data/目录,然后跑一遍看看效果。
这里真正容易踩坑的是:重复运行ingest.py会造成数据重复或陈旧数据残留。所以脚本里使用了upsert,用稳定 ID 来表示同一个知识块。如果文档内容变了,同一个 ID 对应的向量会被更新;如果文档被删除,旧知识块仍然存在,需要额外的清理逻辑来解决。生产环境应记入增量变更状态,而不是无脑全量重跑。
6. 检索与 Agent 调用:让 Agent 学会“查资料”
知识入库只是第一步。第二大脑要真正对智能体可用,必须提供高效的检索接口。最基础的是语义检索:把用户问题转成向量,去向量库找最相似的知识块。
# 文件路径:scripts/search.py import os import chromadb from openai import OpenAI DB_DIR = "../index/chroma_db" COLLECTION_NAME = "second_brain" EMBED_MODEL = "text-embedding-3-small" client = OpenAI() chroma_client = chromadb.PersistentClient(path=DB_DIR) collection = chroma_client.get_or_create_collection(name=COLLECTION_NAME) def search(query: str, top_k: int = 5, source_filter: str = None): embedding = client.embeddings.create( model=EMBED_MODEL, input=[query] ).data[0].embedding kwargs = {} if source_filter: kwargs["where"] = {"source": source_filter} result = collection.query( query_embeddings=[embedding], n_results=top_k, **kwargs, ) return result调用后,返回的documents就是命中的知识块,metadatas里包含来源文件。这样答案有了出处,Agent 可以在回答中引用来源。
6.1 混合检索:向量检索不够时怎么办
纯向量检索偶尔会把语义相近但内容并不准确的片段排在前面。一个常见改进是混合检索:先用向量检索和关键词检索分别取 Top-K,再用 RRF 融合排序。
关键词检索可以用rank_bm25库实现,也可以接入 Elasticsearch。这里演示 RRF 的融合逻辑:
def rrf_fuse(vector_results, keyword_results, k=60): # vector_results 和 keyword_results 都是 [(doc_id, score)] 列表 fused = {} for rank, (doc_id, _) in enumerate(vector_results): fused[doc_id] = fused.get(doc_id, 0) + 1.0 / (k + rank + 1) for rank, (doc_id, _) in enumerate(keyword_results): fused[doc_id] = fused.get(doc_id, 0) + 1.0 / (k + rank + 1) return sorted(fused.items(), key=lambda x: x[1], reverse=True)这个技巧不需要训练模型,成本低,效果提升非常明显。如果你在真实项目中感觉“向量检索结果不靠谱”,优先检查是否做了混合检索和重排序,而不是急着换大模型。
6.2 通过 Function Calling 接入 Agent
有了检索函数,Agent 就可以把它当工具调用。当用户的问题需要知识库支持时,模型会先调用search工具,拿到材料后再组织回答。
# 文件路径:scripts/agent.py import json from openai import OpenAI from search import search TOOLS = [ { "type": "function", "function": { "name": "search_knowledge", "description": "在个人第二大脑知识库中检索与问题相关的知识片段", "parameters": { "type": "object", "properties": { "query": {"type": "string", "description": "需要检索的问题或关键词"}, "top_k": {"type": "integer", "description": "返回结果条数,默认 5"} }, "required": ["query"] } } } ] SYSTEM_PROMPT = """你是用户的智能助手。当问题需要知识库支持时,调用 search_knowledge 工具检索材料。回答时必须引用检索结果,并提供来源文件。如果没有检索到足够信息,要明确说不知道,不要编造。""" def ask(messages): client = OpenAI() for _ in range(5): resp = client.chat.completions.create( model="gpt-4o-mini", messages=messages, tools=TOOLS, ) msg = resp.choices[0].message messages.append(msg) if not msg.tool_calls: return msg.content for tc in msg.tool_calls: args = json.loads(tc.function.arguments) result = search(args["query"], args.get("top_k", 5)) docs = result["documents"][0] metas = result["metadatas"][0] if not docs: tool_content = "没有检索到相关内容。" else: sources = {m.get("source", "unknown") for m in metas} tool_content = "\n---\n".join(docs) tool_content += f"\n\n参考来源:{', '.join(sorted(sources))}" messages.append({ "role": "tool", "tool_call_id": tc.id, "content": tool_content, }) return "达到最大工具调用次数,未能完成回答。"使用起来非常简单:
messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": "订单超时应该怎么处理?"}, ] print(ask(messages))这段代码的关键点在于“工具结果回填”:模型调用工具后,我们拿到检索片段,再把片段作为tool消息返回给模型。模型基于检索片段继续生成回答。没有资料时,模型只能认怂说不知道,这正是我们希望它具备的“诚实”能力。
7. 记忆系统:第二大脑怎么记住“关于你的事”
知识库解决的是“世界知识”和“私有文档”的问题,记忆系统解决的是“长期关系”的问题。一个智能体如果每次对话都不记得用户是谁,不知道用户之前说过什么,那它仍然不可用。
记忆层可以分成两类:
- 会话记忆:当前对话过程中的上下文,通常放在模型的
messages列表里,也可以用缓存存储最近 N 轮。 - 长期记忆:跨会话持久化的事实,比如用户偏好、历史结论、项目背景,需要写入第二大脑,下次对话时再检索出来。
长期记忆的实现思路和知识库几乎一样,只是存储的内容从“文档”变成了“事实”。比如用户说“我习惯早上十点开会”,你把它向量化后写入记忆库,元数据带上用户 ID。下次用户问“今天怎么安排”,Agent 检索后就能结合记忆给出个性化回答。
# 文件路径:scripts/memory.py import os import time import chromadb from openai import OpenAI MEMORY_DB = "../index/memory_db" MEMORY_COLLECTION = "user_memory" EMBED_MODEL = "text-embedding-3-small" client = OpenAI() chroma_client = chromadb.PersistentClient(path=MEMORY_DB) collection = chroma_client.get_or_create_collection(name=MEMORY_COLLECTION) def save_memory(user_id: str, fact: str): embedding = client.embeddings.create( model=EMBED_MODEL, input=[fact] ).data[0].embedding memory_id = f"{user_id}::{int(time.time() * 1000)}" collection.upsert( ids=[memory_id], embeddings=[embedding], documents=[fact], metadatas=[{ "user_id": user_id, "time": int(time.time()), }], ) def recall_memory(user_id: str, question: str, top_k=3): embedding = client.embeddings.create( model=EMBED_MODEL, input=[question] ).data[0].embedding result = collection.query( query_embeddings=[embedding], n_results=top_k, where={"user_id": user_id}, ) return result["documents"]长期记忆有一个被忽略的风险:记忆也会过期。用户去年喜欢的东西,今年不一定还喜欢。如果只写不删,Agent 会把过时信息当最新事实。因此记忆系统同样需要“遗忘机制”。比较简单的做法是给每条记忆打时间戳,检索时按时间衰减排序;更复杂的做法是引入事实版本管理,当发现新旧记忆冲突时,以新为准。
8. 运行验证与效果评估
很多人做了一个 RAG 系统后,不知道怎样才算“建好了”。我的建议是不要只看一两个例子“效果不错”,要建立一套可重复的评估流程。
最基本的评估是“检索命中率”:预先准备一组问题,每个问题关联期望命中的知识块关键词,检索后检查 Top-N 结果中是否包含这些关键词。
# 文件路径:scripts/eval.py from search import search GOLDEN_SET = [ { "question": "第二大脑的数据摄取流程是什么?", "expected_keywords": ["分块", "向量库", "embedding"], "top_k": 3, }, { "question": "Agent 如何访问知识库?", "expected_keywords": ["检索", "Function Calling", "工具"], "top_k": 3, }, ] def hit_rate(docs, keywords): hit_count = 0 for doc in docs: if any(k in doc for k in keywords): hit_count += 1 return hit_count / len(docs) def main(): for item in GOLDEN_SET: result = search(item["question"], top_k=item["top_k"]) docs = result["documents"][0] rate = hit_rate(docs, item["expected_keywords"]) print(f"问题:{item['question']}") print(f"命中率:{rate:.2f}") print("---") if __name__ == "__main__": main()如果你的知识库里根本没有这些测试问题的答案,命中率低是正常的。评估集必须基于你真实入库的内容来构建,而不是拿一个“题库”硬套。
更完整的效果评估还需要关注四个维度:
| 维度 | 含义 | 建议方法 |
|---|---|---|
| 检索命中率 | 检索结果里是否包含相关材料 | Golden Set + Top-N 命中判断 |
| 回答正确性 | 最终回答是否准确 | 人工抽检 + 可扩展为 LLM-as-Judge |
| 幻觉率 | 回答是否包含知识库没有的信息 | 比对回答与检索材料是否一致,检查是否有“无中生有”的内容 |
| 响应时延 | 检索 + 生成耗时是否可接受 | 观察 p95 时延,优化分块和索引 |
生产环境应该把评估流程脚本化,每次调整分块策略、换 Embedding 模型、改提示词之后,都跑一遍评估集,用数据判断方向对不对,而不是凭感觉调参。
9. 常见问题与排查思路
下面是构建“第二大脑”过程中最常遇到的问题,整理成一张排查表。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
摄取时报错,找不到chromadb模块 | 依赖没有安装,或虚拟环境未激活 | 运行pip list查看已安装包 | 执行pip install chromadb,确认虚拟环境激活 |
| 调用 OpenAI API 报 401 | API Key 无效或未设置环境变量 | 打印OPENAI_API_KEY是否为空 | 重新配置环境变量或检查 Key 权限 |
| 检索结果明显不相关 | 分块过大或过小,Embedding 模型不适合 | 打开几个知识块看内容是否完整 | 调整分块大小和重叠度,尝试更强的 Embedding 模型 |
| 中文问题检索效果差 | 分块在句子中间切断,语义不完整 | 调出documents检查知识块开头结尾 | 按标题、段落、句号切分,增加 overlap |
| Agent 回答不引用资料 | 系统提示词没有强调引用来源 | 检查最终回答和工具调用日志 | 在系统提示中强制要求,同时把来源写入回填内容 |
| 文档更新后 Agent 仍回答旧内容 | 增量摄取没做,或旧文档还在向量库中 | 查看向量库中该来源全部 ID | 实现基于 ID 的更新和删除,维护文档版本号 |
| 可能存在记忆污染 | 写入了过时或错误的用户事实 | 检查记忆库最近写入记录 | 增加时间戳和来源,定期清理过期记忆 |
| 检索速度越来越慢 | 向量库数据量增长,无索引优化 | 查看查询时延和向量库规模 | 评估是否需要换 Qdrant/Milvus,或增加集合分区 |
这里要特别提醒:当你遇到“回答质量差”时,不要第一反应是换更大的模型。先看检索结果。如果检索到的知识块本身就不相关,换再大的模型也只能基于错误材料生成错误答案。
10. 最佳实践与工程建议
从一个小 Demo 走到生产环境,需要补上的不只是代码,还有一系列工程约束。
10.1 知识文档要有版本意识
第二大脑里的“知识”是会过期的。建议给每个知识源维护版本号或更新时间,摄取时比较版本变化,只对变更的部分做增量更新。否则全量重跑既慢又容易把错误数据反复写入。
10.2 权限与数据边界要提前设计
向量库里的知识可能包含隐私数据。接入 Agent 时,一定要按用户或部门做数据隔离。Chroma、Qdrant、pgvector 都支持元数据过滤,检索时强制带上租户 ID 条件,避免数据越权访问。生产环境必须遵守最小权限原则,开发阶段也不能把敏感数据全部塞进一个共享索引。
10.3 用检索日志诊断问题
给检索接口加日志:记录查询词、Top-K 结果、来源文件、用户最终反馈。日志是优化第二大脑最重要的数据资产。没有日志,你就无法判断是分块问题、检索问题还是提示词问题。
10.4 建立人工反馈闭环
在 Agent 回答下方加“有帮助 / 无帮助”按钮,把反馈回流到评估集。这个成本很低,但价值极高。用户点“无帮助”时,记下当前问题和回答,每周集中分析一次,往往能找到系统的结构性缺陷。
10.5 不要把所有内容都向量化
不一定所有知识都适合放进向量库。结构化很强的数据(项目配置、价格表、工单规则)更适合用数据库查询或代码逻辑处理。第二大脑应该是“多种工具的集合”,而不是“所有内容往向量库塞”。
11. 总结与后续学习方向
回到标题:“如何构建第二大脑,让 AI 智能体可用”。核心判断可以浓缩为一句话:智能体的可用性,取决于它能不能在正确的时间,查到正确的知识,并记住用户关键信息。模型决定天花板,知识架构决定地板。
本文给出了一个最小闭环:文档清洗与分块,向量化入库,混合检索,Function Calling 接入,以及长期记忆和评估方案。你可以先用自己的几篇文档跑通这个流程,然后把文档规模扩大,再逐步替换为更成熟的向量数据库。
下一步可以沿着三个方向深入:
- 知识增强:把简单的向量检索升级为“向量 + 关键词 + 重排序”的组合检索,提高精度。
- 记忆框架:参考行业里成熟的 Agent 记忆框架设计,实现记忆分层、冲突消解和遗忘机制。
- 评测工程:把黄金集、离线评测、线上反馈串成一套持续评估流水线,让每次改动都有数据支撑。
最后提醒一句:别急着调模型提示词,先把检索链路和记忆链路做扎实。你给 Agent 一个干净、可追溯、能持续更新的第二大脑,它才会真正值得被放进业务里使用。