大多数 Claude 代理教程都在基础的“Hello World”示例后就结束了。
他们会教你如何让 Claude 调用一个工具,如何设置一个基本的循环,如何在一个简单的玩具任务上获得自主响应。
然后,当你尝试构建真正的东西时,一切都会分崩离析。
任务太模糊了。代理卡住了。输出结果不一致。会话结束,什么也没保存。下一次你又得从头开始。
一个可以在教程中正常工作的 Claude 代理和一个可以在生产环境中正常工作的 Claude 代理之间的差距,并非源于 Claude 自身能力的不足。
这个差距在于代理的设计方式。
本指南将完全弥补这一差距。
到文章结束时,你将拥有一个能可靠运行真实工作流的 Claude 代理。不是演示。不是玩具任务。而是一个能够产生一致输出、优雅处理边缘情况、持续改进,并且无需你手动启动每一步的工作流。
是什么让一个真实世界的代理与众不同
在开始构建之前,要理解真实世界的代理与教程中的代理有何不同。
教程代理处理的是干净的任务和干净的输入,并产生干净的输出。任务定义明确。输入以完全预期的格式提供。不会发生任何意外。成功与否是二元的、显而易见的。
真实世界的代理处理的是杂乱的任务和杂乱的输入,但仍需产生有用的输出。任务只是部分定义。输入的格式各不相同。意外情况时常发生。成功是一个程度问题,需要判断力来评估。
有四个属性决定了一个代理能否经受住真实世界的考验:
健壮的任务定义。 代理不仅知道要做什么,还知道如何处理它将在实践中遇到的二十种任务变体。指令涵盖了边缘情况,而不仅仅是理想情况。
持久记忆。 代理可以跨会话积累上下文。上周完成的工作会为今天的工作提供信息。它不会在每个会话中都从零开始。
优雅的失败处理。 当出现问题时,代理能够恢复,而不是停止。它会记录发生的事情,尝试替代方案,并且仅在无法恢复时才向人类发出警报。
质量的自我验证。 代理在交付输出之前,会根据定义的标准检查自己的输出。它关闭了自己的反馈循环,而不是直接交回它产生的第一个结果。
大多数教程代理不具备这些属性中的任何一个。本指南将构建所有这四个属性。
代理架构
该架构包含四个协同工作的组件。
任务定义层
一个结构化的技能文件,定义了任务、流程、边缘情况处理和质量标准。这不是一个提示词。它是一个完整的操作规范,代理会在每次执行前读取它。
记忆层
一个持久化数据库,存储代理做过什么、学到了什么以及需要在会话间记住什么。通过 Hermes Agent 在 SQLite 上构建,或使用基于文件的日志手动实现。
执行层
实际完成工作的 Claude API 调用。经过结构化设计,能为工作流的每一步使用正确的模型、正确的上下文和正确的工具。
质量层
验证循环,在交付输出之前对照定义的标准检查输出,并在输出不达标时使用特定的修正进行重试。
设置基础
安装所需工具:
安装 Hermes Agent 用于编排和记忆
git clone https://github.com/NousResearch/hermes-agent
cd hermes-agent
npm install
安装 MCP 服务器以访问工具
npm install -g @modelcontextprotocol/server-filesystem
npm install -g @modelcontextprotocol/server-brave-search
配置你的环境:
核心配置
MODEL_PROVIDER=anthropic
MODEL_NAME=claude-opus-4-8
ANTHROPIC_API_KEY=your-api-key-here
记忆配置 —— 使用绝对路径
MEMORY_BACKEND=sqlite
MEMORY_PATH=/Users/yourname/agent-data/memory.db
调度器配置
ENABLE_SCHEDULER=true
SCHEDULER_TIMEZONE=America/New_York
输出配置 —— 结果存放位置
OUTPUT_PATH=/Users/yourname/agent-outputs
失败恢复
SKILL_RETRY_ENABLED=true
SKILL_RETRY_MAX=3
SKILL_RETRY_DELAY=300
通知
NOTIFICATION_GATEWAY=telegram
TELEGRAM_BOT_TOKEN=your-bot-token
TELEGRAM_CHAT_ID=your-chat-id
编写 CLAUDE.md:
这是整个设置中最重要的文件。每个代理会话都从读取它开始。所有输出的质量都取决于这里内容的详细程度。
Agent 配置 —— CLAUDE.md
身份与目的
[用一个具体的段落描述这个代理是做什么的。
不是 Claude 通常能做什么。
而是这个特定的代理为这个特定的操作配置了什么。]
操作上下文
[描述这个代理运行的业务或个人上下文。
配置这个代理的人做什么工作?
他们的标准与优先事项是什么?]
当前活跃任务
[列出这个代理运行的具体重复性任务。
每个任务包括:做什么、何时运行、好的输出看起来什么样。]
工具权限
你被允许自主使用以下工具:
- 文件系统:读写 [指定路径]
- 网络搜索:用于研究 [指定主题]
- [其他工具及其特定范围]
你不得:
- 写入任何已配置输出目录之外的路径
- 进行未在上述列表中提及的外部 API 调用
- 在未获得明确批准的情况下执行任何影响外部系统的操作
质量标准
[描述每种任务类型的好输出是什么样的。
尽可能包含示例。
要足够具体,以便代理能够进行自我评估。]
记忆指令
在记忆中存储:
- 每个重要的输出及其日期和质量评估
- 遇到的每个边缘情况及其处理方式
- 每个质量失败及其原因
- 在多个输出中识别出的每种模式
错误处理
工具调用失败时:重试一次,记录失败,使用可用的工具继续。
质量检查失败时:使用特定的修正进行重试,而不是完全重写。最多重试三次。
遇到无法恢复的失败时:保存部分工作,记录具体的失败,发送通知,优雅地停止。
构建任务定义层
任务定义层是大多数真实世界代理失败的地方。
人们会编写一个描述理想情况的提示词,然后就停止了。代理能很好地处理理想情况,但在其他所有事情上都会出问题。
一个健壮的任务定义涵盖了任务的完整操作现实。以下是模板:
[任务名称]
目的
[一句话:这个技能完成什么?]
触发器
[导致此技能运行的精确条件:
预定时间、文件出现、手动命令等。]
执行前检查
在开始之前,验证:
- [所需输入存在并可访问]
- [所需工具已连接并响应]
- [输出路径可写]
- [记忆可访问且是最新的]
如果任何检查失败:记录失败并停止。
在缺少先决条件的情况下不要继续。
主要流程
步骤 1:加载上下文
读取 CLAUDE.md 以获取完整操作上下文。
读取记忆中以 [任务标签] 标记的相关历史记录。
注意以往执行中可能影响本次执行的任何模式。
步骤 2:输入处理
[精确描述如何处理输入。
涵盖主要格式以及实践中出现的替代格式。]
对于标准输入格式:
[精确的处理步骤]
对于替代输入格式 A:
[如何处理]
对于替代输入格式 B:
[如何处理]
对于格式错误或缺失的输入:
[如何处理 —— 永远不要悄无声息地失败]
步骤 3:核心执行
[技能的实际工作。
分解为子步骤。每个子步骤应该足够具体,
以至于一个新的 Claude 实例可以在没有额外上下文的情况下执行它。]
步骤 4:质量验证
在保存输出之前,根据以下标准进行验证:
必需:[不可协商的输出属性]
期望:[能改善输出质量的属性]
禁止:[输出中绝不应出现的内容]
如果输出未能通过必需检查:
- 精确识别失败的具体内容
- 使用有针对性的修正进行重试
- 最多重试三次
- 如果三次后仍然失败:以失败标志保存
步骤 5:输出与存储
保存输出至:[特定路径和文件名格式]
存储到记忆中,标记:[任务标签, 日期]
如果任何当前信息发生变化,更新 CLAUDE.md。
发送通知:[通知中包含的内容]
边缘情况
[边缘情况 1 名称]
条件:[何时发生]
检测:[如何识别]
响应:[怎么做]
[边缘情况 2 名称]
条件:[何时发生]
检测:[如何识别]
响应:[怎么做]
[边缘情况 3 名称]
条件:[何时发生]
检测:[如何识别]
响应:[怎么做]
质量标准
优秀的输出:[具体描述]
可接受的输出:[最低标准]
不可接受的输出:[应触发重试的情况]
记忆指令
每次执行后存储:
- 执行日期和持续时间
- 输出质量评估(优秀/可接受/失败)
- 遇到的任何边缘情况及其处理方式
- 任何值得在未来执行中注意的模式
你的第一个真实代理:研究与简报代理
这里有一个使用此架构构建的完整真实世界代理。这个代理每天监控一组源,研究与你的工作相关的主题,并在每天早上交付一份结构化简报。
这不是一个玩具任务。这是一个真正的工作流,每天可以替代四十五分钟的手动研究整合工作。
创建 skills/research-brief.md:
research-brief
目的
监控已配置的源,并生成一份结构化的
情报简报,涵盖与当前项目和优先事项相关的进展。
触发器
每天上午 6:00 预定执行。
手动触发:"研究简报" 或 "早间简报"
执行前检查
在开始之前,验证:
- CLAUDE.md 在 07-SYSTEM/CLAUDE.md 路径下可读
- Brave Search MCP 正在响应
- 输出路径 outputs/briefings/ 可写
- 记忆数据库可访问
主要流程
步骤 1:加载上下文
完整读取 CLAUDE.md。注意:
- 当前活跃项目及其状态
- 标记为监控的主题
- 任何需要情报来支持的待定决策
- 此简报的质量标准
读取标记为 research-brief 的记忆。
注意:近期简报中已经涵盖的内容,
以避免重复。
步骤 2:来源研究
对于 CLAUDE.md 监控列表中的每个主题:
搜索查询:"[主题] 过去 24 小时新闻"
收集:标题、来源、日期、关键声明
应用信号过滤器:
包含:新进展、数据、产品发布、
重要声明、研究发现
排除:对现有报道的重复、
无新信息的观点、
过去 3 份简报中已涵盖的任何内容
对于每个通过信号过滤器的结果:
如果初步结果表明有重大进展,
则使用后续搜索进行更深入的研究。
步骤 3:综合整理
按主题对发现进行分组。
对于每个主题组,确定:
- 单个最重要的进展
- 它为何对当前项目重要
- 它暗示了什么行动(如果有的话)
跨主题综合:
- 是否有两个或更多的发现相关联,暗示一个更大的模式?
- 是否有任何发现直接影响一个活跃项目或待定决策?
步骤 4:质量验证
在最终确定之前,验证:
必需:
- 至少 3 个信号项(非噪音)
- 每个项都基于特定来源
- 每个项都解释了对当前工作的相关性
- 没有项重复过去 5 份简报中的内容
期望:
- 至少一个跨主题连接
- 至少一个项暗示了具体行动
- 如果新闻较少,诚实地承认这一点
禁止:
- 没有具体证据的泛泛分析
- 有趣但不相关的项
- 为了使简报看起来更全面而填充内容
如果简报未能通过必需检查:精确识别
缺少什么,并在重试前搜索更多来源。
不要用弱信号来填充。
步骤 5:输出生成
以精确格式生成简报:
早间情报简报 —— [日期]
今日最重要
[单个最重要的进展及其为何
对当前工作重要。具体。有依据。]
信号项
[主题 1]
进展: [发生了什么]
来源: [出版物, 日期]
相关性: [为何对当前项目重要]
影响: [建议采取的任何行动]
[主题 2]
[相同格式]
[继续每个信号项]
关联
[如果两个或多个项目相关联,暗示一个更大的
模式,请在此处描述。如果没有真正的关联则跳过。]
决策相关性
[如果任何项目与 CLAUDE.md 中的待定决策
直接相关,请在此处标记并附上具体信息。]
报道说明
[诚实的评估:内容丰富的一天 / 新闻较少的一天。
搜索的来源数量。]
步骤 6:存储与通知
保存至:outputs/briefings/[日期]-morning-brief.md
存储到记忆中:
- 日期:[今天]
- 涵盖项目:[主题列表]
- 质量:[优秀/可接受/失败]
- 值得注意:[任何边缘情况或模式] 标签:research-brief
发送 Telegram 通知:
"早间简报已就绪:[N] 个信号项。
[用一行概括今日最重要]"
边缘情况
未找到某个主题的信号
条件:搜索未返回任何新进展
检测:所有结果都超过 48 小时
响应:对于该主题注明 "无新进展"。
不要编造或填充。继续下一个主题。
来源返回冲突信息
条件:两个来源报道了矛盾的事实
检测:在特定声明上直接矛盾
响应:报告两个版本,引用两个来源,
标记为冲突。不要选择其中一个而忽略另一个。
搜索工具不可用
条件:Brave Search MCP 无响应
检测:工具调用返回错误
响应:记录失败。通过 Telegram 通知。
保存部分简报并注明:"搜索不可用 ——
简报仅基于记忆上下文。"
不要静默失败。
简报将重复昨天的头条
条件:最重要的进展与昨天相同
检测:与记忆中昨天的简报进行交叉引用
响应:注明 "来自 [日期] 的持续进展"
并专注于今天具体新增的内容。
质量标准
优秀简报:4-6 个信号项。每项都相关。
至少一个跨主题洞察。阅读时间少于 5 分钟。
可接受简报:3 个信号项。全部相关。
无跨主题洞察。阅读时间少于 5 分钟。
不可接受简报:少于 3 个信号项。
任何项是泛泛的或与当前工作无关。
任何项重复了最近 3 份简报中的内容。
构建质量验证层
质量验证层是区分产生一致性结果的代理和产生变动结果代理的关键。
大多数代理完全跳过了这一层。它们生成一个输出然后返回它。质量完全取决于生成过程的好坏。有些会话很出色。有些则很平庸。你永远不知道会得到哪个。
质量验证层通过检查每个输出是否符合定义的标准,并在不达标时使用特定的修正进行重试,从而使输出质量保持一致。
以下是实现质量验证的 Claude API 调用模式:
async function executeWithQualityVerification(prompt, qualityStandard, maxRetries = 3) {
let attempt = 0;
let lastOutput = null;
let lastFailure = null;
while (attempt < maxRetries) {
// 生成输出
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01'
},
body: JSON.stringify({
model: 'claude-opus-4-8',
max_tokens: 4096,
messages: [
{
role: 'user',
content: attempt === 0
? prompt
: \${prompt}
Previous attempt failed quality check: ${lastFailure}
Correct specifically for this failure. Do not rewrite everything.\
}
]
})
});
const data = await response.json();
lastOutput = data.content[0].text;
// 验证质量
const verificationResponse = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01'
},
body: JSON.stringify({
model: 'claude-opus-4-8',
max_tokens: 1000,
messages: [
{
role: 'user',
content: `You are a quality checker. Evaluate this output against these standards:
${qualityStandard}
Output to evaluate:
${lastOutput}
Respond with ONLY:
PASS if the output meets all required standards
FAIL: [specific description of what failed] if it does not meet required standards
Do not explain. Do not suggest improvements. Just PASS or FAIL with specific failure description.`
}
]
})
});
const verificationData = await verificationResponse.json();
const verificationResult = verificationData.content[0].text.trim();
if (verificationResult.startsWith('PASS')) {
return { output: lastOutput, attempts: attempt + 1, passed: true };
}
lastFailure = verificationResult.replace('FAIL:', '').trim();
attempt++;
}
// 所有重试已耗尽
return {
output: lastOutput,
attempts: maxRetries,
passed: false,
failure: lastFailure
};
}
这种模式生成一个输出,对照定义的标准进行检查,并在失败时使用特定的修正进行重试。如果所有重试都失败,它会返回最佳输出并带有一个失败标志,而不是崩溃。
记忆集成模式
记忆是将一个有能力的代理转变为一个会学习的代理的关键。
没有记忆,每个会话都从零开始。代理不知道它以前做过什么。它无法应用过去执行中学到的东西。它无法避免已经犯过的错误。
有了记忆,每个会话都建立在上一个会话的基础上。代理知道什么有效,什么无效。它应用积累的上下文来改进当前的输出。它会随着时间的推移,在特定任务上变得更好。
以下是任何 Claude 代理的记忆集成模式:
每次执行开始时:
读取标记为 [任务标签] 的记忆条目
限制:20 个最相关的条目
策略:相关性(而不仅仅是时间先后)
应用此上下文:
- 注意来自以往执行中的模式
- 注意之前遇到的边缘情况
- 注意之前发现的质量问题
- 将学到的东西应用到当前执行中
每次执行结束时:
存储到记忆中:
日期:[今天]
任务:[任务名称]
质量:[优秀/可接受/失败]
值得注意:[任何值得记住的事情]
edge_case:[遇到的任何边缘情况]
pattern:[观察到的任何模式]
标签:[任务标签],[日期]
每月整合:
读取所有标记为 [任务标签] 的记忆条目
识别:
- 跨多个条目出现的模式
- 重复出现的边缘情况
- 重复出现的质量问题
- 跟优秀输出与可接受输出相关的原因
整合成一个单一的更新后的上下文条目
归档超过 90 天的单个条目
失败恢复系统
真实世界的代理会遇到失败。源离线。API 限速。文件不在预期的位置。输出在最大重试次数后未能通过质量检查。
失败恢复系统决定了这些失败是不可见的微小故障,还是灾难性的停止。
三个层级的故障处理:
层级 1:自动恢复
通过重试可以解决的瞬时故障。工具不可用。网络超时。达到速率限制。
层级 1 恢复协议
在任何工具调用失败时:
- 等待 60 秒
- 重试完全相同的调用
- 如果重试成功:正常继续,记录该小故障
- 如果重试失败:升级到层级 2
层级 2:优雅降级
无法解决但允许部分完成的失败。一个源不可用。一个工具无响应。输出的某部分未能通过质量检查。
层级 2 恢复协议
在无法解决的局部失败时:
- 完成能完成的部分
- 明确指出跳过了什么及其原因
- 在文件名中将输出标记为部分
- 在输出本身中包含明确的说明
- 发送通知:"部分输出 —— [具体原因]"
- 不要因为一个组件失败就让整个任务失败
层级 3:优雅停止
使整个任务无法完成的失败。找不到 CLAUDE.md。输出路径不可写。记忆数据库不可访问。
层级 3 恢复协议
在完全失败时:
- 识别具体的失败点
- 将已完成的工作保存到临时位置
- 记录完整的失败上下文
- 发送通知:"任务失败 —— [具体原因]"
- 干净地停止,不损坏任何现有输出
- 不要自动重试 —— 等待人工干预
在部署前测试你的代理
在真实世界代理部署中,最常见的错误是跳过结构化测试。
在任何代理上线之前,有三个测试阶段:
阶段 1:组件测试
在测试整个工作流之前,单独测试每个组件。
测试记忆是否持久化
hermes chat
你存储的最旧的记忆条目是什么?
预期:应报告一个条目或报告数据库为空
如果返回错误:记忆配置错误
测试工具访问
列出 [输出路径] 中的文件
预期:应列出实际文件
如果返回错误:filesystem MCP 配置不正确
测试搜索
搜索 "今日 AI 新闻" 并告诉我最上面的结果
预期:应返回实际搜索结果
如果返回错误:Brave Search MCP 配置不正确
阶段 2:理想路径测试
在干净的标准输入上手动运行技能,并验证输出是否符合质量标准。
手动运行技能
hermes run research-brief
检查输出
cat outputs/briefings/[今天]-morning-brief.md
对照质量标准验证:
- 至少 3 个信号项?
- 每个项都与当前工作相关?
- 没有泛泛的分析?
- 阅读时间少于 5 分钟?
阶段 3:边缘情况测试
有意识地触发每个已记录的边缘情况,并验证恢复行为。
测试:无网络访问
在 .env 中禁用 Brave Search
运行技能
预期:层级 3 失败,干净停止,发送通知
测试:输出路径不可写
将 OUTPUT_PATH 更改为一个不存在的目录
运行技能
预期:层级 3 失败,干净停止,发送通知
测试:新闻较少的日子
在周末或假日运行
预期:层级 2 输出,包含表明是淡季的报道说明
在生产环境中运行你的代理
一旦所有三个测试阶段都通过,配置调度器并迁移到生产环境。
{
"schedules": [
{
"skill": "research-brief",
"cron": "0 6 \ \ *",
"description": "每天上午 6 点",
"timeout_minutes": 15,
"on_failure": "notify_and_stop"
}
]
}
以后台模式启动 Hermes:
npm run start -- --daemon
验证第一次预定运行:
上午 6 点后检查日志
cat logs/hermes-[日期].log
检查输出是否已生成
ls outputs/briefings/
检查记忆是否已更新
hermes chat
你有多少条 research-brief 记忆条目?
如果第一次自动化运行产生了良好的输出,那么代理已经在生产环境中运行了。
第三个月会发生什么
第一个月:代理可靠地运行。输出一致。失败被优雅地处理。你每天节省四十五分钟。
第二个月:记忆层开始产生可见的改进。智能体已经处理了六十天的数据来源,并积累了关于哪些来源产出高信号内容与噪音之间的上下文信息。信号过滤的质量得到提升,因为智能体已经学会了哪些来源值得持续跟踪。
第三个月:记忆整合已经运行了两次。智能体识别出了九十天研究中的模式。简报引用了积累的上下文,使其比任何单次研究都能产出的内容更扎实、更具体。
第三个月的智能体运行的工作流与第一个月不同。
它基于九十天积累的运营情报,运行的是该工作流的改进版本。
这就是教程型智能体与真实世界智能体之间的区别。
教程型智能体执行任务。
真实世界智能体学会了更好地执行任务。
这个周末打好基础。
运行一周。修复崩溃的问题。
运行一个月。观察它如何改进。
运行三个月。留意它所知道的东西——那些你在第一天无法告诉它的事情。
这就是构建一个能在真实世界中实际运作的 Claude 智能体的样子。
关注 @cyrilXBT 以获取所有能让你的 Claude 智能体在真实世界中存活的智能体架构、技能模板和生产部署模式。





