Hermes Agent自进化的实现方式

以下是 Hermes Agent 自进化机制的完整分析,重点聚焦于"如何记录经验并复用"。

两类知识存储

Agent 将知识分为两种类型,分别存储:

类型 文件 内容 工具
陈述性记忆 ~/.hermes/memories/MEMORY.md 环境事实、学到的教训 memory
用户画像 ~/.hermes/memories/USER.md 用户偏好、习惯、纠正历史 memory
程序性技能 ~/.hermes/skills/<name>/SKILL.md 可复用的步骤、命令序列 skill_manage

经验如何被记录

1. 主动记录(实时触发)

Agent 在对话中可以直接调用 memory 工具保存信息。工具 schema 明确规定了触发条件:

  • 用户纠正了 agent("不要这样做"、"记住这个")
  • 用户分享了偏好、习惯、个人信息
  • Agent 发现了环境信息(OS、项目结构)
  • Agent 学到了某个约定或工作流 1

File: tools/memory_tool.py (L519-528)

python 复制代码
        "WHEN TO SAVE (do this proactively, don't wait to be asked):\n"
        "- User corrects you or says 'remember this' / 'don't do that again'\n"
        "- User shares a preference, habit, or personal detail (name, role, timezone, coding style)\n"
        "- You discover something about the environment (OS, installed tools, project structure)\n"
        "- You learn a convention, API quirk, or workflow specific to this user's setup\n"
        "- You identify a stable fact that will be useful again in future sessions\n\n"
        "PRIORITY: User preferences and corrections > environment facts > procedural knowledge. "
        "The most valuable memory prevents the user from having to repeat themselves.\n\n"
        "Do NOT save task progress, session outcomes, completed-work logs, or temporary TODO "
        "state to memory; use session_search to recall those from past transcripts.\n"

skill的创建条件同样在 schema 中明确定义:

  • 复杂任务成功(5+ 次工具调用)
  • 克服了错误后找到了可行方案
  • 用户纠正后的方法奏效了
  • 发现了非平凡的工作流 2

File: tools/skill_manager_tool.py (L691-698)

python 复制代码
        "Create when: complex task succeeded (5+ calls), errors overcome, "
        "user-corrected approach worked, non-trivial workflow discovered, "
        "or user asks you to remember a procedure.\n"
        "Update when: instructions stale/wrong, OS-specific failures, "
        "missing steps or pitfalls found during use. "
        "If you used a skill and hit issues not covered by it, patch it immediately.\n\n"
        "After difficult/iterative tasks, offer to save as a skill. "
        "Skip for simple one-offs. Confirm with user before creating/deleting.\n\n"

2. 后台异步审查(周期性触发)

每隔 N 轮对话,_spawn_background_review 会在独立线程中启动一个"审查 agent",对整个对话历史进行分析,决定是否需要保存记忆或创建技能: 3
File: run_agent.py (L2448-2470)

python 复制代码
    def _spawn_background_review(
        self,
        messages_snapshot: List[Dict],
        review_memory: bool = False,
        review_skills: bool = False,
    ) -> None:
        """Spawn a background thread to review the conversation for memory/skill saves.

        Creates a full AIAgent fork with the same model, tools, and context as the
        main session. The review prompt is appended as the next user turn in the
        forked conversation. Writes directly to the shared memory/skill stores.
        Never modifies the main conversation history or produces user-visible output.
        """
        import threading

        # Pick the right prompt based on which triggers fired
        if review_memory and review_skills:
            prompt = self._COMBINED_REVIEW_PROMPT
        elif review_memory:
            prompt = self._MEMORY_REVIEW_PROMPT
        else:
            prompt = self._SKILL_REVIEW_PROMPT

审查 agent 是主 agent 的完整 fork,共享同一个 _memory_store,但禁用了自身的 nudge 间隔(避免递归触发): 4
File: run_agent.py (L2481-2489)

python 复制代码
			import contextlib, os as _os
            review_agent = None
            try:
                with open(_os.devnull, "w") as _devnull, \
                    contextlib.redirect_stdout(_devnull), \
                    contextlib.redirect_stderr(_devnull):
                    review_agent = AIAgent(
                        model=self.model,
                        max_iterations=8,
                        #通常表示少输出日志或中间过程
                        quiet_mode=True,
                        platform=self.platform,
                        provider=self.provider,
                    )
                    review_agent._memory_store = self._memory_store
                    review_agent._memory_enabled = self._memory_enabled
                    review_agent._user_profile_enabled = self._user_profile_enabled
                    review_agent._memory_nudge_interval = 0
                    review_agent._skill_nudge_interval = 0

审查完成后,会扫描工具调用结果,将 created/updated/added 等成功操作汇总显示给用户(💾 ...): 5


技能如何自我改进(失败修正)

这是最关键的自进化路径。skill_manage 的 schema 明确要求:

"If you used a skill and hit issues not covered by it, patch it immediately ." 6

技能支持三种更新操作:

  • patch:精准 find-and-replace,用于修复步骤、补充遗漏的坑
  • edit:全量重写,用于大规模重构
  • write_file:向 references/scripts/ 等子目录添加辅助文件

patch 操作使用模糊匹配引擎(fuzzy_find_and_replace),能处理空白差异、缩进不一致等问题,降低精确匹配失败的概率: 7
File: tools/skill_manager_tool.py (L444-448)

