提示词组装
Hermes 明确区分了:
- 缓存的系统提示状态
- 仅在 API 调用时临时添加的内容
这是该项目最重要的设计决策之一,因为它影响:
- token 使用量
- 提示词缓存效率
- 会话连续性
- 记忆正确性
主要文件:
run_agent.pyagent/prompt_builder.pytools/memory_tool.py
缓存的系统提示层
缓存的系统提示按以下顺序组装:
- Agent 身份 —— 若
HERMES_HOME下存在SOUL.md,则使用该文件;否则回退至prompt_builder.py中的DEFAULT_AGENT_IDENTITY - 工具感知行为指导
- Honcho 静态块(当启用时)
- 可选的系统消息
- 冻结的 MEMORY 快照
- 冻结的 USER 配置文件快照
- 技能索引
- 上下文文件(
AGENTS.md、.cursorrules、.cursor/rules/*.mdc)—— 若第 1 步已加载SOUL.md作为身份,则此处不再包含SOUL.md - 时间戳 / 可选会话 ID
- 平台提示
当设置 skip_context_files 时(例如子 Agent 委派),SOUL.md 不会被加载,而是直接使用硬编码的 DEFAULT_AGENT_IDENTITY。
具体示例:组装后的系统提示
以下是所有层均存在时最终系统提示的简化视图(注释标明各部分来源):
# 第 1 层:Agent 身份(来自 `~/.hermes/SOUL.md`)
You are Hermes, an AI assistant created by Nous Research.
You are an expert software engineer and researcher.
You value correctness, clarity, and efficiency.
...
# 第 2 层:Tool 感知行为指导
You have persistent memory across sessions. Save durable facts using
the memory tool: user preferences, environment details, tool quirks,
and stable conventions. Memory is injected into every turn, so keep
it compact and focused on facts that will still matter later.
...
When the user references something from a past conversation or you
suspect relevant cross-session context exists, use session_search
to recall it before asking them to repeat themselves.
# Tool-使用强制执行(仅适用于 GPT/Codex models)
You MUST use your tools to take action — do not describe what you
would do or plan to do without actually doing it.
...
# 第 3 层:Honcho 静态块(激活时)
[Honcho personality/context data]
# 第 4 层:可选系统消息(来自配置或 API)
[User-configured system message override]
# 第 5 层:冻结 MEMORY 快照
## 持久 Memory
- User prefers Python 3.12, uses pyproject.toml
- Default editor is nvim
- Working on project "atlas" in ~/code/atlas
- Timezone: US/Pacific
# 第 6 层:冻结 USER profile 快照
## 用户 Profile
- Name: Alice
- GitHub: alice-dev
# 第 7 层:Skills 索引
## Skills(必填)
Before replying, scan the skills below. If one clearly matches
your task, load it with skill_view(name) and follow its instructions.
...
<available_skills>
software-development:
- code-review: Structured code review workflow
- test-driven-development: TDD methodology
research:
- arxiv: Search and summarize arXiv papers
</available_skills>
# 第 8 层:Context 文件(来自项目目录)
# 项目上下文
The following project context files have been loaded and should be followed:
## AGENTS.md
This is the atlas project. Use pytest for testing. The main
entry point is src/atlas/main.py. Always run `make lint` before
committing.
# 第9层:时间戳+session
Current time: 2026-03-30T14:30:00-07:00
Session: abc123
# 第10层:平台提示
You are a CLI AI Agent. Try not to use markdown but simple text
renderable inside a terminal.
SOUL.md 在提示词中的呈现方式
SOUL.md 位于 ~/.hermes/SOUL.md,作为 Agent 的身份标识 —— 系统提示的最开始部分。prompt_builder.py 中的加载逻辑如下:
# 来自代理/prompt_builder.py(简体)
def load_soul_md() -> Optional[str]:
soul_path = get_hermes_home() / "SOUL.md"
if not soul_path.exists():
return None
content = soul_path.read_text(encoding="utf-8").strip()
content = _scan_context_content(content, "SOUL.md") # 安全扫描
content = _truncate_content(content, "SOUL.md") # 上限为 20k 字符
return content
当 load_soul_md() 返回内容时,它将替换硬编码的 DEFAULT_AGENT_IDENTITY。随后调用 build_context_files_prompt() 并传入 skip_soul=True,以防止 SOUL.md 被重复出现(一次作为身份,一次作为上下文文件)。
若 SOUL.md 不存在,则系统回退至:
You are Hermes Agent, an intelligent AI assistant created by Nous Research.
You are helpful, knowledgeable, and direct. You assist users with a wide
range of tasks including answering questions, writing and editing code,
analyzing information, creative work, and executing actions via your tools.
You communicate clearly, admit uncertainty when appropriate, and prioritize
being genuinely useful over being verbose unless otherwise directed below.
Be targeted and efficient in your exploration and investigations.
上下文文件的注入方式
build_context_files_prompt() 使用 优先级系统 —— 仅加载一种项目上下文类型(首个匹配项胜出):
# 来自代理/prompt_builder.py(简体)
def build_context_files_prompt(cwd=None, skip_soul=False):
cwd_path = Path(cwd).resolve()
# 优先级:第一场比赛获胜 - 仅加载 ONE 项目 context
project_context = (
_load_hermes_md(cwd_path) # 1. .hermes.md / HERMES.md(走到 git 根目录)
or _load_agents_md(cwd_path) # 2. AGENTS.md(仅限 cwd)
or _load_claude_md(cwd_path) # 3. CLAUDE.md(仅限cwd)
or _load_cursorrules(cwd_path) # 4. .cursorrules / .cursor/rules/*.mdc
)
sections = []
if project_context:
sections.append(project_context)
# `SOUL.md` 来自 `HERMES_HOME`(独立于项目上下文)
if not skip_soul:
soul_content = load_soul_md()
if soul_content:
sections.append(soul_content)
if not sections:
return ""
return (
"# Project Context\n\n"
"The following project context files have been loaded "
"and should be followed:\n\n"
+ "\n".join(sections)
)
上下文文件发现细节
| 优先级 | 文件 | 搜索范围 | 说明 |
|---|---|---|---|
| 1 | .hermes.md、HERMES.md | 从当前工作目录向上至 git 仓库根目录 | Hermes 原生项目配置 |
| 2 | AGENTS.md | 仅当前工作目录 | 常见的 Agent 指令文件 |
| 3 | CLAUDE.md | 仅当前工作目录 | Claude Code 兼容性 |
| 4 | .cursorrules、.cursor/rules/*.mdc | 仅当前工作目录 | Cursor 兼容性 |
所有上下文文件均经过:
- 安全扫描 —— 检查提示注入模式(不可见 Unicode、"忽略先前指令"、凭证外泄尝试)
- 截断处理 —— 使用 70/20 头尾比例,上限 20,000 字符,并添加截断标记
- 移除 YAML 前置元数据 ——
.hermes.md的前置元数据将被移除(保留用于未来配置覆盖)
仅在 API 调用时生效的层
这些内容不会作为缓存系统提示的一部分持久化:
ephemeral_system_prompt- 预填充消息
- 网关派生的会话上下文叠加层
- 后续轮次 Honcho 回忆注入到当前轮次用户消息中
这种分离确保了稳定前缀的稳定性,便于缓存。
记忆快照
本地记忆和用户配置文件数据在会话开始时作为冻结快照注入。会话中段的写入会更新磁盘状态,但不会修改已构建的系统提示,直到新会话或强制重建发生。
上下文文件
agent/prompt_builder.py 使用 优先级系统 扫描并净化项目上下文文件 —— 仅加载一种类型(首个匹配项胜出):
.hermes.md/HERMES.md(从当前目录向上遍历至 git 根目录)AGENTS.md(启动时仅在当前工作目录;会话期间通过agent/subdirectory_hints.py逐步发现子目录)CLAUDE.md(仅当前工作目录).cursorrules/.cursor/rules/*.mdc(仅当前工作目录)
SOUL.md 通过 load_soul_md() 单独加载,用于身份槽位。若加载成功,则调用 build_context_files_prompt(skip_soul=True) 以防止其重复出现。
长文件在注入前会被截断。
技能索引
当可用技能工具时,技能系统会向提示词中添加一个紧凑的技能索引。
为何提示词组装采用此方式
该架构有意优化以实现:
- 保留提供商端的提示词缓存
- 避免不必要的历史变更
- 保持记忆语义清晰可理解
- 允许网关/ACP/CLI 添加上下文,而不污染持久化提示状态