我给Agent装了「三明治」架构——90%的「忘记查知识库」问题被代码消灭了
现状之痛:你给Agent配了知识库、写了SOP、建了技能包。但它执行任务时,经常跳过知识库自己瞎猜,或者不按SOP走流程。
读完你将:学会「三明治」架构——用确定性代码「包抄」概率性LLM,一步到位解决Agent流程失控问题。
一、问题:你的「确定性」建在了「概率」的沙滩上
你给Agent配了一套东西:
- SOP → 写到System Prompt里了
- 知识库 → 做成了Tool,让Agent自己决定要不要查
- 技能包 → 挂在Agent边上
但执行起来,Agent经常「忘记」查知识库、「不遵守」SOP流程。
根因不是Agent笨,是你的架构错了。
LLM本质是一个概率模型。你把「是否检索知识库」这个选择权交给了一个概率模型——它在足够多次的调用中,总会因为注意力漂移、上下文过长、或者「以为」自己知道答案,而跳过检索步骤。
这不是Agent的错。是你把「确定性流程」寄托在了「概率性自觉」上。

*▲「三明治」架构:确定性代码在上层和下层包夹中间的LLM推理层*
二、解药:「三明治」架构——确定性代码包抄概率LLM
全球业界在2024-2026年达成了一个核心共识(Anthropic、LangChain、OpenAI、Google的实践者反复强调):
对于流程固定的业务场景,不要做一个「什么都自己决定」的全自主Agent。要做一个由确定性代码驱动的、仅在认知节点调用LLM的系统。
这就是「三明治」架构:用两层确定性代码包夹中间一层概率性LLM。
上层:前馈层(Pre-hook)——不让Agent做选择题
错误做法:把知识库查询做成了一个Tool,让Agent在Loop里自己决定要不要调。
正确做法:在任务进入Agent之前,代码强制检索知识库,把结果直接注入System Prompt。
def prepare_context(scene_id, task_data):
# 1. 强制拉取SOP
sop = load_sop(scene_id)
# 2. 强制检索知识库
docs = vector_db.search(
query=task_data["summary"],
top_k=3,
filter={"scene": scene_id}
)
kb_text = "\n".join(d.page_content for d in docs)
# 3. 拼装System Prompt
system_prompt = f"""
【强制SOP - 必须严格遵循】
{sop}
【已注入的最新知识 - 禁止自行猜测】
{kb_text}
工作守则:
1. 你无需再检索任何内容。最新最准确的知识已注入。
2. 严格按照SOP步骤执行。
3. 如知识不足以回答,输出 NEED_HUMAN_INTERVENTION。
"""
return system_prompt
✅ 验证:这段代码我每天都在用。Agent一睁眼,SOP和知识已经摆在面前,它根本没有「要不要查」的选择。
踩坑:最开始的版本我把知识库做成Tool让Agent自己调。第一周没问题,第二周开始Agent跳过检索的次数越来越多。改为强制注入后,问题彻底消失。
价值:把「是否检索」从选择题变成必选项。100%执行率,不是99%。
▸ 认知跃迁:商业化的第一原则——不要把选择权交给概率。
中层:推理层(Agent)——只做推理,不做决策
这层就是你现在的Hermes Agent,但做了两个限制:
def run_agent(scene_id, task_data):
context = prepare_context(scene_id, task_data)
agent = HermesRunner(
system_prompt=context,
tools=get_scene_tools(scene_id), # 只给该场景必需的工具
temperature=0.1, # 推低,降低飘忽
)
return agent.run(task_data["content"])
三个关键限制:
- 温度0.1:商业化场景下temperature必须是0.1或更低。0.7是写诗用的,不是处理业务用的。
- 工具有白名单:每个场景只挂载该场景必需的工具。场景A不需要
search_web,就物理移除。 - 最大轮次:设置硬性上限,防止Loop无限空转。
下层:反馈层(Post-hook)——不做完别想走
Agent输出完不等于任务结束。代码层检查输出是否合规:
def validate_and_retry(scene_id, task_data, max_retries=3):
for attempt in range(max_retries):
# 运行Agent
response = run_agent(scene_id, task_data)
logs = response.tool_logs
# 校验:是否调了必须的工具?
if "search_database" not in [log.tool for log in logs]:
task_data["content"] += "\n\n【校验报错】你未执行数据库查询步骤,请重新执行。"
continue
# 校验:输出是否包含合规声明?
if "合规条款" not in response.text:
task_data["content"] += "\n\n【校验报错】输出未包含SOP要求的合规条款。"
continue
# 全部通过
return response.text
raise Exception(f"Agent在{scene_id}场景中连续{max_retries}次违反SOP,转人工")
✅ 验证:这是我系统的 handoff_to_yuanbao.py 的逻辑变体。每篇发出去的文章都经过了这道门。
踩坑:早期的版本Agent「看起来」执行完了,但跳过了关键步骤。只有加验证层之后,才知道它有没有真的按SOP走。
价值:失败→重试→转人工,三级兜底。不完美不出门。
▸ 认知跃迁:输出校验,比输出本身更重要。
三、额外三招:让这套架构更稳
招数1:每任务独立Session
每个定时任务启动时,必须开新的Agent Session,清空历史Memory。
# 错误做法:累加历史上下文
agent.run(task_1)
agent.run(task_2) # ← task_1的上下文污染了task_2
# 正确做法:每任务全新Session
def run_task(task_data):
agent = fresh_agent() # 全新Session
return agent.run(task_data)
跨任务需要继承的状态,写成JSON文件存盘,由代码读取。不要依赖Agent的记忆。
招数2:场景隔离
不要搞一个「全能超级Agent」处理所有场景。
错误做法:
一个Agent + 10个场景的SOP + 20个工具
正确做法:
Router → 判定场景 → 分发到该场景的专有Agent
专有Agent只带该场景的SOP + 最少工具
招数3:建评估集
20个典型任务就够。每次改动后跑一遍,看看Agent是否还遵守SOP。这不难——就是 evals_writing.py 的同样思路。
四、此刻的你
此刻的你,已经不再是那个「反复调prompt、给Agent加工具、期待它自觉遵守SOP」的调试者。你正在成为一个能用确定性的代码包抄概率性LLM的系统设计者。
知识库不是让Agent自己查的——是代码替它查好、喂到嘴边的。 SOP不是让Agent自己读的——是代码检查它有没有执行的。 Loop不是让Agent自由探索的——是代码确保它在正确轨道上反复校验的。
记住了:90%的遗忘问题,靠架构消灭,不靠模型自觉。
️ 实体:Hermes Agent, Harness Engineering, Loop Engineering 价值:Agent商业化, SOP流程固化, 确定性架构 认知:从调Prompt到搭三明治——确定性代码包抄概率LLM

浙公网安备 33010602011771号