PPT 大纲 — Hermes Agent 培训幻灯片
106张幻灯片逐页大纲
本文档为讲师主导的 Hermes Agent 培训课程提供逐页幻灯片大纲。 共 6 个模块、约 106 张幻灯片,每张幻灯片附讲师备注。 技术术语保留英文,正文使用中文。
Module 1: 认识 Hermes Agent(15 slides)
Slide 1: 封面 — Hermes Agent 培训课程
- 课程名称:Hermes Agent 专业培训
- 主讲人 / 日期 / 场地信息
- 课程时长:约 8 小时(理论 4h + 实操 4h)
- [讲师备注: 开场白 — 介绍自己和课程目标,确认学员背景分布]
Slide 2: 课程目标与学习路径
- 理解 AI Agent 与聊天机器人的本质差异
- 掌握 Hermes Agent 的架构、工具系统、安全模型
- 能够独立部署、配置、扩展 Hermes Agent
- 完成飞书接入、自定义工具开发等实操练习
- [讲师备注: 让学员设定个人学习目标,收集期望]
Slide 3: 什么是 AI Agent — 从问答到执行
- 传统 AI:单轮问答(User -> LLM -> Response)
- AI Agent:工具调用循环(User -> LLM -> Tool -> LLM -> ... -> Response)
- 关键差异:Agent 是"执行者"而非"建议者"
- [讲师备注: 用"帮你部署项目"举例 — 聊天机器人给步骤,Agent 直接执行]
Slide 4: Hermes Agent 核心定义
- AI 驱动的自主 Agent 框架(AI-powered Autonomous Agent)
- 核心引擎:
run_agent.py中的run_conversation()while 循环 - IterationBudget 控制迭代上限(默认 90 次)
- 能力链:理解意图 -> 拆解任务 -> 调用工具 -> 迭代执行 -> 交付结果
- [讲师备注: 强调"while 循环"是一切的基础,后续模块会反复引用]
Slide 5: 核心特性总览(动画逐步展示)
- 特性 1:多平台接入(19+ 即时通讯平台)
- 特性 2:工具调用(30+ 内置工具)
- 特性 3:子 Agent 委派(并行任务处理)
- 特性 4:持久记忆(跨会话 MEMORY.md)
- 特性 5:上下文压缩(自动管理 token 预算)
- 特性 6:安全审批(多层纵深防御)
- [讲师备注: 每个特性点击一次展示,配合简短场景描述]
Slide 6: 技术栈概览
- 语言:Python 3.10+
- LLM SDK:OpenAI Python SDK(兼容 3 种 API 模式)
- 异步模型:asyncio + threading 混合
- 存储:SQLite(会话)、JSONL(日志)、YAML(配置)
- 部署:Docker / systemd / Nix / Modal
- 核心依赖:openai、httpx、playwright、yaml
- [讲师备注: 确认学员对 Python 和异步编程的熟悉程度]
Slide 7: 架构总览图
- 三层架构:CLI -> Gateway -> Agent
- CLI 层:hermes_cli/main.py,子命令分发
- Gateway 层:gateway/run.py,GatewayRunner 主控制器
- Agent 层:run_agent.py,AIAgent 核心引擎
- 工具层:tools/registry.py,ToolRegistry 单例
- [讲师备注: 用 diagrams/architecture.md 中的整体架构图展示]
Slide 8: 快速演示 — CLI 模式
- 安装:
git clone+uv pip install -e ".[all]" - 配置:
hermes setup交互式向导 - 运行:
hermes启动交互式对话 - 演示:让 Agent 执行一个简单任务(如创建文件、搜索代码)
- [讲师备注: 现场演示,让学员看到 Agent 的工具调用循环]
Slide 9: 快速演示 — Gateway 模式
- 启动:
hermes gateway run - 飞书接入:配置 FEISHU_APP_ID / FEISHU_APP_SECRET
- 演示:在飞书中 @机器人 发送消息,观察 Agent 响应
- 核心类:GatewayRunner(gateway/run.py:510)
- [讲师备注: 如果环境允许,现场演示飞书接入;否则用截图展示]
Slide 10: 适用场景矩阵 — 开发与运维
- 软件开发:代码编写、调试排错、Git 操作、重构
- DevOps:Docker 部署、CI/CD 配置、监控告警、日志分析
- 数据分析:数据清洗、统计分析、可视化、报告生成
- [讲师备注: 让学员分享自己的使用场景]
Slide 11: 适用场景矩阵 — 内容与协作
- 内容创作:文档编写、翻译、审核、SEO 优化
- 团队协作:Slack/Discord/飞书/钉钉集成
- 个人效率:Telegram/WhatsApp 助手、邮件自动化
- 定时任务:Cron 自动巡检、日报生成
- [讲师备注: 强调多平台接入是 Hermes 的差异化优势]
Slide 12: Hermes vs ChatGPT vs Copilot 对比
- 交互模式:自主工具调用循环 vs 单轮问答 vs 代码补全
- 工具调用:30+ 内置工具自动执行 vs 无 vs 无
- 执行环境:本地/Docker/Modal/SSH vs 沙箱 vs 编辑器内
- 记忆能力:持久记忆 MEMORY.md vs 会话内 vs 项目上下文
- 多平台:19+ 平台 vs Web/App vs IDE 插件
- [讲师备注: 强调 Agent 是"执行者"而非"建议者"这一核心差异]
Slide 13: 安装与环境准备
- 前置条件:Python 3.10+、Git、API Key
- 安装命令:
pip install -e ".[all]"或uv pip install -e ".[all]" - 配置文件位置:
~/.hermes/config.yaml+~/.hermes/.env - Profile 系统:
hermes -p work多环境切换 - 诊断工具:
hermes doctor检查配置完整性 - [讲师备注: 确认所有学员完成安装,为后续实操做准备]
Slide 14: 配置系统快速入门
- config.yaml 结构:model / terminal / memory / delegation / security
- .env 文件:API Key 等敏感信息存储
- 优先级链:命令行参数 > .env > config.yaml > 代码默认值
- 环境变量展开:支持
${ENV_VAR}语法 - [讲师备注: 展示一个最小化配置示例,让学员快速上手]
Slide 15: Module 1 小结与 Q&A
- 回顾:Hermes Agent 是什么、核心特性、架构概览、快速体验
- 关键概念:工具调用循环、三层架构、IterationBudget
- 预告:下一模块深入核心架构
- [讲师备注: 留 5-10 分钟答疑,确认学员对基础概念的理解]
Module 2: 核心架构(20 slides)
Slide 16: Module 2 开场 — 三层架构总览
- CLI 层(hermes_cli/main.py)— 用户交互前端
- Gateway 层(gateway/run.py)— 多平台消息路由
- Agent 层(run_agent.py)— LLM 交互与工具调度
- 数据流方向:用户 -> CLI/Gateway -> AIAgent -> Tools -> LLM
- [讲师备注: 每层用不同颜色标注,后续 slides 逐层展开]
Slide 17: CLI 层 — 执行流程
- 第一步:Profile 覆盖(
_apply_profile_override(),第 83 行) - 第二步:环境加载(
load_hermes_dotenv()) - 第三步:子命令分发(chat / gateway / setup / doctor / sessions)
- Profile 解析优先级:命令行参数 > active_profile 文件 > 默认
- [讲师备注: 重点讲解 Profile 为什么必须在 import 之前执行]
Slide 18: Gateway 层 — GatewayRunner 类
- 核心类:GatewayRunner(gateway/run.py:510)
- 关键组件:SessionStore / DeliveryRouter / PlatformAdapter
- Agent 缓存:
_agent_cache维持 Prompt Caching 有效性 - SSL 自动检测:NixOS 等非标准系统的 CA 证书处理
- [讲师备注: 解释为什么需要 Agent 缓存 — Anthropic Prompt Caching]
Slide 19: Gateway — 配置桥接机制
- config.yaml 值桥接到环境变量(第 89-207 行)
- 统一使用
os.getenv()读取配置 - 优先级:.env > config.yaml > 代码默认值
- 环境变量分类:TERMINAL_* / AUXILIARY_* / HERMES_*
- [讲师备注: 解释为什么不直接读 config.yaml — 向后兼容 + 环境变量覆盖]
Slide 20: Agent 层 — AIAgent 类初始化
AIAgent.__init__(第 516-1199 行,约 680 行)- 初始化阶段:安全 stdio / API 模式 / Provider 路由 / 工具加载 / 记忆系统
- API 模式自动检测:chat_completions / codex_responses / anthropic_messages
- [讲师备注: 强调这是"重量级"类,后续 slides 拆解各阶段]
Slide 21: 消息处理流程 — 时序图
- 用户消息 -> 平台适配器 -> GatewayRunner -> SessionStore
- -> HookRegistry.emit("agent:start") -> AIAgent.run_conversation()
- -> ContextCompressor 检查 -> LLM API 调用 -> 工具执行循环
- -> HookRegistry.emit("agent:end") -> SessionStore.save -> 平台回复
- [讲师备注: 用 diagrams/architecture.md 中的时序图展示,重点标注每一步]
Slide 22: AIAgent 核心循环 — run_conversation()
- 入口方法:
run_conversation()(第 7506 行) - 阶段 1:初始化(安全 stdio、Surrogate 清理、连接健康检查)
- 阶段 2:系统提示构建(SOUL.md + 平台上下文 + 记忆 + 技能)
- 阶段 3:主循环(LLM 调用 -> 工具执行 -> 预算检查 -> 循环)
- 阶段 4:后处理(记忆 flush、会话日志)
- [讲师备注: 这是整个系统最核心的方法,需要重点讲解]
Slide 23: IterationBudget — 迭代预算控制
- 类定义:
IterationBudget(第 170 行),线程安全 - 核心方法:
consume()/refund()/reset() - 父 Agent 默认 90 次,子 Agent 默认 50 次
- 优雅耗尽:预算耗尽时注入提示,给模型最后一次机会总结
execute_code的迭代可退款- [讲师备注: 为什么需要线程安全 — 子 Agent 并行执行场景]
Slide 24: 工具调用循环动画
- 动画 Step 1:LLM 返回包含 tool_calls 的响应
- 动画 Step 2:Agent 遍历 tool_calls,调用 ToolRegistry.dispatch()
- 动画 Step 3:工具返回 JSON 结果,追加到消息列表
- 动画 Step 4:IterationBudget.consume() 检查
- 动画 Step 5:再次调用 LLM,携带工具结果
- 循环直到 LLM 不再返回 tool_calls 或预算耗尽
- [讲师备注: 用逐步动画展示,每步暂停解释。可用 diagrams 中的流程图]
Slide 25: Provider 路由机制 — 三种 API 模式
chat_completions:OpenAI 兼容端点(大多数 API)codex_responses:OpenAI Responses API(GPT-5.x)anthropic_messages:Anthropic Messages API(原生 Claude)- 自动检测逻辑:provider 名称 -> URL 模式 -> 默认值
- [讲师备注: 解释为什么需要支持三种模式 — 兼容性 + 性能差异]
Slide 26: Provider — 检测链与自动升级
- 检测优先级:显式 api_mode > provider 名 > URL 匹配 > 默认
- 自动升级:GPT-5.x 模型必须使用 Responses API
- Fallback 链:主 Provider 不可用时自动切换备用
- Prompt Caching:Anthropic Claude 的缓存优化
- [讲师备注: 展示配置示例,让学员理解如何配置多 Provider]
Slide 27: 配置系统层级
- 五层优先级:命令行参数 > .env > config.yaml > 代码默认值
- config.yaml 主要配置段:model / terminal / memory / delegation / security
- 环境变量展开:
${ENV_VAR}语法 - Profile 系统:独立配置目录
~/.hermes-<profile>/ - [讲师备注: 用 diagrams/architecture.md 中的配置层级图展示]
Slide 28: config.yaml 结构详解
- model:provider / default / context_length / fallback_model
- terminal:backend / timeout / cwd / docker_image
- memory:memory_enabled / user_profile_enabled / provider
- delegation:max_concurrent_children / max_iterations / model
- security:redact_secrets / tirith_enabled
- [讲师备注: 展示完整配置文件,逐段解释]
Slide 29: 会话管理 — SessionStore
- 核心类:SessionStore(gateway/session.py:495)
- 存储后端:SQLite(主)+ JSONL(降级)
- 数据结构:SessionSource(来源信息)+ SessionContext(连接上下文)
- PII 脱敏:SHA-256 前 12 位确定性哈希
- [讲师备注: 解释为什么需要 PII 脱敏 — WhatsApp/Signal 手机号保护]
Slide 30: 会话重置策略
- per_message:每条消息创建新会话(无上下文)
- per_conversation:基于超时的会话延续(默认)
- never:永远不重置
- 活跃进程保护:有后台任务时不重置
- [讲师备注: 让学员思考不同场景下应选择哪种策略]
Slide 31: Agent 缓存与 Prompt Caching
_agent_cache:按 session_key 缓存 AIAgent 实例- 目的:维持 Anthropic Prompt Caching 的前缀稳定性
- 缓存失效:配置变更时重建
- 内存考虑:长时间运行后缓存积累的内存压力
- [讲师备注: 解释 Prompt Caching 的成本优势 — 输入成本降低约 75%]
Slide 32: 异步模型 — asyncio + threading
- Gateway 层:asyncio 事件循环(平台适配器异步 IO)
- Agent 层:同步 + ThreadPoolExecutor(工具并行执行)
- 异步桥接:
_run_async()处理三种场景 - 场景 1:已有事件循环 -> 新建线程
- 场景 2:工作线程 -> 每线程持久循环
- 场景 3:主线程 -> 共享持久循环
- [讲师备注: 这是 Hermes 异步架构的核心设计,需要仔细讲解]
Slide 33: 上下文压缩触发机制
- ContextCompressor(agent/context_compressor.py)
- 触发条件:
prompt_tokens >= threshold_tokens(默认 50%) - 五步压缩算法:剪枝 -> 保护头部 -> 保护尾部 -> LLM 摘要 -> 组装
- 摘要模板:Goal / Progress / Decisions / Files / Remaining Work
- [讲师备注: 下一模块再详细展开,这里只介绍触发时机和目标]
Slide 34: 系统提示词构建流程
- 组件化拼装:Identity -> PlatformHints -> SkillsIndex -> ContextFiles -> Memory -> Guidance
- Identity:SOUL.md(用户自定义)或 DEFAULT_AGENT_IDENTITY
- Context Files:.hermes.md / AGENTS.md / CLAUDE.md 按优先级加载
- 注入扫描:检测 prompt injection 和不可见 Unicode
- [讲师备注: 强调系统提示词构建是 Agent 行为的基础]
Slide 35: Module 2 小结与 Q&A
- 三层架构:CLI -> Gateway -> Agent
- 核心循环:run_conversation() 的 while 循环
- IterationBudget:迭代预算控制
- Provider 路由:三种 API 模式 + Fallback
- 配置系统:五层优先级 + Profile 隔离
- [讲师备注: 留 10 分钟答疑,这是理解后续模块的基础]
Module 3: 工具系统(18 slides)
Slide 36: Module 3 开场 — 工具系统架构
- ToolRegistry 单例(tools/registry.py)
- 模块级注册:每个工具文件导入时自动
registry.register() - 统一调度:
registry.dispatch(name, args)路由到 handler - 工具发现:
model_tools.py的_discover_tools()导入所有模块 - [讲师备注: 展示 diagrams 中的工具注册与调度架构图]
Slide 37: ToolEntry 数据结构
- 字段:name / toolset / schema / handler / check_fn / requires_env / is_async / emoji
__slots__设计:节省内存、防止动态属性注入- schema 格式:OpenAI function calling JSON Schema
- check_fn:可用性检查函数(如检查 API Key 是否配置)
- [讲师备注: 展示一个完整的 ToolEntry 实例]
Slide 38: 工具注册流程
- 时机:模块导入时(
import tools.terminal_tool-> 末尾registry.register()) - 导入链:registry.py <- tools/*.py <- model_tools.py <- run_agent.py
- 循环安全:registry.py 不导入任何工具文件
- 动态发现:MCP 工具 + 插件工具在标准发现后加载
- [讲师备注: 画导入依赖图,强调为什么这样设计避免循环]
Slide 39: 内置工具一览 — 终端与文件
- terminal:6 种执行后端(local/docker/modal/ssh/singularity/daytona)
- read_file / write_file / patch / search_files:文件操作工具集
- 后端选择:
TERMINAL_ENV环境变量控制 - 超时控制:前台命令最大 600 秒
- [讲师备注: 重点讲解 terminal 工具,它是使用最频繁的工具]
Slide 40: 内置工具一览 — Web 与浏览器
- web_search / web_extract:Web 搜索和内容提取
- browser_navigate / browser_snapshot / browser_click / browser_type:浏览器自动化
- 三种浏览器后端:Local Chromium / Browserbase / Browser Use
- Accessibility Tree 交互:基于文本而非截图
- [讲师备注: 演示浏览器工具的使用,展示 Accessibility Tree 输出]
Slide 41: 内置工具一览 — 其他工具
- vision_analyze:图像分析
- delegate_task:子 Agent 委派
- memory:持久记忆管理
- skills_list / skill_view / skill_manage:技能管理
- cronjob:定时任务
- text_to_speech:TTS 语音合成
- clarify:向用户提问澄清
- [讲师备注: 快速过一遍,后续模块会深入部分工具]
Slide 42: 工具调度流程 — handle_function_call()
- 统一入口:
handle_function_call()(model_tools.py:459) - Step 1:参数类型强制转换(
coerce_tool_args) - Step 2:Agent 循环拦截(todo/memory/session_search/delegate_task)
- Step 3:插件 pre_tool_call 钩子
- Step 4:
registry.dispatch()路由到 handler - Step 5:插件 post_tool_call 钩子
- [讲师备注: 画出完整的调度流程图]
Slide 43: 参数类型强制转换
- 问题:LLM 返回字符串类型的数字和布尔值(
"42"而非42) - 解决:
coerce_tool_args()根据 schema 自动转换 - 支持转换:
"42"->42/"3.14"->3.14/"true"->True - 联合类型按顺序尝试
- [讲师备注: 这是 LLM 工具调用中常见的问题,几乎所有框架都会遇到]
Slide 44: 异步桥接 — _run_async()
- 问题:Agent 层同步,但很多工具 handler 是异步
- 三种场景处理:
- 已有事件循环(Gateway)-> 新建线程
- 工作线程(并行执行)-> 每线程持久循环
- 主线程(CLI)-> 共享持久循环
registry.dispatch()自动检测is_async并桥接- [讲师备注: 这是 Hermes 异步架构的精妙之处]
Slide 45: 并行执行安全模型
- 条件:模型返回多个 tool_calls 时判断是否可并行
- 并行安全白名单:
_PARALLEL_SAFE_TOOLS(read_file / web_search 等) - 永不并行:
clarify(需要用户交互) - 路径作用域检查:
read_file("/a")+write_file("/a")-> 检查路径重叠 - 最大并发:8 个线程
- [讲师备注: 解释为什么需要路径检查 — 避免读写冲突]
Slide 46: Agent 循环拦截工具
- 拦截列表:todo / memory / session_search / delegate_task
- 原因:这些工具需要访问 Agent 级别状态(TodoStore / MemoryStore)
- 处理方式:
handle_function_call()返回错误,Agent 主循环自行处理 - 绕过 model_tools.py 的标准路由
- [讲师备注: 这是工具系统中的一个特殊情况,需要特别注意]
Slide 47: 终端工具 — 破坏性命令检测
- Agent 层:
_is_destructive_command()(run_agent.py:256) - 正则匹配:rm / mv / sed -i / git reset 等
- 工具层:Tirith 安全扫描器(AST 级别分析)
- 纵深防御:正则匹配 -> Tirith 扫描 -> 用户审批
- [讲师备注: 用实际命令示例展示检测效果]
Slide 48: 终端工具 — Sudo 密码处理
- 命令重写:
sudo->sudo -S -p ''(从 stdin 读密码) - 密码来源:环境变量 / 交互式提示(45 秒超时)
- 会话内密码缓存
- 安全考量:密码不以明文出现在命令历史中
- [讲师备注: 解释为什么需要这种处理 — Agent 场景下的 sudo 场景]
Slide 49: 自定义工具开发 — 最简示例
- Step 1:创建
tools/database_tool.py - Step 2:定义 JSON Schema(DATABASE_QUERY_SCHEMA)
- Step 3:实现 handler 函数(
_handle_database_query) - Step 4:模块级调用
registry.register() - Step 5:在
model_tools.py的_discover_tools()中添加模块 - [讲师备注: 现场编码演示,让学员跟着做]
Slide 50: 自定义工具 — 异步工具开发
- handler 声明为
async def - 注册时设置
is_async=True registry.dispatch()自动通过_run_async()桥接- 示例:使用 httpx AsyncClient 的天气查询工具
- [讲师备注: 展示异步工具的完整代码]
Slide 51: MCP 工具扩展
- MCP(Model Context Protocol):标准化外部工具协议
- 配置:config.yaml 的
mcp_servers节 - 动态注册:发现后通过
registry.register()注册 - 热更新:MCP 服务器发送
notifications/tools/list_changed时重新注册 - [讲师备注: MCP 是 Agent 生态的重要趋势]
Slide 52: 工具集过滤与配置
- 白名单模式:
enabled_toolsets只包含指定工具集 - 黑名单模式:
disabled_toolsets排除指定工具集 - 兼容性:
_LEGACY_TOOLSET_MAP支持新旧工具集名称 - check_fn 运行时检查:API Key 缺失的工具自动隐藏
- [讲师备注: 展示如何通过配置控制可用工具范围]
Slide 53: Module 3 小结与实操练习
- ToolRegistry 单例 + 模块级注册
- handle_function_call() 统一调度
- 参数强制转换 + 异步桥接 + 并行安全
- 自定义工具开发:Schema + Handler + Register
- 实操:编写一个简单的自定义工具
- [讲师备注: 留 15 分钟让学员实操编写自定义工具]
Module 4: 多平台 + Hook + 技能(20 slides)
Slide 54: Module 4 开场 — 平台适配器架构
- BasePlatformAdapter 抽象基类(gateway/platforms/base.py:726)
- 核心抽象方法:connect() / disconnect() / send() / get_chat_info()
- 可选方法:edit_message() / send_typing() / send_image() / send_voice()
- 设计原则:平台无关的 Agent 能力 + 平台特定的消息处理
- [讲师备注: 强调 BasePlatformAdapter 是所有平台的统一接口]
Slide 55: MessageEvent — 统一消息模型
- 数据类:text / message_type / source / media_urls / auto_skill
- MessageType 枚举:TEXT / PHOTO / VIDEO / AUDIO / VOICE / DOCUMENT
- 消息归一化:每个平台将原生格式转换为 MessageEvent
- 命令解析:
is_command()/get_command()便捷方法 - [讲师备注: 展示消息归一化的价值 — Agent 层不需要关心平台差异]
Slide 56: SendResult 与重试机制
- SendResult 数据类:success / message_id / error / retryable
- 基类重试逻辑(
_send_with_retry,第 1331 行) - 可重试错误:ConnectionError / ConnectionReset -> 指数退避
- 超时错误:不重试(消息可能已送达,避免重复)
- 格式化错误:尝试纯文本降级
- [讲师备注: 解释为什么超时不重试 — 消息可能已经送达用户]
Slide 57: 适配器生命周期
- 初始化:super().init() + 平台配置加载
- 连接:依赖检查 -> 凭证验证 -> 平台锁获取 -> 建立连接
- 消息接收:归一化 -> MessageEvent -> handle_message()
- 消息发送:extract_media -> auto-TTS -> send_text -> send_images
- 断线重连:
_set_fatal_error()+ Gateway 自动重启 - [讲师备注: 画出完整的生命周期图]
Slide 58: 飞书适配器实战 — 连接建立
- 两种模式:WebSocket(推荐)+ Webhook
- connect() 流程:依赖检查 -> 凭证验证 -> 平台锁 -> WebSocket 连接
- SDK 集成:lark-oapi 的 FeishuWSClient
- 独立线程运行 WebSocket 客户端
- [讲师备注: 重点讲解 WebSocket 模式 — 不需要公网 IP]
Slide 59: 飞书适配器实战 — 消息处理
- 事件注册:im_message_receive / message_reaction / card_action
- 消息类型映射:text / post(富文本)/ image / file / audio / merge_forward
- 富文本解析:递归处理 text / a / at / img / code_block 元素
- @机器人触发:检查 mentioned_ids 匹配 bot_open_id
- [讲师备注: 展示飞书 Post 消息的 JSON 结构和归一化结果]
Slide 60: 飞书适配器实战 — 消息发送
- 两种格式:纯文本(msg_type="text")/ 富文本 Post(msg_type="post")
- 文件上传:本地文件 -> 飞书 CDN -> image_key/file_key -> 消息体
- 批量发送优化:FeishuBatchState 延迟合并
- 群聊权限规则引擎
- [讲师备注: 展示发送消息的完整代码流程]
Slide 61: API Server 适配器
- OpenAI 兼容 HTTP API
- 端点:/v1/chat/completions / /v1/responses / /v1/models / /v1/runs
- ResponseStore:SQLite 持久化会话状态
- 前端兼容:Open WebUI / LobeChat / LibreChat 可直接接入
- [讲师备注: 这是将 Hermes 作为后端 API 使用的关键适配器]
Slide 62: 接入新平台模式
- Step 1:继承 BasePlatformAdapter
- Step 2:实现 connect() / disconnect() / send() / get_chat_info()
- Step 3:实现消息归一化(_normalize_message)
- Step 4:在 Platform 枚举中注册
- Step 5:在 config.yaml 中添加平台配置
- [讲师备注: 展示完整的模板代码,让学员了解接入流程]
Slide 63: Hook 系统概述
- HookRegistry 类(gateway/hooks.py:34)
- 轻量级事件处理器,在 Agent 生命周期关键节点触发
- 目录结构:
~/.hermes/hooks/<hook-name>/HOOK.yaml + handler.py - 事件类型:gateway:startup / session:start / agent:start / agent:end / command:*
- [讲师备注: Hook 是"开闭原则"的体现 — 对扩展开放,对修改关闭]
Slide 64: Hook 生命周期事件
- gateway:startup:Gateway 进程启动
- session:start / session:end / session:reset:会话生命周期
- agent:start / agent:step / agent:end:Agent 处理流程
- command:*:任意斜杠命令(支持通配符匹配)
- [讲师备注: 展示 diagrams 中的 Hook 生命周期图]
Slide 65: Hook — discover_and_load() 流程
- Step 1:注册内置 Hook(boot-md)
- Step 2:扫描
~/.hermes/hooks/目录 - Step 3:解析 HOOK.yaml 清单
- Step 4:动态导入 handler.py
- Step 5:提取 handle 函数并注册到事件
- 错误隔离:单个 Hook 失败不影响其他 Hook
- [讲师备注: 展示 HOOK.yaml 和 handler.py 的最小示例]
Slide 66: Hook — emit() 事件触发
- 精确匹配 + 通配符匹配(
command:*) - 同步/异步兼容:
asyncio.iscoroutine()检测 - 错误隔离:try/except 包裹,Hook 失败不阻断主流程
- 非阻塞保证:Hook 异常只打印日志
- [讲师备注: 强调"Hook 失败不阻断主流程"的设计原则]
Slide 67: i18n Hook 案例展示
- 设计思路:monkey-patch BasePlatformAdapter.send()
- gateway:startup 事件中替换所有适配器的 send() 方法
- pkgutil.iter_modules 遍历所有适配器子类
- 翻译策略:精确匹配 + 子串匹配(按长度降序)
- [讲师备注: 展示完整的 i18n Hook 代码,让学员理解 monkey-patch 方式]
Slide 68: 内置 Hook — boot-md
- 功能:Gateway 启动时执行
~/.hermes/BOOT.md - 非阻塞:独立线程执行,不阻塞 Gateway 启动
- 静默模式:回复包含
[SILENT]则不发送通知 - 限制:max_iterations=20,防止无限循环
- [讲师备注: 展示 BOOT.md 的示例内容 — 启动检查清单]
Slide 69: 技能系统设计 — 渐进式披露
- 四层架构:
- Tier 0:categories() — 分类名 + 描述
- Tier 1:skills_list() — 技能名 + 描述
- Tier 2:skill_view(name) — SKILL.md 完整内容
- Tier 3:skill_view(name, file_path) — 关联文件
- 核心优势:token 效率,按需加载
- [讲师备注: 解释为什么需要渐进式披露 — 节省 token 开销]
Slide 70: SKILL.md 格式规范
- YAML Frontmatter:name / description / version / platforms / prerequisites
- Markdown 正文:铁律 + 标准化流程 + 故障排除
- 关联目录:references/ / templates/ / assets/ / scripts/
- 平台兼容性检查:
skill_matches_platform() - [讲师备注: 展示一个完整的 SKILL.md 示例]
Slide 71: 技能加载与安全检查
- 安全检查 1:路径遍历防护(
validate_within_dir) - 安全检查 2:Prompt 注入检测(
_INJECTION_PATTERNS) - 安全检查 3:信任目录验证
- 环境变量准备:检查 required_environment_variables
- Gateway 模式:无法安全输入密钥,提示用户手动配置 .env
- [讲师备注: 强调技能加载的安全考量]
Slide 72: 编写部署技能实战
- cloud-deploy 技能案例:6 步标准化部署流程
- 铁律设计:绝不修改 Nginx listen 指令(带原因和后果说明)
- 错误处理:每步定义回滚策略
- 关联文件:references/nginx.md / templates/service.conf
- [讲师备注: 展示 cloud-deploy 技能的完整结构和铁律部分]
Slide 73: 技能最佳实践
- 描述编写:说明触发条件 + 覆盖核心功能 + 突出价值(< 1024 字符)
- 铁律约束:明确性 + 原因驱动 + 后果可预测 + 正反对比(3-5 条)
- 错误处理:立即停止 + 回滚优先 + 清晰报告 + 等待指示
- 关联文件:长内容放 references/ 而非 SKILL.md 正文
- [讲师备注: 让学员思考如何为自己的场景编写技能]
Slide 74: Module 4 小结与实操练习
- 平台适配器:BasePlatformAdapter + MessageEvent + SendResult
- 飞书实战:WebSocket + 富文本解析 + 文件上传
- Hook 系统:事件驱动 + 通配符 + 错误隔离
- 技能系统:渐进式披露 + SKILL.md 格式 + 安全检查
- 实操:编写一个简单的 Hook 或技能
- [讲师备注: 留 20 分钟实操,学员可选择编写 Hook 或技能]
Module 5: 记忆 + 安全(18 slides)
Slide 75: Module 5 开场 — 记忆系统架构
- 双存储模型:MEMORY.md(Agent 笔记)+ USER.md(用户画像)
- MemoryStore 类(tools/memory_tool.py:100)
- 核心设计:冻结快照机制 + 原子写入 + 文件锁
- MemoryManager 编排器:内置 provider + 最多一个外部 provider
- [讲师备注: 记忆和上下文是 Agent 长期可用性的基石]
Slide 76: MEMORY.md 与 USER.md
- MEMORY.md:Agent 自身笔记(环境事实、项目约定、经验教训),上限 2200 字符
- USER.md:用户画像(姓名、角色、偏好、习惯),上限 1375 字符
- 字符数限制:模型无关,不同 LLM 的 tokenizer 不影响行为一致性
- 条目分隔符:
§(在正常内容中极少出现) - [讲师备注: 解释为什么用字符数而非 token 数 — 跨模型一致性]
Slide 77: 冻结快照机制
- 核心设计:系统提示词使用加载时的快照,而非实时状态
- 目的:保证 prefix cache 稳定性(Anthropic Prompt Caching)
- 中途写入:立即持久化到磁盘,但不更新系统提示词
- 下次会话启动时快照才刷新
- 缓存命中率:从 0% 提升到接近 100%
- [讲师备注: 这是 MemoryStore 最精妙的设计,需要重点讲解]
Slide 78: 文件持久化与并发安全
- 原子写入:tempfile + fsync + os.replace()
- 文件锁:fcntl.flock(Linux)/ msvcrt(Windows)
- 锁内重读:每次操作前在锁保护下重新读取最新状态
- os.replace() vs os.rename():前者是原子操作
- [讲师备注: Gateway 多会话并发场景下的安全保障]
Slide 79: 记忆工具接口
- 四个操作:add / replace / remove / read
- 子串匹配:replace 和 remove 使用模糊匹配,降低模型精确性要求
- 重复检测:多个匹配时要求更具体的文本
- 自动 Flush:每 N 个 turn 提示 Agent 保存有价值的信息
- [讲师备注: 展示 MEMORY_SCHEMA 的指导文本]
Slide 80: 上下文压缩 — 5 步算法动画
- Step 1:剪枝旧工具输出(> 200 字符的 tool result 替换为占位符,无需 LLM)
- Step 2:保护头部消息(protect_first_n=3,系统提示词不可压缩)
- Step 3:保护尾部消息(按 token 预算反向计算,最少 3 条)
- Step 4:LLM 结构化摘要(Goal / Progress / Decisions / Files / Remaining Work)
- Step 5:迭代更新(后续压缩在旧摘要基础上增量更新)
- [讲师备注: 用 diagrams 中的压缩算法流程图逐步动画展示]
Slide 81: 压缩摘要模板
- Goal:用户目标
- Progress:Done / In Progress / Blocked
- Key Decisions:关键技术决策
- Resolved Questions vs Pending User Asks:防止重复回答
- Relevant Files:具体文件路径
- Remaining Work:待办事项
- "Different assistant" 隔离框架:交接语义,避免摘要中执行指令
- [讲师备注: 展示一个完整的压缩摘要示例]
Slide 82: 压缩边界对齐与工具配对
_align_boundary_forward/_align_boundary_backward:不在 tool_call/result 组中间切割_sanitize_tool_pairs:修复孤儿 tool_call 或 tool_result- 消息角色交替:避免连续相同角色(API 要求)
- 摘要失败处理:静态回退 + 600 秒冷却期
- [讲师备注: 这些是压缩后 API 合法性的关键保证]
Slide 83: 系统提示词构建
- 7 层组件化拼装:
- Identity(SOUL.md)
- Platform Hints
- Skills Index
- Context Files
- Memory Snapshot
- Behavioral Guidance
- Nous Subscription
- 每层独立可配置、职责单一
- [讲师备注: 展示完整的系统提示词结构图]
Slide 84: 注入扫描 — Prompt Injection 防御
- 威胁模式:ignore previous instructions / system prompt override / hidden div
- 不可见字符检测:零宽空格 / BOM / 方向控制符
- 处理方式:检测到威胁时替换为警告,而非拒绝加载
- 方向控制符风险:U+202E RTL Override 可隐藏恶意文本
- [讲师备注: 展示几种注入攻击的示例]
Slide 85: 安全模型 — 多层防护总览
- Layer 0:容器沙箱隔离(环境级隔离,限制爆炸半径)
- Layer 1:DANGEROUS_PATTERNS 正则匹配(快速模式匹配)
- Layer 2:Tirith 深度扫描(内容级威胁检测)
- Layer 3:内容注入扫描(防止 Prompt Injection)
- Layer 4:检查点回滚(最后一道防线,恢复误操作)
- [讲师备注: 纵深防御 — 每层独立工作,即使某层被绕过,其他层仍提供保护]
Slide 86: 命令审批系统
- DANGEROUS_PATTERNS:约 30 个正则表达式
- 覆盖类别:文件删除 / 权限变更 / 系统破坏 / SQL 危险 / 远程执行 / 自我终止
- 敏感写入目标:/etc/ / /dev/sd / ~/.ssh/ / ~/.hermes/.env
- 命令规范化:ANSI 剥离 + null 字节移除 + Unicode NFKC 规范化
- [讲师备注: 展示几个被检测到的危险命令示例]
Slide 87: 审批级别与 YOLO 模式
- 四种审批:once(仅一次)/ session(会话内)/ always(永久)/ deny(拒绝)
- 持久化:always 写入 config.yaml 的 command_allowlist
- Key 别名映射:正则变更不影响已有审批
- YOLO 模式:Gateway 中按会话启用,ContextVar 隔离
- [讲师备注: 解释为什么 YOLO 是会话级而非全局级]
Slide 88: Smart Approval — 智能审批
- 辅助 LLM 评估命令实际风险,自动审批误报
- 三种返回值:approve(自动批准)/ deny(阻止)/ escalate(手动审批)
- 典型误报:
python3 -c "print('hello')"/git commit -m "fix: remove deprecated API" - 配置:approvals.mode = smart / timeout = 60 / gateway_timeout = 300
- [讲师备注: 解释 Smart Approval 的价值 — 减少审批疲劳]
Slide 89: Tirith 安全扫描器
- Rust 编写的独立安全二进制,扫描延迟 < 100ms
- 检测能力:同形字 URL / pipe-to-interpreter / terminal injection
- 自动安装:后台线程下载 + SHA-256 校验 + Cosign 签名验证
- Fail-Open vs Fail-Closed:默认 fail-open(可用性优先)
- 与 DANGEROUS_PATTERNS 协同:单一审批提示,合并所有警告
- [讲师备注: 展示 Tirith 的调用方式和输出格式]
Slide 90: Gateway 异步审批
- 问题:Agent 在线程池中运行,不能阻塞在 input()
- 解决:_ApprovalEntry + threading.Event + 回调通知
- 流程:Agent 线程创建审批请求 -> 回调通知用户 -> 用户 /approve 或 /deny
- 超时:300 秒未响应自动拒绝
- 并发支持:每个 Agent 线程独立审批,FIFO 解决
- [讲师备注: 画出 Gateway 异步审批的完整时序图]
Slide 91: 检查点系统 — Shadow Git
- CheckpointManager(tools/checkpoint_manager.py)
- Shadow Git 仓库:独立于用户项目的 git 仓库
- 路径确定性:SHA-256(工作目录)[:16]
- 透明性:通过 GIT_DIR / GIT_WORK_TREE 环境变量隔离
- 触发时机:每轮首次文件修改前自动创建
- [讲师备注: 解释为什么用 Shadow Git 而非简单的文件备份]
Slide 92: 检查点 — 回滚与安全
- 回滚粒度:整个目录 / 单个文件 / 预览差异
- 安全验证:commit hash 格式校验 + 文件路径防遍历 + 回滚前创建新快照
- 排除规则:node_modules / .env / pycache / .git / .venv
- 文件上限:_MAX_FILES = 50,000
- 用户交互:/rollback / /rollback
/ /rollback diff - [讲师备注: 演示 /rollback 命令的使用]
Module 6: 高级特性 + 运维(15 slides)
Slide 93: Module 6 开场 — 子 Agent 委派架构
- delegate_task 工具(tools/delegate_tool.py)
- 隔离设计:独立上下文 + 独立终端会话 + 受限工具集
- 并行执行:ThreadPoolExecutor,默认最大 3 个并发子 Agent
- 深度限制:MAX_DEPTH = 2(parent -> child -> 不允许 grandchild)
- [讲师备注: 展示 diagrams 中的子 Agent 委派架构图]
Slide 94: 子 Agent — 工具集控制与凭证
- 工具过滤:移除 delegate/clarify/memory/send_message/execute_code
- 凭证池轮转:子 Agent 共享父 Agent 的凭证池,租约机制
- 心跳机制:每 30 秒向父 Agent 报告活跃状态,防止不活跃超时
- 进度回调:实时显示子 Agent 的工具调用(CLI 树状 / Gateway 批量)
- [讲师备注: 解释为什么禁止这些工具 — 每个都有明确的隔离理由]
Slide 95: 子 Agent — 结果格式与工具名恢复
- 结构化结果:status / summary / api_calls / duration / tokens / tool_trace
- 工具追踪:tool_call_id 正确配对并行调用与结果
- 全局工具名恢复:构建子 Agent 前后保存/恢复
_last_resolved_tool_names - 委派凭证路由:子 Agent 可使用不同的 provider 和模型
- [讲师备注: 展示一个完整的委派结果 JSON 示例]
Slide 96: 定时任务系统 — Cron 调度器
- cron/scheduler.py:基于 tick 的调度器,Gateway 每 60 秒调用
- 文件锁防并发:fcntl.flock 非阻塞排他锁
- Cron 表达式:标准格式(
0 9 * * 1-5) - 预运行脚本:执行前收集数据,注入为上下文
- [讲师备注: 展示定时任务的完整配置示例]
Slide 97: 定时任务 — 投递与超时
- 投递目标:local / origin / platform / platform:chat_id / platform:label
- SILENT_MARKER:Agent 返回
[SILENT]抑制投递(无新信息时) - 不活跃超时:每 10 分钟检查,活跃工作则不终止(非总超时)
- 环境变量清理:任务完成后清理注入的环境变量
- [讲师备注: 解释不活跃超时 vs 总超时的设计选择]
Slide 98: 浏览器自动化
- 三种后端:Local Chromium / Browserbase / Browser Use
- Accessibility Tree 交互:基于文本,不依赖视觉模型
- 元素引用:
@e1/@e2精确定位 - 会话隔离:每个 task_id 独立浏览器上下文
- 操作:navigate / snapshot / click / type / scroll / back / press
- [讲师备注: 演示浏览器工具的使用,展示 Accessibility Tree 输出]
Slide 99: 智能模型路由
- 目标:简单消息路由到廉价模型,复杂消息保留主模型
- 复杂度检测:关键词 + 长度阈值 + 代码块 + URL 检测
- 保守策略:只在明确简单时路由,任何疑似复杂都保留主模型
- 配置:smart_model_routing.enabled + cheap_model
- 运行时回退:廉价模型不可用时自动回退到主模型
- [讲师备注: 展示路由判断的具体示例]
Slide 100: 部署方式对比
- 本地开发:
git clone+uv pip install+hermes chat - Docker 容器:Dockerfile + volume 挂载 + 容器内免审
- Systemd 用户服务:loginctl enable-linger + systemctl --user
- Nix 部署:NixOS 模块化配置
- Modal 云沙箱:弹性计算 + 按需付费
- [讲师备注: 根据学员场景推荐合适的部署方式]
Slide 101: Systemd 用户服务配置
- 服务文件:
~/.config/systemd/user/hermes-gateway.service - 关键配置:Restart=on-failure / RestartSec=5
- loginctl enable-linger:用户注销后服务继续运行
- 日志查看:journalctl --user -u hermes-gateway -f
- Nginx 反向代理:HTTPS + WebSocket 支持
- [讲师备注: 现场展示服务配置和启停操作]
Slide 102: 日志管理与监控
- 日志目录:
~/.hermes/logs/ - 日志文件:gateway.log / agent.log / cron.log
- 日志轮转:logrotate 配置(daily + rotate 30 + compress)
- 资源监控:磁盘空间 / 会话数据库大小 / 内存使用 / CPU 使用
- 进度通知:tool_progress_callback + 心跳机制
- [讲师备注: 展示实际日志内容和监控命令]
Slide 103: 更新与维护流程
- 标准更新:
git pull+uv pip install -e ".[all]"+systemctl --user restart - 记忆保护:MEMORY.md / USER.md 不会被覆盖
- 配置兼容:config.yaml 不被覆盖,注意新版本新配置项
- 会话管理:/new / /reset / /compact / /resume 命令
- [讲师备注: 强调更新前备份 config.yaml]
Slide 104: 生产环境 Checklist
- API Key 安全:.env 权限 600 / 专用 Key / 定期轮换
- 审批模式:smart 或 off / 超时配置
- 网络安全:Nginx 反代 / HTTPS / 防火墙 / force_ipv4
- 日志轮转:logrotate / 敏感信息脱敏
- 备份策略:config.yaml / memories/ / skills/ / sessions/
- [讲师备注: 让学员对照 Checklist 检查自己的部署]
Slide 105: 常见问题排查
- 认证失败:API Key 配置 / .env 格式 / provider 配置
- 端口冲突:ss -tlnp / lsof / HERMES_PORT
- 上下文溢出:压缩配置 / threshold_percent / SOUL.md 大小
- Agent 卡死:进程检查 / CPU 内存 / 活动追踪 / 审批等待
- Cron 失败:表达式格式 / 投递目标 / 文件锁残留
- [讲师备注: 分享实际遇到的案例和解决方法]
Slide 106: 课程总结与后续资源
- 核心概念回顾:三层架构 / 工具调用循环 / IterationBudget / 纵深防御
- 实操回顾:自定义工具 / 飞书接入 / Hook 编写 / 技能开发
- 进阶方向:子 Agent 委派 / 浏览器自动化 / Cron 任务 / MCP 扩展
- 参考资源:源码位置 / 文档目录 / 社区链接
- 反馈收集:课程评价表
- [讲师备注: 感谢学员参与,留下联系方式,鼓励加入社区]