Hermes Agent 深度解析:47K Star 的自进化 AI 智能体框架——从 GEPA 进化引擎到跨会话持久记忆的全链路技术实战
当所有 AI 助手都在比拼"谁答得更快"时,Hermes Agent 选择了一条没人走过的路——让 AI 自己学会做事。这不是又一个大模型套壳,而是一套从记忆到技能、从进化到部署的完整智能体工程体系。
一、引言:为什么 AI 助手越用越蠢?
你有没有过这种体验?
第一天跟 ChatGPT 说"我是后端开发者,偏好 Go 语言",它记得清清楚楚。第二天再聊,它问你喜欢用什么语言。你把一段代码调试经验告诉 Claude,它当时说"明白了",下次遇到同样的问题,它从零开始分析。
这不是个别产品的缺陷,而是整个 AI 助手行业的结构性问题——无状态架构。每次对话从零开始,没有记忆,没有积累,没有成长。你用了一年的 AI 助手和用了一天的新用户,得到的服务没有任何区别。
2026 年 2 月,Nous Research 发布了 Hermes Agent,用一句话定义了它的核心定位:"The agent that grows with you"——与你一起成长的智能体。这不是营销话术,而是由底层架构决定的必然结果。
在 GitHub 上,Hermes Agent 上线两个月就冲到 47,000+ Star,月趋势榜稳居第一。国内开发者给它取了个外号——"爱马仕",因为 Hermes 恰好和奢侈品牌同名。但这个外号倒也贴切:在所有 AI Agent 框架里,Hermes Agent 确实是那个最"奢侈"的存在——它奢侈地给 AI 装上了记忆、学习能力和自我进化系统。
本文将从架构设计、核心机制、代码实战、部署运维到性能优化,对 Hermes Agent 做一次完整的深度拆解。看完这篇文章,你不仅知道 Hermes Agent 是什么,更知道它为什么这样设计、怎么在生产环境跑起来、以及如何榨干它的全部能力。
二、背景:AI Agent 的三次范式跃迁
2.1 从聊天机器人到智能体
AI 助手的演进可以分为三个阶段:
第一阶段:对话式助手(2022-2024)。以 ChatGPT 为代表,核心能力是"一问一答"。用户输入 prompt,模型返回回答。没有记忆,没有工具,没有自主行动能力。这本质上是一个更智能的搜索引擎。
第二阶段:工具增强型助手(2024-2025)。以 Claude with Tools、GPT with Function Calling 为代表。AI 可以调用外部工具——搜索网页、执行代码、操作文件。但依然是无状态的:工具调用的结果不会自动沉淀为经验,下次遇到类似问题还要从头来过。
第三阶段:自主进化型智能体(2026-)。Hermes Agent 就是这个阶段的代表。它的核心突破在于三个字:学得会。完成一次复杂任务后,它会自动把解决方案提炼成技能文件;解决过的问题,下次直接调用技能,不再从头分析;使用的次数越多,积累的技能越多,能力越强。
2.2 Nous Research:从模型到智能体的战略跃迁
Nous Research 成立于 2023 年,总部在加州 Saratoga,由 Jeffrey Quesnelle 创立。2026 年初完成 Paradigm 领投的 5000 万美元 A 轮融资,估值 10 亿美元。
在 Hermes Agent 之前,Nous Research 最知名的产品是 Hermes 系列开源模型(Hermes-2、Hermes-3 等),在 Hugging Face 上累计下载量超过数千万次。他们从模型训练起家,对大模型的能力边界有着极其深刻的理解。
正是这种理解,让他们做出了一个关键判断:大模型的对话能力已经足够强了,瓶颈不在模型本身,而在使用模型的方式。聊天机器人的交互范式已经触顶——你永远无法通过更好的 prompt,让一个没有记忆的系统产生真正的智能行为。
于是 Hermes Agent 诞生了。它不是一个新模型,而是一个让现有模型"活起来"的运行时框架。
2.3 竞品格局:为什么是 Hermes Agent?
2026 年的 AI Agent 赛道已经非常拥挤。OpenClaw、Cline、Cursor Agent、Devin、AutoGPT……每个都在解决不同的问题。Hermes Agent 的差异化在于一个根本性的技术选择:自进化。
| 维度 | Hermes Agent | OpenClaw | AutoGPT | Cline |
|---|---|---|---|---|
| 跨会话记忆 | FTS5 全文搜索 + LLM 摘要 | 工作区文件 | 无 | 无 |
| 技能学习 | 自动生成与自我改进 | 手动 Skill.md | 无 | 无 |
| 自我优化 | GEPA 进化引擎 | 无 | 无 | 无 |
| 消息平台 | 15+ 网关接入 | 多通道 | 终端为主 | VS Code |
| 模型支持 | 200+ 一键切换 | 多模型 | GPT 为主 | Claude 为主 |
| 部署方案 | 6 种后端 | Docker 为主 | Docker | VS Code 插件 |
Hermes Agent 选择了"学习深度"这个维度做极致优化。它不追求单次任务的峰值表现,而是追求长期使用后的累积优势。用得越久,它越懂你;解决的问题越多,它的技能库越丰富。这是一个典型的复利效应。
三、架构设计:六个技术支柱
Hermes Agent 的架构由六个核心模块组成,每个模块解决一个关键问题。这六个模块不是简单堆叠,而是形成了紧密耦合的进化闭环。
3.1 GEPA 自我进化引擎
GEPA 是 Hermes Agent 最核心的模块,也是它区别于所有同类框架的根本。GEPA 全称是 Gradient Estimation via Prompt Adaptation(通过 Prompt 适配的梯度估计),由 UC Berkeley、Stanford 和 MIT 的研究者联合开发。
传统强化学习需要上万次评估才能收敛,这在 LLM 场景下是不现实的——每次评估都要调用一次 API,成本和时间都无法承受。GEPA 的突破在于:它用一种类似反向传播的方式来优化 prompt,只需要 100 到 500 次评估就能完成策略迭代。
GEPA 的工作流程分为四个阶段:
- 行为记录(Behavior Recording):Hermes Agent 记录每次任务执行的完整过程——输入、决策、工具调用、输出、结果评估。
- 效果评估(Performance Evaluation):根据任务结果评估当前策略的效果。评估维度包括任务完成率、准确率、效率等。
- 策略优化(Policy Optimization):GEPA 通过 prompt 适配来优化策略。它不会修改模型的权重,而是调整传递给模型的指令模板,让模型在相同的输入下产生更优的输出。
- 技能沉淀(Skill Consolidation):优化后的策略被提炼为技能文件,存入技能库供未来复用。
让我用一段伪代码来说明 GEPA 的核心逻辑:
# GEPA 自我进化引擎的简化工作流
class GEPAEngine:
def __init__(self, llm_client, skill_registry, memory_store):
self.llm = llm_client
self.skills = skill_registry
self.memory = memory_store
self.evaluation_history = []
def execute_with_evolution(self, task: str, context: dict) -> dict:
"""带进化能力的任务执行"""
# 1. 检索相关技能和历史经验
relevant_skills = self.skills.search(task, top_k=3)
relevant_memory = self.memory.search(task, top_k=5)
# 2. 构建增强 prompt(融合技能 + 记忆 + 当前任务)
enhanced_prompt = self.build_prompt(
task=task,
skills=relevant_skills,
memory=relevant_memory,
strategy=self.current_strategy
)
# 3. 执行任务
result = self.llm.execute(enhanced_prompt, tools=context.get("tools"))
# 4. 评估结果
evaluation = self.evaluate(task, result)
self.evaluation_history.append(evaluation)
# 5. 如果评估不达标,触发策略优化
if evaluation.score < self.evolution_threshold:
self.optimize_strategy(task, evaluation)
# 6. 如果任务成功,沉淀为技能
if evaluation.success and evaluation.is_complex:
skill = self.consolidate_skill(task, result, evaluation)
self.skills.register(skill)
# 7. 持久化重要经验到记忆
if evaluation.has_lessons:
self.memory.persist(task, evaluation.lessons)
return result
def optimize_strategy(self, task: str, evaluation: Evaluation):
"""GEPA 核心:通过 prompt 适配优化策略"""
# 分析失败原因
failure_analysis = self.llm.analyze_failure(
task=task,
attempt=evaluation.trace,
error=evaluation.error_info
)
# 生成策略变体(类似梯度下降中的参数更新)
strategy_variants = self.generate_variants(
current=self.current_strategy,
gradient=failure_analysis.gradient_direction,
learning_rate=self.adaptive_lr()
)
# 选择最优变体
best_variant = self.select_best(strategy_variants)
self.current_strategy = best_variant
def adaptive_lr(self) -> float:
"""自适应学习率:根据近期评估结果动态调整"""
if len(self.evaluation_history) < 10:
return 0.1 # 初期大步探索
recent_scores = [e.score for e in self.evaluation_history[-10:]]
variance = np.var(recent_scores)
if variance > 0.3:
return 0.02 # 高方差时小步调整
return 0.05 # 低方差时适度调整
关键设计决策:GEPA 选择优化 prompt 而非模型权重,这是一个深思熟虑的工程选择。优化模型权重需要大量 GPU 资源和训练数据,而 prompt 适配只需要少量评估就能收敛。更重要的是,prompt 适配的结果是可解释的——你可以直接看到策略是怎么变化的,而权重变化是黑盒。
3.2 持久记忆架构
Hermes Agent 的记忆系统是它"不健忘"的根本原因。传统 AI 助手是无状态的,对话结束一切归零。Hermes Agent 通过两个自主管理的文件实现跨会话记忆:
- MEMORY.md:存储环境事实和经验教训。比如"用户的开发环境是 macOS + Go 1.23"、"上次部署时遇到了 SSL 证书问题,解决方案是……"
- USER.md:存储用户偏好。比如"偏好简洁的代码风格"、"习惯用 TDD 方式开发"、"讨厌依赖过多的第三方库"
底层实现是 SQLite FTS5 全文搜索配合 LLM 摘要。让我深入看看这个记忆系统的工作机制:
# Hermes Agent 记忆系统的核心实现逻辑
class PersistentMemory:
"""
持久记忆系统:基于 SQLite FTS5 + LLM 摘要
"""
def __init__(self, data_dir: str = "~/.hermes/memories"):
self.db_path = os.path.join(data_dir, "memory.db")
self._init_fts5()
# 记忆文件
self.memory_md = os.path.join(data_dir, "MEMORY.md")
self.user_md = os.path.join(data_dir, "USER.md")
def _init_fts5(self):
"""初始化 FTS5 全文搜索索引"""
conn = sqlite3.connect(self.db_path)
conn.execute("""
CREATE VIRTUAL TABLE IF NOT EXISTS memory_index
USING fts5(
content,
timestamp,
category,
importance,
tokenize='unicode61'
)
""")
conn.commit()
conn.close()
def store(self, content: str, category: str = "general",
importance: float = 0.5):
"""存储一条记忆"""
# 1. Prompt 注入安全扫描
if self._detect_injection(content):
logger.warning("检测到潜在 prompt 注入,已拦截")
return False
# 2. LLM 摘要压缩
summary = self.llm.summarize(content, max_tokens=200)
# 3. 写入 FTS5 索引
conn = sqlite3.connect(self.db_path)
conn.execute(
"INSERT INTO memory_index VALUES (?, ?, ?, ?)",
(summary, time.time(), category, importance)
)
conn.commit()
conn.close()
# 4. 同步更新 MEMORY.md 文件
self._append_to_memory_md(summary, category, importance)
return True
def search(self, query: str, top_k: int = 5) -> list[MemoryEntry]:
"""语义检索相关记忆"""
conn = sqlite3.connect(self.db_path)
# FTS5 全文搜索 + BM25 排序
cursor = conn.execute("""
SELECT content, timestamp, category, importance,
bm25(memory_index) as rank
FROM memory_index
WHERE memory_index MATCH ?
ORDER BY rank
LIMIT ?
""", (query, top_k))
results = []
for row in cursor:
results.append(MemoryEntry(
content=row[0],
timestamp=row[1],
category=row[2],
importance=row[3],
relevance_score=-row[4] # BM25 分数越低越相关
))
conn.close()
return results
def consolidate(self):
"""
记忆整理:定期执行,类似人类的睡眠整理过程
- 合并重复记忆
- 提升高频记忆的重要性
- 衰减过时记忆
- 更新 MEMORY.md 和 USER.md
"""
conn = sqlite3.connect(self.db_path)
# 1. 查找语义重复的记忆
all_memories = conn.execute(
"SELECT rowid, content FROM memory_index"
).fetchall()
duplicates = self._find_duplicates(all_memories)
# 2. 合并重复记忆,保留最完整的版本
for group in duplicates:
best = max(group, key=lambda x: len(x.content))
for dup in group:
if dup.id != best.id:
conn.execute(
"DELETE FROM memory_index WHERE rowid=?",
(dup.id,)
)
# 将被删除记忆的独特信息合并到最佳版本
best.content = self.llm.merge(best.content, dup.content)
conn.execute(
"UPDATE memory_index SET content=? WHERE rowid=?",
(best.content, best.id)
)
# 3. 重要性衰减
conn.execute("""
UPDATE memory_index
SET importance = importance * 0.95
WHERE timestamp < ?
""", (time.time() - 30 * 86400,)) # 30天前的记忆衰减
# 4. 重建 MEMORY.md 和 USER.md
self._rebuild_memory_files(conn)
conn.commit()
conn.close()
def _detect_injection(self, content: str) -> bool:
"""Prompt 注入检测"""
suspicious_patterns = [
r"ignore\s+(previous|all)\s+instructions",
r"you\s+are\s+now\s+",
r"system\s*prompt",
r"<\/?system>",
r"jailbreak",
r"DAN\s+mode",
]
for pattern in suspicious_patterns:
if re.search(pattern, content, re.IGNORECASE):
return True
return False
这个记忆系统的几个关键设计点值得深入分析:
FTS5 vs 向量数据库的选择。Hermes Agent 选择 SQLite FTS5 而非 Pinecone、Milvus 等向量数据库,这是一个务实的工程选择。FTS5 是 SQLite 内置的全文搜索引擎,零外部依赖,单文件存储,天然适合单机部署场景。对于个人智能体的记忆规模(通常在万条级别),FTS5 的检索性能完全够用,而且避免了向量数据库的运维复杂度。
LLM 摘要压缩。每条记忆在存储前都经过 LLM 摘要压缩,控制在 200 token 以内。这避免了记忆库无限膨胀的问题,同时保留了关键信息。摘要的质量直接影响后续检索的效果——Hermes Agent 在这里做了大量 prompt 工程,确保摘要既简洁又不丢失关键信息。
定期整理机制。记忆不是只进不出,Hermes Agent 会定期执行"记忆整理",类似人类睡眠时大脑整理记忆的过程。合并重复记忆、衰减过时记忆、提升高频记忆的重要性。这确保了记忆库的质量不会随时间退化。
安全扫描。在记忆写入前进行 prompt 注入检测。这是一个容易被忽视但极其重要的安全措施——如果攻击者能通过对话让 AI 把恶意指令写入记忆,那么这些指令会在后续所有会话中被执行,造成持久性的安全威胁。
3.3 技能自动学习系统
技能系统是 Hermes Agent "越用越聪明"的直接体现。当你完成一个复杂任务后,Hermes Agent 会自动将解决方案提炼为 Markdown 格式的技能文件,遵循 agentskills.io 开放标准。
技能采用渐进式披露设计——三层信息架构:
- Level 0(~3000 tokens):技能概要,包含名称、描述、触发条件。这是每次检索时加载的内容,确保不会占用过多上下文。
- Level 1:完整技能内容,包含详细步骤、代码示例、注意事项。只在技能被触发时加载。
- Level 2:深入参考材料,包含边界情况、性能数据、替代方案。在需要深入了解时按需加载。
# 示例:一个自动生成的技能文件
---
name: go-project-ci-setup
version: 1.2.0
author: hermes-agent
created: 2026-04-15
trigger:
- "Go 项目 CI 配置"
- "Go GitHub Actions"
- "golangci-lint CI"
level_0_tokens: 2800
---
## 概要(Level 0)
为 Go 项目配置完整的 CI/CD 流水线,包括 golangci-lint 代码检查、
单元测试、集成测试、代码覆盖率报告和自动发布。
适用于:Go 1.21+、GitHub Actions、多模块项目。
## 详细步骤(Level 1)
### 1. 创建 GitHub Actions 工作流
```yaml
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.57
args: --timeout=5m
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.23'
- name: Run tests
run: go test -race -coverprofile=coverage.out ./...
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: coverage.out
2. 配置 golangci-lint
# .golangci.yml
run:
timeout: 5m
modules-download-mode: readonly
linters:
enable:
- errcheck
- govet
- staticcheck
- unused
- gosimple
- ineffassign
- typecheck
- gocritic
- gofmt
- goimports
issues:
max-issues-per-linter: 50
max-same-issues: 3
3. 注意事项
- 多模块项目需在根目录添加
go.work文件 - 覆盖率阈值建议设置在 60%-80%,避免过高要求阻碍开发
- golangci-lint 首次运行较慢,后续有缓存加速
深入参考(Level 2)
边界情况
- CGO 项目:需要
CGO_ENABLED=1,运行环境需安装 gcc - 私有模块:需配置
GOPRIVATE环境变量和 Git 认证 - 大仓库:考虑使用
paths-filter只检测变更的模块
性能数据
| 指标 | 数值 |
|---|---|
| lint 首次运行 | ~45s (中等项目) |
| lint 增量运行 | ~8s (有缓存) |
| 测试运行 | 取决于项目规模 |
替代方案
- GitLab CI:使用
.gitlab-ci.yml,语法类似但 Runner 配置不同 - CircleCI:支持 Docker 层缓存,适合复杂构建流程
技能的自我改进机制同样值得关注。当一个技能被多次使用后,Hermes Agent 会收集每次使用的效果数据——成功率、用户反馈、边界情况——然后用这些数据来改进技能的内容。比如,如果某个技能在处理 CGO 项目时经常失败,Hermes Agent 会自动在技能中补充 CGO 相关的注意事项和解决方案。
### 3.4 多模型零锁定架构
Hermes Agent 支持 200+ 种大语言模型,通过 OpenRouter 一个密钥即可路由到几乎所有主流模型。对于本地场景,兼容 Ollama、vLLM、SGLang 等推理引擎。
切换模型只需一条命令:
```bash
# 交互式选择模型
hermes model
# 直接指定模型
hermes chat --model claude-sonnet-4
hermes chat --model openrouter:anthropic/claude
hermes chat --model custom:qwen-2.5
# 在会话中切换
/model gpt-4o
/model deepseek-v3
这个设计的核心思想是模型无关性。Hermes Agent 的价值不在模型本身,而在于记忆、技能和进化这些模型之上的能力。这意味着你可以随时切换到更便宜或更强的模型,而不丢失任何已积累的能力。
对于国内用户,Hermes Agent 原生支持智谱 AI 和 Kimi 等国产模型,无需科学上网。这在实际使用中是一个很大的优势——很多企业场景下,访问海外 API 的网络不稳定性和合规风险是真实存在的问题。
3.5 多平台消息网关
Hermes Agent 的消息网关支持 15+ 个平台:Telegram、Discord、Slack、WhatsApp、Signal,以及飞书、钉钉、企业微信。一个网关进程即可同时接入所有平台,确保 AI 智能体在所有渠道上保持统一的记忆与人格。
# 消息网关的架构示意
class MessageGateway:
"""多平台消息网关"""
def __init__(self, config: GatewayConfig):
self.adapters = {
"telegram": TelegramAdapter(config.telegram),
"discord": DiscordAdapter(config.discord),
"slack": SlackAdapter(config.slack),
"feishu": FeishuAdapter(config.feishu),
"dingtalk": DingTalkAdapter(config.dingtalk),
"wecom": WeComAdapter(config.wecom),
"whatsapp": WhatsAppAdapter(config.whatsapp),
}
self.agent = HermesAgent(config.agent)
self.active_sessions = {}
async def run(self):
"""启动所有适配器"""
tasks = []
for name, adapter in self.adapters.items():
if adapter.enabled:
task = asyncio.create_task(
adapter.listen(self._on_message)
)
tasks.append(task)
logger.info(f"已启动 {name} 适配器")
await asyncio.gather(*tasks)
async def _on_message(self, platform: str, user_id: str,
message: str, context: dict):
"""统一消息处理入口"""
# 1. 加载用户上下文(跨平台统一)
session_key = f"{platform}:{user_id}"
session = self._get_or_create_session(session_key)
# 2. 消息安全检查
if self._is_suspicious(message):
await self._send_warning(platform, user_id)
return
# 3. 加载用户专属记忆
user_memory = self.agent.memory.load_user(user_id)
# 4. 构建 Agent 请求
request = AgentRequest(
message=message,
user_id=user_id,
platform=platform,
session=session,
user_memory=user_memory,
available_tools=self._get_tools_for_user(user_id)
)
# 5. 执行 Agent(带进化能力)
response = await self.agent.execute(request)
# 6. 发送响应到原平台
await self.adapters[platform].send(
user_id=user_id,
message=response.text,
attachments=response.attachments
)
关键设计:所有平台共享同一套记忆和技能系统。这意味着你在 Telegram 上教 Hermes Agent 的东西,它在飞书上也能记住。对于需要多渠道覆盖的企业场景,这个设计极具价值——不需要在每个平台维护独立的对话历史和配置。
3.6 企业级安全体系
Hermes Agent v0.5.0 进行了专项安全强化,合并了 200 余个安全补丁。至今保持零 CVE 记录。安全体系涵盖:
- 指令审批机制:危险操作(删除文件、发送邮件等)需要用户显式批准
- 危险模式阻挡:内置规则引擎,自动识别和拦截潜在危险行为
- Docker 容器沙箱隔离:在隔离容器中执行不可信代码
- 路径遍历防护:防止通过
../等路径操作访问敏感文件 - SSRF 缓解:限制 Agent 可以访问的网络地址范围
- 凭证管理:API 密钥等敏感信息加密存储,日志脱敏
- Prompt 注入扫描:在记忆写入前检测潜在的注入攻击
# 安全配置示例 (~/.hermes/config.yaml)
security:
# 指令审批
approval_required:
- file_delete
- email_send
- shell_execute
- network_request
# 沙箱配置
sandbox:
enabled: true
backend: docker # docker | singularity | modal
memory_limit: "2g"
cpu_limit: 2
network: restricted # restricted | isolated | full
allowed_hosts:
- api.github.com
- registry.npmjs.org
# 路径保护
path_protection:
forbidden_paths:
- /etc/shadow
- ~/.ssh
- ~/.gnupg
allowed_base_paths:
- ~/projects
- /tmp/hermes-workspace
# SSRF 防护
ssrf_protection:
blocked_ranges:
- 127.0.0.0/8
- 10.0.0.0/8
- 169.254.169.254/32 # 云元数据端点
max_redirects: 3
四、代码实战:从零搭建一个生产级 Hermes Agent
理论讲完了,现在动手。我们从安装到部署,再到自定义技能开发,完整走一遍 Hermes Agent 的使用流程。
4.1 环境安装
Hermes Agent 支持 Linux、macOS 和 WSL2(原生 Windows 不支持)。一键安装脚本会自动处理所有依赖:
# 一键安装(自动配置 Python 3.11, Node.js v22, ripgrep, ffmpeg)
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
# 刷新环境变量
source ~/.bashrc
# 验证安装
hermes --version
# 输出:hermes-agent v0.8.0
# 环境诊断
hermes doctor
# ✅ Python 3.11.8
# ✅ Node.js v22.x
# ✅ ripgrep 14.x
# ✅ ffmpeg 6.x
# ✅ SQLite 3.45 (FTS5 enabled)
如果你更偏好手动安装以精确控制依赖版本:
# 克隆仓库(含子模块)
git clone --recurse-submodules https://github.com/NousResearch/hermes-agent.git
cd hermes-agent
# 使用 uv 安装(推荐,比 pip 快 10-100 倍)
uv pip install -e ".[all]"
# 初始化配置目录
hermes init
# 创建 ~/.hermes/ 目录结构:
# ├── config.yaml 主配置文件
# ├── .env API 密钥
# ├── memories/ 持久记忆存储
# ├── skills/ 技能文件
# ├── sessions/ 会话历史
# └── logs/ 运行日志
4.2 配置 API 密钥和模型
# 方法一:命令行设置(推荐)
hermes config set OPENROUTER_API_KEY sk-or-v1-你的密钥
hermes config set ANTHROPIC_API_KEY sk-ant-你的密钥
# 方法二:直接编辑环境文件
nano ~/.hermes/.env
.env 文件内容:
# 推荐首选:一个密钥访问 200+ 模型
OPENROUTER_API_KEY=sk-or-v1-xxxxxxxx
# 直接使用 Claude(推荐生产环境,稳定性最好)
ANTHROPIC_API_KEY=sk-ant-xxxxxxxx
# OpenAI GPT 系列
OPENAI_API_KEY=sk-xxxxxxxx
# Google Gemini
GOOGLE_API_KEY=AIzaxxxxxxxx
# 国内用户推荐(无需翻墙)
ZHIPUAI_API_KEY=xxxxxxxx
KIMI_API_KEY=xxxxxxxx
# 本地模型(零 API 费用)
# 需要先安装 Ollama,然后在 hermes model 中选择 Custom Endpoint
选择模型:
# 交互式模型选择
hermes model
# 输出示例:
# ? 选择模型提供商:
# ❯ OpenRouter (200+ 模型)
# Anthropic (Claude 系列)
# OpenAI (GPT 系列)
# Google (Gemini 系列)
# 智谱AI (GLM 系列)
# Custom Endpoint (Ollama/vLLM/SGLang)
模型选择建议:
| 场景 | 推荐模型 | 理由 |
|---|---|---|
| 日常开发助手 | Claude Sonnet 4 | 性价比最优,64K 上下文 |
| 复杂推理任务 | Claude Opus 4 | 推理能力最强 |
| 预算有限 | DeepSeek V3 | 价格极低,质量接近 GPT-4 |
| 数据隐私要求 | Qwen 2.5 (本地) | 完全本地运行,零数据外泄 |
| 长上下文需求 | Kimi | 支持 200 万 token 上下文 |
4.3 Docker 生产部署
对于生产环境,Docker 是最推荐的部署方式:
# 初始化配置
mkdir -p ~/.hermes
docker run -it --rm \
-v ~/.hermes:/opt/data \
nousresearch/hermes-agent setup
# 网关模式持久运行
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
-e ANTHROPIC_API_KEY="sk-ant-你的密钥" \
-p 8080:8080 \
nousresearch/hermes-agent gateway run
# 如果需要浏览器自动化,添加共享内存
docker run -d \
--name hermes \
--restart unless-stopped \
-v ~/.hermes:/opt/data \
--shm-size=1g \
nousresearch/hermes-agent gateway run
资源要求:
| 配置 | 最低要求 | 推荐配置 |
|---|---|---|
| 内存 | 1 GB | 2-4 GB |
| CPU | 1 核 | 2 核 |
| 磁盘 | 500 MB | 2 GB |
| 网络 | 稳定出站 | 低延迟出站 |
Serverless 部署(Modal):
对于不需要 24/7 在线的场景,Modal 是最经济的选择——按需唤醒,空闲近零成本:
# modal_deploy.py
import modal
app = modal.App("hermes-agent")
image = (
modal.Image.from_registry("nousresearch/hermes-agent:latest")
.pip_install("hermes-agent[all]")
)
@app.function(
image=image,
gpu="A10G", # 需要本地模型时启用
memory=4096,
timeout=300,
keep_warm=0, # 空闲时零成本
allow_concurrent_inputs=10,
)
@modal.web_endpoint(method="POST")
async def hermes_endpoint(request: dict):
"""Serverless Hermes Agent 端点"""
from hermes import Agent
agent = Agent()
response = await agent.chat(
message=request["message"],
user_id=request["user_id"],
)
return {"response": response.text}
4.4 接入消息平台
Telegram 接入
# 1. 在 Telegram 搜索 @BotFather,发送 /newbot 创建机器人
# 2. 获取 Bot Token
# 3. 配置 Hermes Agent
hermes config set TELEGRAM_BOT_TOKEN "123456:ABC-你的Token"
# 4. 获取你的 Telegram 用户 ID(搜索 @userinfobot)
hermes config set TELEGRAM_ALLOWED_USERS "你的用户ID"
# 5. 启动网关
hermes gateway
飞书接入
# 1. 在飞书开放平台创建应用
# 2. 获取 App ID 和 App Secret
# 3. 配置 Hermes Agent
hermes gateway setup
# 选择 Feishu 平台
# 填入 app_id、app_secret、verification_token
# 飞书适配器支持:
# - 事件订阅
# - 消息卡片
# - 群聊
# - 图片文件附件
# - 访问白名单 (FEISHU_ALLOWED_USERS)
企业微信接入
# 企业微信使用 WebSocket 网关,无需公网端点
hermes config set WECOM_BOT_ID "你的机器人ID"
hermes config set WECOM_SECRET "你的密钥"
# 支持:
# - 文本、图片、语音、视频消息
# - 群聊场景
# - AES 加密解密(自动处理)
4.5 自定义技能开发
Hermes Agent 最强大的能力之一是技能的自动生成,但有时你需要手动编写技能来满足特定需求。以下是一个完整的自定义技能开发示例:
---
name: k8s-troubleshooter
version: 1.0.0
author: your-name
created: 2026-05-03
trigger:
- "K8s 故障排查"
- "Kubernetes 调试"
- "Pod 异常"
- "k8s troubleshooting"
---
## 概要(Level 0)
Kubernetes 集群故障排查技能,自动收集 Pod、Service、
Ingress 等资源状态,定位常见问题并提供修复建议。
适用于:Kubernetes 1.28+、kubectl 已配置。
## 详细步骤(Level 1)
### 1. 收集集群基本信息
```bash
# 集群版本和节点状态
kubectl version -o yaml
kubectl get nodes -o wide
# 检查节点资源使用
kubectl top nodes
2. 定位问题 Pod
# 查看所有命名空间的异常 Pod
kubectl get pods -A --field-selector=status.phase!=Running
# 查看 Pod 事件
kubectl describe pod <pod-name> -n <namespace>
# 查看 Pod 日志
kubectl logs <pod-name> -n <namespace> --previous # 上一个容器
kubectl logs <pod-name> -n <namespace> --tail=100 # 最近100行
3. 常见问题速查
| 状态 | 可能原因 | 排查命令 |
|---|---|---|
| ImagePullBackOff | 镜像不存在/无权限 | kubectl describe pod 查看 Events |
| CrashLoopBackOff | 容器启动失败 | kubectl logs --previous |
| OOMKilled | 内存不足 | 调整 resources.limits.memory |
| Pending | 资源不足/调度失败 | kubectl describe pod 查看调度事件 |
| Completed | 任务已完成 | 正常状态,检查日志确认 |
深入参考(Level 2)
网络问题排查
Service 无法访问:
# 检查 Endpoints kubectl get endpoints <service-name> # 检查 Service 选择器是否匹配 Pod 标签 kubectl get pods -l app=<selector-value> # 测试集群内连通性 kubectl run tmp --image=busybox --rm -it -- wget -qO- <service-name>:<port>Ingress 502/503:
# 检查 Ingress 后端 Service kubectl describe ingress <ingress-name> # 检查 Ingress Controller 日志 kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
将这个文件保存到 `~/.hermes/skills/k8s-troubleshooter.md`,Hermes Agent 就会自动识别并在相关场景中调用它。
### 4.6 子代理并行执行
Hermes Agent 支持生成隔离的子代理来并行处理复杂工作流。这在处理大型任务时非常有用——比如同时分析多个微服务的日志、并行处理多个代码仓库的审查等。
```python
# 子代理并行执行示例
from hermes import Agent, SubAgentConfig
agent = Agent()
# 定义并行任务
tasks = [
SubAgentConfig(
task="分析 user-service 的错误日志,提取近24小时的异常模式",
model="deepseek-v3", # 用便宜的模型做初步分析
timeout=60,
),
SubAgentConfig(
task="分析 order-service 的错误日志,提取近24小时的异常模式",
model="deepseek-v3",
timeout=60,
),
SubAgentConfig(
task="分析 payment-service 的错误日志,提取近24小时的异常模式",
model="deepseek-v3",
timeout=60,
),
]
# 并行执行所有子代理
results = await agent.spawn_subagents(tasks)
# 汇总分析(用更强的模型做综合判断)
summary = await agent.chat(
message=f"基于以下三个服务的分析结果,给出整体系统健康评估和跨服务问题定位:\n\n"
f"User Service: {results[0].text}\n\n"
f"Order Service: {results[1].text}\n\n"
f"Payment Service: {results[2].text}",
model="claude-sonnet-4", # 用更强的模型做综合判断
)
子代理彼此隔离,一个失败不会波及其他。这种设计让 Hermes Agent 在处理大规模任务时具备真正的并发能力。
4.7 MCP 协议集成
自 v0.6.0 起,Hermes Agent 原生支持 Model Context Protocol(MCP),兼容 stdio 和 HTTP 双传输。v0.8.0 引入了 MCP OAuth 2.1 认证。通过 MCP 协议,任何支持 MCP 的工具和服务都能被 Hermes Agent 直接调用。
# MCP 服务器配置 (~/.hermes/config.yaml)
mcp:
servers:
# GitHub MCP 服务器
- name: github
transport: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_TOKEN}"
# 文件系统 MCP 服务器
- name: filesystem
transport: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
# PostgreSQL MCP 服务器
- name: postgres
transport: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-postgres"]
env:
POSTGRES_CONNECTION_STRING: "postgresql://user:pass@localhost:5432/mydb"
# 远程 MCP 服务器(带 OAuth 认证)
- name: remote-api
transport: http
url: https://api.example.com/mcp
auth:
type: oauth2.1
client_id: "hermes-agent"
scopes: ["read", "execute"]
MCP 集成让 Hermes Agent 的能力边界被无限扩展。任何支持 MCP 的工具和服务——代码仓库、数据库、文件系统、API——都能成为 Hermes Agent 的"手"和"眼"。
五、性能优化:让 Hermes Agent 跑得更快更省
5.1 上下文管理策略
Hermes Agent 要求底层模型至少支持 64,000 token 上下文长度。但长上下文意味着更高的 API 成本和更慢的响应速度。Hermes Agent 内置了几种上下文管理策略:
# 上下文管理配置
context:
# 压缩策略
compression:
enabled: true
method: "summary" # summary | sliding_window | hybrid
# 当上下文超过阈值时自动压缩
trigger_threshold: 50000 # tokens
# 压缩后保留的核心信息量
target_size: 20000 # tokens
# 技能加载策略
skill_loading:
# 默认只加载 Level 0 概要
default_level: 0
# 触发技能时加载 Level 1
on_trigger_level: 1
# 需要深入参考时才加载 Level 2
on_deep_dive_level: 2
# 记忆检索策略
memory_retrieval:
# 每次对话加载的最大记忆条数
max_entries: 5
# 记忆相关性阈值
relevance_threshold: 0.6
# 优先加载最近的记忆
recency_bias: 0.3
手动压缩上下文:
# 在对话中输入 /compress 压缩当前上下文
/compress
# 查看当前上下文使用情况
/context
5.2 API 成本优化
Hermes Agent 的运行成本主要来自 LLM API 调用。以下是几种有效的成本优化策略:
策略一:分层模型使用
# 模型分层配置
models:
# 简单任务用便宜模型
simple_tasks:
model: deepseek-v3
cost_per_1k_tokens: 0.001 # 约 $0.001/1K tokens
use_cases:
- 记忆摘要
- 技能概要生成
- 简单问答
# 复杂推理用强模型
complex_tasks:
model: claude-sonnet-4
cost_per_1k_tokens: 0.015
use_cases:
- 代码生成
- 架构设计
- 复杂问题分析
# GEPA 进化用中等模型
evolution:
model: claude-haiku-4
cost_per_1k_tokens: 0.003
use_cases:
- 策略评估
- 技能改进
- 记忆整理
策略二:本地模型降本
# 使用 Ollama 运行本地模型(零 API 费用)
# 需要 16GB+ 显存
# 安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh
# 拉取模型
ollama pull qwen2.5:14b # 推荐:质量与速度的平衡
ollama pull llama3.1:8b # 轻量级:速度优先
ollama pull deepseek-v2:16b # 代码能力最强
# 配置 Hermes Agent 使用本地模型
hermes model
# 选择 Custom Endpoint -> 填入 http://localhost:11434
策略三:缓存与批处理
# 缓存配置
cache:
# LLM 响应缓存(相同输入直接返回缓存结果)
response_cache:
enabled: true
ttl: 3600 # 1小时过期
max_size: "100MB"
# 技能调用缓存
skill_cache:
enabled: true
# 相同技能 + 相似参数时复用历史结果
similarity_threshold: 0.95
5.3 实际成本参考
基于实际使用数据的成本参考:
| 使用强度 | 月 API 费用 | 说明 |
|---|---|---|
| 轻度(每天几条消息) | $5-15 | 日常问答、简单任务 |
| 中度(每天 1-2 小时) | $30-60 | 开发辅助、代码审查 |
| 重度(整天使用) | $80-150 | 深度开发、持续集成 |
| 本地模型 | $0 | 需 16GB+ 显存 |
| Serverless 部署 | $5-20 | 空闲近零成本 |
5.4 Cron 调度与定时任务
Hermes Agent 内置 Cron 调度器,可以无人值守地执行周期性任务:
# 定时任务配置 (~/.hermes/config.yaml)
cron:
jobs:
# 每天早上 8 点检查 CI 状态
- name: ci-monitor
schedule: "0 8 * * *"
task: "检查所有活跃项目的 CI 状态,报告失败的任务"
model: deepseek-v3 # 用便宜模型做例行检查
# 每周一上午生成周报
- name: weekly-report
schedule: "0 9 * * 1"
task: "汇总本周的代码提交、PR 合并和问题修复情况,生成周报"
model: claude-sonnet-4
# 每 6 小时检查服务健康
- name: health-check
schedule: "0 */6 * * *"
task: "检查生产环境服务健康状态,异常时发送告警"
model: deepseek-v3
notify:
platform: feishu
users: ["your-user-id"]
六、与同类框架的深度对比
6.1 Hermes Agent vs OpenClaw
这两个是目前最热门的开源 AI 智能体框架,设计哲学有根本差异。
OpenClaw 的核心是"AI 网关"——一个连接多通道(微信、飞书、钉钉等)的统一消息路由层,上面挂载各种 Skill(技能)。它的优势在于多通道接入的深度和广度,以及 Skill 生态的丰富度。但 OpenClaw 的 Skill 是手动编写的,Agent 本身没有学习能力。
Hermes Agent 的核心是"自进化"——GEPA 引擎让 Agent 从经验中学习,自动生成和改进技能。它的优势在于长期使用的累积优势。但在消息通道的深度上,Hermes Agent 还在追赶。
选择建议:
- 需要多通道深度覆盖 → OpenClaw
- 需要自主学习和长期进化 → Hermes Agent
- 两者可以结合使用 → Hermes Agent 作为"大脑",OpenClaw 作为"通道"
Hermes Agent 甚至提供了从 OpenClaw 迁移的专用命令:hermes claw migrate。
6.2 Hermes Agent vs Cline
Cline 是一个 VS Code 插件,把 AI 编程代理直接嵌入编辑器。它的优势在于深度集成 IDE,文件操作、终端执行、浏览器预览都很方便。但 Cline 是有状态的——每次对话从零开始,没有记忆和技能积累。
Hermes Agent 不绑定 IDE,通过消息平台交互。这意味着你可以在任何设备上使用它——手机上的 Telegram、电脑上的飞书、甚至是通过 SSH 连接的终端。但缺少 IDE 集成意味着代码操作的便利性不如 Cline。
选择建议:
- 专注编码场景 → Cline
- 全场景智能助手 → Hermes Agent
6.3 Hermes Agent vs AutoGPT
AutoGPT 是最早的自主 AI Agent 项目之一,它的核心是让 GPT 自主规划和执行多步骤任务。但 AutoGPT 缺少记忆持久化和技能学习,每次运行都是独立的。
Hermes Agent 在 AutoGPT 的自主执行能力基础上,增加了记忆、学习和进化。可以说 Hermes Agent 是"AutoGPT + 记忆 + 学习 + 进化"。
七、生产环境最佳实践
7.1 安全加固清单
# 1. 保护密钥文件权限
chmod 600 ~/.hermes/.env
chmod 700 ~/.hermes/memories
# 2. 启用 Docker 沙箱
hermes config set sandbox.enabled true
hermes config set sandbox.backend docker
# 3. 配置危险操作审批
hermes config set security.approval_required "[file_delete,shell_execute,email_send]"
# 4. 限制网络访问
hermes config set security.sandbox.network restricted
# 5. 启用 Prompt 注入扫描
hermes config set security.injection_scan true
# 6. 配置日志脱敏
hermes config set logging.redact_secrets true
# 7. 定期更新
hermes update # 更新到最新版本
hermes doctor # 检查安全配置
7.2 监控与告警
# 监控配置
monitoring:
# Prometheus 指标导出
prometheus:
enabled: true
port: 9090
metrics:
- hermes_tasks_total
- hermes_tasks_success
- hermes_tasks_failure
- hermes_memory_entries
- hermes_skills_count
- hermes_api_calls_total
- hermes_api_cost_total
- hermes_evolution_cycles
# 告警规则
alerts:
- name: high_failure_rate
condition: "hermes_tasks_failure / hermes_tasks_total > 0.3"
duration: 5m
action: notify
channels: ["feishu"]
- name: cost_spike
condition: "rate(hermes_api_cost_total[1h]) > 10" # $10/h
action: notify
- name: memory_bloat
condition: "hermes_memory_entries > 10000"
action: auto_consolidate # 自动触发记忆整理
7.3 备份与恢复
# 备份 Hermes Agent 全部数据
tar -czf hermes-backup-$(date +%Y%m%d).tar.gz \
~/.hermes/memories/ \
~/.hermes/skills/ \
~/.hermes/sessions/ \
~/.hermes/config.yaml \
~/.hermes/MEMORY.md \
~/.hermes/USER.md
# 恢复
tar -xzf hermes-backup-20260503.tar.gz -C ~/
# 使用 CLI 备份(更方便)
hermes backup create --output ./backups/
hermes backup list
hermes backup restore --file ./backups/backup-20260503.tar.gz
7.4 多 Agent 协作架构
对于复杂业务场景,你可能需要多个 Hermes Agent 实例协同工作。Hermes Agent 支持多 Agent 架构,涉及规划者、执行者和审核者角色:
# 多 Agent 协作架构
class AgentOrchestrator:
"""多 Agent 编排器"""
def __init__(self):
self.planner = Agent(role="planner", model="claude-sonnet-4")
self.executor = Agent(role="executor", model="deepseek-v3")
self.reviewer = Agent(role="reviewer", model="claude-sonnet-4")
async def execute_complex_task(self, task: str) -> dict:
# 1. 规划者分解任务
plan = await self.planner.chat(
f"将以下任务分解为可独立执行的子任务:\n{task}"
)
subtasks = parse_subtasks(plan.text)
# 2. 执行者并行执行子任务
results = await asyncio.gather(*[
self.executor.chat(f"执行子任务:{st}")
for st in subtasks
])
# 3. 审核者检验结果
review = await self.reviewer.chat(
f"审核以下子任务执行结果,确认是否符合要求:\n"
f"原始任务:{task}\n"
f"执行结果:{[r.text for r in results]}"
)
if review.needs_revision:
# 反馈给执行者修正
for feedback in review.feedbacks:
await self.executor.chat(f"修正:{feedback}")
return {
"task": task,
"plan": plan.text,
"results": [r.text for r in results],
"review": review.text,
"approved": review.approved
}
八、常见问题与排障指南
8.1 安装与配置问题
| 问题 | 解决方案 |
|---|---|
hermes: command not found | source ~/.bashrc 刷新环境变量,检查 PATH 是否包含 ~/.local/bin |
| API 密钥不工作 | hermes config show 确认密钥正确,检查提供商账户余额 |
| HTTP 400 错误 | 模型名称与提供商不匹配,重新执行 hermes model 选择 |
| Telegram 群组无响应 | 通过 BotFather 关闭隐私模式,踢出再重新拉入 |
| Discord 消息为空 | 在开发者面板启用 Message Content Intent |
| Docker 后端连接失败 | docker info 确认守护进程正常,确保用户加入 docker 组 |
| 上下文长度超限 | 输入 /compress 压缩上下文,或切换更大上下文模型 |
8.2 通用诊断方法
# 自动检测和修复环境问题
hermes doctor --fix
# 实时追踪日志
hermes logs -f
# 导出完整调试信息(用于社区求助)
hermes dump > debug-info.json
# 检查配置完整性
hermes config check
# 交互式补全缺失配置
hermes config migrate
九、版本演进与生态
9.1 关键版本里程碑
| 版本 | 日期 | 核心更新 |
|---|---|---|
| v0.1.0 | 2026.02.25 | 首次公开发布,确立核心架构 |
| v0.2.0 | 2026.03.12 | 合并 216 个 PR,引入 MCP 支持与 70 余项内建技能 |
| v0.4.0 | 2026.03.23 | OpenAI 兼容 API 上线,新增多个消息平台适配器 |
| v0.5.0 | 2026.03.30 | 安全专项强化,200+ 安全补丁,零 CVE |
| v0.7.0 | 2026.04.03 | 安全性与稳定性全面强化 |
| v0.8.0 | 2026.04.08 | 后台任务通知、MCP OAuth 2.1、Plugin 扩展系统 |
六周时间,合并千余个 PR。这个迭代速度说明两件事:一是社区贡献非常活跃,二是团队对代码质量的把控很严格——每个 PR 都有完整的测试和 review。
9.2 周边生态
- Hermes Workspace:浏览器管理界面,集成聊天、终端和记忆浏览器
- Mission Control:多 Agent 调度仪表板,3700+ GitHub Stars
- AgentSkills.io:开放技能市场,社区开发者发布经过安全扫描的技能包
十、总结与展望
10.1 Hermes Agent 带来的三个核心认知
认知一:AI 的瓶颈不在模型,在架构。 更大的模型、更多的参数、更好的训练数据——这些当然重要。但对于实际使用来说,更关键的是怎么用模型。一个有记忆、会学习、能进化的架构,比一个参数量翻倍的模型更有实际价值。
认知二:自进化是 AI Agent 的终极形态。 手动编写技能和插件,本质上是把人的知识硬编码到系统中。自动从经验中学习,才是真正的智能化。GEPA 引擎证明了 prompt 级别的进化是可行的、高效的、安全的。
认知三:安全是进化的前提。 能力越强,风险越大。Hermes Agent 在自进化的同时保持了零 CVE 的安全记录,靠的不是运气,而是从一开始就把安全作为架构的根基——容器沙箱、指令审批、注入扫描,每一层都是一道防线。
10.2 当前局限与未来方向
Hermes Agent 也不是完美的。当前的局限包括:
- 原生 Windows 不支持:必须通过 WSL2 使用,这对 Windows 开发者不太友好。
- FTS5 检索不如向量搜索精准:对于大规模记忆库,FTS5 的语义理解能力有限。未来可能需要引入混合检索方案。
- GEPA 进化的评估标准还需完善:自动评估任务执行质量仍然是一个开放问题,当前的评估维度可能不够全面。
- 多 Agent 协作还处于早期:规划者-执行者-审核者的模式还需要更多生产验证。
未来的方向可能包括:
- 向量检索增强:引入嵌入模型,实现更精准的语义检索
- 联邦学习:多用户协作训练共享技能,同时保护隐私
- 更深的 IDE 集成:在保持平台无关性的同时,提供可选的 IDE 插件
- 进化可视化:让用户直观地看到 Agent 的进化路径和技能图谱
10.3 一句话总结
Hermes Agent 不是一个更快的聊天机器人,而是一个会成长的数字同事。它用记忆对抗遗忘,用技能对抗重复,用进化对抗停滞。在 AI Agent 这个赛道上,大多数项目都在追求"一次做得更好",而 Hermes Agent 追求的是"百次做得更好"——因为真正的智能,从来不是一次性的。
参考资源:
- GitHub 仓库:https://github.com/NousResearch/Hermes-Agent
- 官方中文站:https://hermesagentai.cn/
- AgentSkills.io 技能市场:https://agentskills.io
- GEPA 论文:Gradient Estimation via Prompt Adaptation (UC Berkeley/Stanford/MIT)