python 复制代码
    from tools.fuzzy_match import fuzzy_find_and_replace

    new_content, match_count, _strategy, match_error = fuzzy_find_and_replace(
        content, old_string, new_string, replace_all
    )

知识如何被复用(注入系统提示)

记忆复用

MemoryStore 在会话开始时从磁盘加载,生成一个冻结快照 注入系统提示。中途写入只更新磁盘,不改变当前会话的系统提示(保持 prefix cache 稳定),下次会话启动时才生效: 8 9
File: tools/memory_tool.py (L124-140)

python 复制代码
    def load_from_disk(self):
        """Load entries from MEMORY.md and USER.md, capture system prompt snapshot."""
        mem_dir = get_memory_dir()
        mem_dir.mkdir(parents=True, exist_ok=True)

        self.memory_entries = self._read_file(mem_dir / "MEMORY.md")
        self.user_entries = self._read_file(mem_dir / "USER.md")

        # Deduplicate entries (preserves order, keeps first occurrence)
        self.memory_entries = list(dict.fromkeys(self.memory_entries))
        self.user_entries = list(dict.fromkeys(self.user_entries))

        # Capture frozen snapshot for system prompt injection
        self._system_prompt_snapshot = {
            "memory": self._render_block("memory", self.memory_entries),
            "user": self._render_block("user", self.user_entries),
        }

File: tools/memory_tool.py (L359-370)

python 复制代码
    def format_for_system_prompt(self, target: str) -> Optional[str]:
        """
        Return the frozen snapshot for system prompt injection.

        This returns the state captured at load_from_disk() time, NOT the live
        state. Mid-session writes do not affect this. This keeps the system
        prompt stable across all turns, preserving the prefix cache.

        Returns None if the snapshot is empty (no entries at load time).
        """
        block = self._system_prompt_snapshot.get(target, "")
        return block if block else None

技能复用

agent/prompt_builder.py 在构建系统提示时扫描所有技能目录,将技能的触发条件和描述注入系统提示,让 agent 知道"遇到什么情况应该用哪个技能": 10
File: agent/prompt_builder.py (L18-26)

python 复制代码
from agent.skill_utils import (
    extract_skill_conditions,
    extract_skill_description,
    get_all_skills_dirs,
    get_disabled_skill_names,
    iter_skill_index_files,
    parse_frontmatter,
    skill_matches_platform,
)

技能更新后会立即清除缓存,确保下次构建系统提示时读取最新版本: 11
File: tools/skill_manager_tool.py (L667-672)

python 复制代码
    if result.get("success"):
        try:
            from agent.prompt_builder import clear_skills_system_prompt_cache
            clear_skills_system_prompt_cache(clear_snapshot=True)
        except Exception:
            pass

完整自进化流程



用户对话 / 任务执行
Agent 主循环
实时触发?

(用户纠正/发现新知识)
直接调用 memory/skill_manage
周期性 nudge

(每N轮)
_spawn_background_review

(后台线程)
Review Agent 分析对话历史
调用 memory/skill_manage 写入
写入 MEMORY.md / USER.md

SKILL.md
下次会话启动
MemoryStore.load_from_disk()
冻结快照注入系统提示
prompt_builder 扫描技能目录
技能索引注入系统提示
Agent 带着历史经验开始工作
使用技能时遇到问题?
立即 patch 技能

(失败修正)


关键设计要点

  • 记忆是有界的MEMORY.md 限制 2200 字符,USER.md 限制 1375 字符,强迫 agent 保持精炼而非堆砌
  • 技能有安全扫描 :agent 创建/修改的技能会经过 skills_guard 安全扫描,防止恶意代码注入
  • 失败修正是即时的:技能在使用过程中发现问题就立即 patch,而不是等到会话结束
  • 记忆与技能分工明确 :记忆存"是什么"(事实、偏好),技能存"怎么做"(步骤、命令) 12

File: tools/skill_manager_tool.py (L10-12)

python 复制代码
Skills are the agent's procedural memory: they capture *how to do a specific
type of task* based on proven experience. General memory (MEMORY.md, USER.md) is
broad and declarative. Skills are narrow and actionable.
相关推荐
qq_342295822 小时前
Redis怎样按照距离远近排序展示_通过GEORADIUS的ASC参数进行Geo排序
jvm·数据库·python
2201_761040592 小时前
C#比较两个二进制文件的差异 C#如何实现一个二进制diff工具
jvm·数据库·python
普鲁夕格2 小时前
【AI翻唱】RVC和SVC声音音色模型难找?推荐这个下载网站
人工智能
Csvn2 小时前
🌟 LangChain 30 天保姆级教程 · Day 23|Agent 进阶实战!Function Calling + 自动 Tool 注册,打造会“动
python·langchain
Csvn2 小时前
🌟 LangChain 30 天保姆级教程 · Day 22|长文档处理三剑客!MapReduce、Refine、Map-Rerank,让 AI 消化整本手册
python·langchain
John.Lewis2 小时前
Python小课(1)认识Python
开发语言·python
Polar__Star2 小时前
SQL中如何实现特定顺序的查询:CASE WHEN自定义排序
jvm·数据库·python
亚马逊云开发者2 小时前
【Bedrock AgentCore】AI Agent 回答不一致怎么办?双 Memory 架构实现服务标准化(附完整代码)
大数据·人工智能·架构
u0109147602 小时前
mysql如何配置监听IP_mysql bind-address多地址设置
jvm·数据库·python