跳到主要内容

提示组装

Hermes 刻意分离了:

  • 缓存的系统提示状态
  • 临时 API 调用时添加

这是项目中最重要的设计选择之一,因为它影响:

  • token 使用量
  • 提示缓存效果
  • 会话连续性
  • 记忆正确性

主要文件:

  • run_agent.py
  • agent/prompt_builder.py
  • tools/memory_tool.py

缓存的系统提示层

缓存的系统提示大致按此顺序组装:

  1. Agent 身份 — 来自 HERMES_HOMESOUL.md(如果有),否则回退到 prompt_builder.py 中的 DEFAULT_AGENT_IDENTITY
  2. 工具感知行为指导
  3. Honcho 静态块(当活跃时)
  4. 可选系统消息
  5. 冻结的 MEMORY 快照
  6. 冻结的 USER profile 快照
  7. 技能索引
  8. 上下文文件(AGENTS.md.cursorrules.cursor/rules/*.mdc)— 当 SOUL.md 已作为身份在步骤1加载时,包括在此处
  9. 时间戳 / 可选会话 ID
  10. 平台提示

当设置 skip_context_files 时(例如子 Agent 委托),SOUL.md 不会被加载,而是使用硬编码的 DEFAULT_AGENT_IDENTITY

具体示例:组装后的系统提示

以下是一个简化视图,展示了当所有层都存在时最终系统提示的样子(注释显示每个部分的来源):

# Layer 1: Agent Identity (from ~/.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.
...

# Layer 2: Tool-aware behavior guidance
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 yourself.

# Tool-use enforcement (for GPT/Codex models only)
You MUST use your tools to take action — do not describe what you
would do or plan to do without actually doing it.
...

# Layer 3: Honcho static block (when active)
[Honcho personality/context data]

# Layer 4: Optional system message (from config or API)
[User-configured system message override]

# Layer 5: Frozen MEMORY snapshot
## Persistent Memory
- User prefers Python 3.12, uses pyproject.toml
- Default editor is nvim
- Working on project "atlas" in ~/code/atlas
- Timezone: US/Pacific

# Layer 6: Frozen USER profile snapshot
## User Profile
- Name: Alice
- GitHub: alice-dev

# Layer 7: Skills index
## Skills (mandatory)
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>

# Layer 8: Context files (from project directory)
# Project 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.

# Layer 9: Timestamp + session
Current time: 2026-03-30T14:30:00-07:00
Session: abc123

# Layer 10: Platform hint
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 中的加载逻辑如下:

# From agent/prompt_builder.py (simplified)
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") # Security scan
content = _truncate_content(content, "SOUL.md") # Cap at 20k chars
return content

load_soul_md() 返回内容时,它会替换硬编码的 DEFAULT_AGENT_IDENTITY。然后使用 skip_soul=True 调用 build_context_files_prompt() 函数,以防止 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() 使用优先级系统 — 只加载一种项目上下文(先到先得):

# From agent/prompt_builder.py (simplified)
def build_context_files_prompt(cwd=None, skip_soul=False):
cwd_path = Path(cwd).resolve()

# Priority: first match wins — only ONE project context loaded
project_context = (
_load_hermes_md(cwd_path) # 1. .hermes.md / HERMES.md (walks to git root)
or _load_agents_md(cwd_path) # 2. AGENTS.md (cwd only)
or _load_claude_md(cwd_path) # 3. CLAUDE.md (cwd only)
or _load_cursorrules(cwd_path) # 4. .cursorrules / .cursor/rules/*.mdc
)

sections = []
if project_context:
sections.append(project_context)

# SOUL.md from HERMES_HOME (independent of project context)
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.mdCWD 向上到 git 根目录Hermes 原生项目配置
2AGENTS.md仅 CWD常见 agent 指令文件
3CLAUDE.md仅 CWDClaude Code 兼容性
4.cursorrules, .cursor/rules/*.mdc仅 CWDCursor 兼容性

所有上下文文件都:

  • 安全扫描 — 检查提示注入模式(隐形 unicode、"忽略先前指令"、凭证泄露尝试)
  • 截断 — 使用 70/20 头/尾比截断到 20,000 字符
  • 剥离 YAML frontmatter.hermes.md frontmatter 被移除(保留供将来配置覆盖)

API 调用时专属层

这些有意作为缓存系统提示的一部分持久化:

  • ephemeral_system_prompt
  • prefill 消息
  • 网关派生的会话上下文覆盖
  • 后续轮次中注入当前轮次用户消息的 Honcho 召回

这种分离保持了稳定前缀的稳定以供缓存。

记忆快照

本地记忆和用户 profile 数据在会话开始时作为冻结快照注入。中会话写入会更新磁盘状态,但不会改变已构建的系统提示,直到新会话或强制重建发生。

上下文文件

agent/prompt_builder.py 使用优先级系统扫描和清理项目上下文文件 — 只加载一种类型(先到先得):

  1. .hermes.md / HERMES.md(向上走到 git 根目录)
  2. AGENTS.md(启动时的 CWD;子目录在会话期间通过 agent/subdirectory_hints.py 逐步发现)
  3. CLAUDE.md(仅 CWD)
  4. .cursorrules / .cursor/rules/*.mdc(仅 CWD)

SOUL.md 通过 load_soul_md() 单独加载到身份槽。当它成功加载时,build_context_files_prompt(skip_soul=True) 防止它出现两次。

长文件在注入前被截断。

技能索引

当技能工具可用时,技能系统向提示贡献一个紧凑的技能索引。

为什么提示组装这样拆分

架构有意优化以:

  • 保持提供者端提示缓存
  • 避免不必要地改变历史
  • 保持记忆语义可理解
  • 让网关/ACP/CLI 添加上下文而不污染持久提示状态

相关文档