尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Hermes框架:为AI Agent接入跨会话记忆与反思机制

Hermes框架:为AI Agent接入跨会话记忆与反思机制 在 AI Agent 的实际开发里“记忆”往往是功能上线后才暴露出来的问题。模型本身能处理上下文但上下文窗口有限而且每次对话结束后模型对之前说过的事实几乎没有任何驻留认知。Hermes 这类智能体框架之所以被越来越多团队关注正是因为它在基础对话能力之外提供了 Mnemosyne 与 Hindsight 两套记忆机制前者负责长期事实存储后者负责对输出结果进行事后反思。本文会用完整示例带你把这两套机制接入一个可运行的最小 Agent并验证跨会话记忆是否真的生效。1. 先理解 Hermes 的记忆体系Mnemosyne 是什么Hindsight 又是什么1.1 AI Agent 为什么需要两套记忆一个普通的聊天机器人只需要把用户最近几条消息放进上下文就能完成大部分问答。但 AI Agent 一旦进入真实工作场景比如辅助写代码、做数据分析、维护客户信息它面对的就不再是一问一答而是一个持续多天的任务流。用户可能在第 1 天告诉 Agent“我们项目使用 Python 3.11”第 5 天又问“刚才说好的依赖版本是多少”。如果 Agent 没有长期记忆第 5 天的回答只能靠猜。问题到这里还没有结束。假设 Agent 在第 1 天给出过一个冗长且不准确的回答第 2 天它又遇到了类似的提问。只保留长期事实记忆并不能帮助它改进回答质量因为它并不知道自己上次的表现如何。于是需要在“事实记忆”之外再增加一层“对输出的反思记忆”。这也正是 Hermes 生态中 Mnemosyne 和 Hindsight 被设计出来的原因。1.2 Mnemosyne把“事实”变成可召回的结构化记忆Mnemosyne 这个名字来自希腊神话中的记忆女神从这个命名可以看出它负责的核心是长期记忆。在 Hermes 的设计里Mnemosyne 不是简单地把聊天记录原样存下来而是把用户说过的话、Agent 内部产生的临时结论、外部系统返回的数据经过抽取和向量化后保存成可检索的记忆片段。每个记忆片段通常包括文本内容一段可以被模型阅读的自然语言。元数据用户 ID、会话 ID、创建时间、来源类型。向量表示用于语义相似度召回。重要度或过期时间用于控制记忆的保留优先级。它的价值在于“按需召回”。模型不需要把所有历史记录都塞进上下文只需要在与当前问题语义相关时把最相关的几条记忆取出来。这既节省 token也能减少无关信息对模型回答的干扰。1.3 Hindsight在回答完成之后生成反思记忆Hindsight 的意思是“事后之明”它处理的是已经发生过的对话。Agent 每完成一次回答Hindsight 会根据对话记录生成一条反思例如用户真正想要的是什么。刚才的回答是否完整是否忽略了约束条件。下次遇到类似问题应该采用哪些步骤。哪些信息需要进一步确认。与 Mnemosyne 不同Hindsight 保存的不是事实本身而是“关于这次回答的经验教训”。反思的结果也会被写入记忆库只不过在检索时通常使用单独的命名空间或标签避免与用户事实混在一起。这样当下一次对话触发相似问题时Agent 可以带着上次的教训来回答而不是重新踩同一个坑。1.4 两套记忆在完整对话链路中的位置可以把一次带记忆的对话过程拆成以下几个阶段用户输入一条消息。Agent 把用户消息交给 Mnemosyne做语义召回。Agent 将召回结果拼入系统提示或上下文。模型根据上下文生成回答。Agent 把用户消息和模型回答交给 Hindsight。Hindsight 判断是否需要生成反思记录。反思记录写回记忆库供后续会话使用。整个流程可以理解为“先查记忆再生成回答再沉淀经验”。Mnemosyne 管的是“记得什么”Hindsight 管的是“学到的经验”。两个模块在流程上互补数据上都归 Hermes 的记忆接口统一管理。2. 环境准备先确认运行方式再安装 Hermes2.1 学习环境与生产环境的最小要求在开始安装之前先搞清楚你的运行环境。Hermes 相关的社区项目在迭代中变动较快不同分支对 Python、Node.js 或 Docker 的依赖并不相同。本文以 Python 版本的调用方式为例示例代码只负责说明实现思路落地时请以你实际拿到手的分支文档为准。环境建议配置说明学习环境4 核 CPU、8GB 内存只跑对话和记忆演示使用本地 SQLite 存储开发环境4 核以上、16GB 内存需要同时启动 Hermes Agent 和 Hermes Studio 调试界面生产环境8 核以上、32GB 内存或容器集群需要增加 Redis、对象存储、监控日志和模型服务集群如果只是验证记忆机制不推荐一开始就上 Docker Compose。原因是 Hermes 相关组件仍在快速更新先跑通命令行版本能更快定位问题。生产环境再考虑容器化部署反而更稳妥。2.2 安装 Python 基础环境建议使用 Python 3.10 或 3.11并创建独立虚拟环境避免污染系统 Python。python3.11 -m venv .venv source .venv/bin/activate python -m pip install --upgrade pip不同操作系统下命令略微不同。Windows 用户使用.venv\Scripts\activate激活虚拟环境。安装前可以先用python --version确认版本因为 Hermes 的部分依赖对 Python 3.12 的兼容性还不稳定。2.3 获取 Hermes 核心包克隆或下载 Hermes 项目后进入项目目录安装依赖。由于本文不绑定具体仓库地址命令中使用占位符git clone hermes 项目仓库地址 cd hermes pip install -e .执行完成后运行以下命令确认 CLI 可用hermes --version如果提示找不到命令可能是当前 Python 环境的bin目录没有加入 PATH。可以改用python -m hermes --version或者检查虚拟环境是否已经激活。注意不要因为hermes --version能输出版本号就认为所有功能已经可用。下一步配置模型后端时如果连不上模型服务版本号再漂亮也跑不出对话。2.4 配置 OpenAI 兼容的模型后端Hermes 的对话生成能力通常依赖一个模型推理服务。这里选择 OpenAI 兼容接口因为它被广泛支持DeepSeek、通义、Kimi 等厂商都提供类似接口也可以用本地部署的 vLLM 服务。下面是一个最小配置示例{ model_backend: openai-compatible, model_name: deepseek-chat, api_base: https://api.example.com/v1, api_key: your-api-key, temperature: 0.7 }把api_base换成你实际使用的服务地址model_name换成目标模型名称。这里不指定具体厂商因为不同的模型名称和价格策略都会影响后续 credits 消耗。2.5 初始化项目目录和日志建议在项目根目录建立以下结构hermes-demo/ ├── config/ │ └── hermes.json ├── memory/ │ ├── mnemosyne.db │ └── hindsight.db ├── logs/ │ └── hermes.log └── scripts/ └── demo_chat.py日志是排错的重要依据。生产环境中日志级别建议设置为INFO开发调试时设置为DEBUG。第一次启动前先确认logs目录存在且当前用户有写权限否则启动后可能只看到内存报错却不知道日志没有落盘。3. 配置 Mnemosyne 长期记忆让 Agent 记住跨会话事实3.1 设计记忆存储为什么建议先用 SQLiteMnemosyne 需要保存文本、向量和元数据。学习阶段使用 SQLite 加一个向量列就足够不需要单独引入向量数据库。原因是记忆量小的时候全表扫描加余弦相似度计算完全能接受等记忆量超过几十万条再迁移到专用的向量数据库例如 Qdrant 或 Milvus。过早引入重型组件只会增加排错难度。以下是 Mnemosyne 在 SQLite 中常见的表结构CREATE TABLE memory ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT NOT NULL, content TEXT NOT NULL, metadata TEXT, embedding BLOB, score REAL DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, expires_at DATETIME );content存放可读文本embedding存放向量表示的序列化结果metadata用 JSON 存放来源、标签等信息。user_id字段非常关键多用户场景下必须用它隔离记忆否则用户 A 的记忆会被用户 B 召回。3.2 初始化记忆库与第一个写入在 Hermes 中Mnemosyne 通常会提供一个 Python 客户端。下面的示例代码说明如何创建存储目录并写入一条记忆from hermes.memory import Mnemosyne mnemosyne Mnemosyne( storage_path./memory/mnemosyne.db, default_user_iduser_001, embedding_modeltext-embedding-3-small, ) mnemosyne.add( content用户是后端开发工程师技术栈是 Python 3.11 和 FastAPI, metadata{source: conversation, topic: user_profile}, ttl_days90, )ttl_days指定 90 天后过期避免长期积累无用的陈旧记忆。embedding_model用于把文本转成向量。注意如果使用云端 embedding 模型每一次add和search都会产生 API 调用费用这在本地开发时容易被忽略。3.3 实现基于语义相似度的召回召回是 Mnemosyne 最核心的操作。常规做法是把用户当前消息向量化然后计算与记忆中向量的余弦相似度返回得分最高的几条。hits mnemosyne.search( query用户的职业和主要技术栈是什么, user_iduser_001, top_k5, score_threshold0.3, ) for hit in hits: print(hit.score, hit.content)当查询与记忆语义接近时返回结果里应该出现“后端开发工程师”这条记录。这里的关键参数是score_threshold。设置过低会召回很多不相关内容设置过高则可能漏掉有效记忆。比较稳妥的做法是先设成 0.3再根据测试结果逐步调整。3.4 召回参数top_k、score_threshold 与 ttl参数默认值建议作用设置过高设置过低top_k5最多召回条数上下文变长token 消耗增加可能漏掉关键记忆score_threshold0.3相似度门槛有效记忆被过滤无关内容混入ttl_days90记忆有效期陈旧信息长期保留重要事实过早失效这里的参数会直接影响对话质量和成本。生产环境建议把 top_k 控制在 3 到 8 之间score_threshold 需要结合 embedding 模型的分布实测。3.5 常见问题为什么明明写入了却召回不到比较常见的原因有三个一是查询语句与记忆内容的语义向量不匹配比如记忆是“后端开发工程师”查询是“你的工作是什么”如果 embedding 模型对同义表达不敏感得分就会偏低二是score_threshold设置过高三是user_id不一致写入时是user_001查询时传了user_002。排查时先打印相似度分数确认是语义问题还是过滤问题。4. 配置 Hindsight 反思记忆让 Agent 从错误中学习4.1 反思与长期记忆的区别Hindsight 产生的是经验性知识而不是事实性知识。事实性知识“用户使用 Python 3.11”来自 Mnemosyne经验性知识“遇到版本兼容性问题时应该先检查依赖锁定文件”来自 Hindsight。两者都会影响模型回答但来源完全不同。Hindsight 的工作方式是在一次回答结束后把用户消息和模型回答放进模板调用一次模型生成反思总结再把总结存入单独的存储表。它的价值在于持续迭代。Agent 可以根据上次回答的教训在当前回答中主动调整策略。4.2 触发方式回答结束、指定关键词、主动调用Hindsight 不需要每次对话都执行否则 credits 消耗会明显上升。常见的触发方式有三种触发方式场景优点缺点on_response_finish每次回答结束后不会遗漏改进点消耗较多 API creditskeyword_match命中“再试一次”“方案不行”等关键词成本可控可能漏掉未被关键词表达的问题manual_call由用户或上层流程手动触发最省成本依赖外部判断在演示阶段推荐使用on_response_finish因为可以尽快看到反思记录。生产环境则建议切换到关键词或手动触发。4.3 配置反思模板和存储下面是一个 Hindsight 的 YAML 配置示例hindsight: enabled: true trigger: on_response_finish model_name: deepseek-chat store_path: ./memory/hindsight.db reflection_template: | 请对下面的对话进行反思输出两条结论 1. 这次回答可能存在什么不足。 2. 下次遇到类似问题应该怎么做。 用户问题{question} 模型回答{answer} 请用简洁中文输出不超过 200 字。存储表和 Mnemosyne 类似但会多一个category字段用来标记这是一条reflection。实际写入时可以继续使用同一套向量存储只通过元数据区分类型。4.4 一个最小反思记录示例假设用户的问题是“请帮我写一个 Python 脚本读取 CSV 文件”模型回答时没有处理文件不存在的情况。Hindsight 生成的反思记录可能如下{ category: reflection, content: 用户很可能需要可直接运行的脚本回答中缺少异常处理和编码说明。下次遇到文件读写问题先补充 FileNotFoundError 处理和 encoding 参数。, question: 请帮我写一个 Python 脚本读取 CSV 文件, answer_preview: 可以使用 pandas.read_csv..., created_at: 2025-01-01T12:00:00Z }这条记录以后会被召回作为解决同类问题的经验提示。5. 把记忆模块接入 Hermes Agent 主流程5.1 重点先读后写再反思把 Mnemosyne 和 Hindsight 接入 Agent 后代码复杂度并不高真正重要的是顺序。必须先在生成回答前读取 Mnemosyne再把召回结果放入上下文回答完成后再触发 Hindsight。如果顺序反了Agent 将基于“没有记忆”的上下文回答反思也只是对糟糕输出的再一次记录。5.2 核心代码记忆版 chat 方法下面是一段最小可运行的核心逻辑from hermes import HermesAgent from hermes.memory import Mnemosyne, Hindsight class MemoryChatAgent: def __init__(self, config): self.agent HermesAgent(config) self.memory Mnemosyne(config[mnemosyne_path]) self.hindsight Hindsight(config[hindsight_path]) def chat(self, user_id, user_message): # 1. 召回记忆 memories self.memory.search(user_message, user_iduser_id, top_k5) context \n.join([m.content for m in memories]) # 2. 召回反思经验 reflections self.memory.search( user_message, user_iduser_id, top_k2, metadata_filter{category: reflection}, ) if reflections: context \n\n历史经验\n \n.join(r.content for r in reflections) # 3. 生成回答 response self.agent.generate( user_message, system_contextcontext, ) # 4. 记录事实 self.memory.add( contentf用户问题{user_message}, metadata{category: conversation, user_id: user_id}, ) # 5. 反思 self.hindsight.record( questionuser_message, answerresponse, user_iduser_id, ) return response这段代码体现了一个完整的记忆闭环先召回再生成后写入最后反思。实际项目中你还需要处理generate失败、模型返回空内容、重复记忆合并等问题但主链路可以按这个顺序扩展。5.3 通过 Hermes Studio 或日志观察记忆状态如果 Hermes 生态提供了 Studio 或 Desktop 类工具它们通常可以展示当前 Agent 的记忆列表、相似度得分和反思记录。在没有图形界面的服务器上最直接的方式是查看日志tail -f logs/hermes.log日志中应能看到类似memory recall: hit_count5, top_score0.82的记录。看到这类记录说明记忆召回流程确实执行了而不是只把记忆存进了数据库。5.4 关于 credits 消耗需要提前算清楚很多 AI 服务用 credits 计量模型调用费用。一次带记忆的对话通常包含三类模型调用调用类型用途是否每次都有Embedding将输入文本向量化几乎每次召回写入都有Chat completion生成最终回答每次都有Reflection completion生成反思总结取决于触发策略长文本 embedding 会消耗较多 credits。建议先统计一次对话平均消耗再设置每日或每用户的 credits 阈值。如果发现消耗过高优先降低top_k或者把 Hindsight 的触发方式从每次回答改成关键词触发。5.5 Skill 扩展让记忆模块跟随技能组合使用Hermes 生态中另一个常见概念是 Skill即把某个领域的提示词、工具函数和记忆规则打包成一个可复用技能。Mnemosyne 和 Hindsight 都可以作为 Skill 的组成部分。例如一个“代码审查 Skill”可以在 Mnemosyne 中保存项目的编码规范在 Hindsight 中记录上次审查遗漏的问题类型。这样设计可以让记忆不局限于单个对话而是跟技能绑定便于复用到多个项目。6. 运行验证用三个场景证明记忆真正生效6.1 场景一跨会话记住用户身份第一个验证对应 Mnemosyne 的核心能力跨会话记忆。先运行第一次对话agent.chat(user_001, 我是一名后端开发工程师喜欢简洁的技术文章。)然后模拟一个全新会话只输入查询agent.chat(user_001, 你知道我的职业吗)预期输出中应包含“后端开发”相关描述。如果回答是“不知道”说明 Mnemosyne 写入成功但召回失败需要检查user_id或score_threshold。6.2 场景二反思后输出风格发生变化第二个验证对应 Hindsight 的效果。先输入一条需要改进的对话让 Hindsight 生成反思agent.chat(user_001, 请解释一下什么是 Python 装饰器尽量详细。)此时模型可能输出很长的解释。等 Hindsight 写入反思后再次输入agent.chat(user_001, 请再解释一下什么是 Python 装饰器。)如果反思记录提示“上次回答过于冗长用户希望简洁”第二次回答就应该更简短。如果没有变化需要检查 Hindsight 是否有反思记录被召回。6.3 场景三限定领域召回减少无关记忆干扰第三个验证检验记忆隔离。给同一个用户写入两条不同领域的记忆然后只针对其中一个领域提问看召回结果是否会混入另一个领域。agent.memory.add(用户正在开发一个在线支付系统, metadata{tag: project}) agent.memory.add(用户最近在学吉他, metadata{tag: hobby})查询“支付系统用什么数据库比较好”时不应召回“学吉他”这条记录。如果混入了说明需要利用metadata_filter按标签过滤。6.4 验证结果判定表测试场景预期结果通过标准跨会话记忆新会话能回答用户职业回答中出现“后端”或“开发”反思记忆第二次回答更简洁回答字数明显减少领域隔离只召回相关项目记忆无吉他、音乐等无关内容三个场景全部通过说明记忆模块已经真正接入主流程而不是只停留在“能写入数据库”层面。7. 常见问题排查从现象定位问题而不是靠猜测7.1 记忆写入了但新会话没有召回现象数据库里能查到记忆但下次对话回答中没有相关内容。可能原因和检查顺序检查user_id是否一致。写入和查询必须使用同一个用户标识。检查score_threshold。打印召回结果的相似度得分看是否低于阈值。检查 embedding 模型是否稳定。不同模型的向量分布差异很大调低阈值后重新测试。检查是否在生成回答时把召回结果拼入了上下文。如果没有拼入召回成功也不会影响回答。7.2 Hindsight 一直没有产生反思记录现象日志中没有reflection generated数据库中没有新的反思记录。排查路径确认enabled是否为true。确认触发方式。如果使用的是keyword_match检查关键词是否包含当前提问。确认反思模型配置是否正确。反思过程需要单独调用一次模型接口接口失败会静默跳过或写入错误日志。确认回答为空。如果模型返回空字符串Hindsight 可能因没有有效回答而放弃反思。7.3 模型接口报 401、429 或 timeout错误常见原因处理方式401API key 错误检查配置中的 api_key 是否有多余空格429请求频率超限或 credits 不足降低并发检查账户余额timeout模型响应过慢增大请求超时时间或切换更快的模型7.4 中文语义召回效果差中文和英文在向量空间中的表现差异较大。如果“用户问题”和“记忆内容”用词完全不一致相似度可能很低。改进方法包括在写入记忆时增加关键词标签。在查询时先用大模型做一次意图改写再执行向量检索。调整score_threshold以实际测试分数为准。把中文文本统一做同义改写后再存储。7.5 排错顺序与常用检查命令不要一开始就怀疑框架有 bug。建议按以下顺序排查# 1. 确认服务是否向模型端发起了请求 hermes debug --trace-http # 2. 查看当前记忆库中的记录数量 hermes memory count --user user_001 # 3. 查看某一次召回的具体打分 hermes memory search 你知道我的职业吗 --verbose日志文件中的关键字包括memory.write、memory.recall、hindsight.record、model.call。按这个顺序对所有关键字各 grep 一次通常能快速定位断点。8. 生产环境落地建议与扩展方向8.1 学习环境到生产环境至少要补齐四件事学习环境验证通过后直接复制到生产环境是不可取的。生产环境至少需要补齐四类能力配置外置化把模型地址、API key、credits 阈值放到环境变量或配置中心而不是写在代码里。日志和监控记录每次记忆召回的数量、相似度得分、模型调用耗时和 credits 消耗设置告警。数据备份Mnemosyne 和 Hindsight 的存储文件需要定期备份并验证恢复流程。权限隔离不同用户之间的记忆必须通过user_id隔离必要时增加项目级和团队级权限。8.2 记忆内容治理谁可以写入谁能读取记忆库积累到一定规模后治理比写入更重要。建议在写入前做敏感信息过滤例如身份证号、手机号、密钥等内容不要直接存进记忆库召回时也要做权限校验不允许跨用户读取。过期记忆需要定期清理避免陈旧信息长期参与模型上下文。可以设计一张记忆审计表记录是谁在什么时间写入了哪条记忆以及哪次对话召回过它。这样既能满足合规要求也能在出现错误回答时回溯原因。8.3 与 Spring AI 等外部框架集成如果你是 Java 技术栈可以在 Spring AI 应用里把 Hermes 的记忆 API 封装成MemoryServiceBean。Spring AI 提供统一的模型客户端接口Hermes 负责记忆召回和反思生成两者可以互补。封装时注意线程安全和连接池配置避免高并发下重复创建模型客户端导致连接数被打满。8.4 还可以继续做的实验记忆模块非常适合做实验。下一步可以尝试让 Hindsight 依据用户反馈自动修改反思记录而不是只追加。对比不同 embedding 模型在中文场景下的召回准确率。
返回列表