摘要
本文记录了我的 HomeSense 项目在构建本地优先的通用 Agent 框架过程中,从最初的技术误解到核心理念演进的完整历程。我们探讨了为什么同样的模型、同样的提示词,别人能做到 95% 成功率,而自己却总是差强人意------答案不在模型本身,而在模型外面那套"缰绳"(Harness)。本文完整呈现了从 Prompt Engineering 到 Context Engineering 再到 Harness Engineering 的三阶演进,以及 HomeSense 如何将这套理念落地为可运行的代码。
一、起点:一个普遍存在的问题
1.1 问题现象
同样的 GPT-4,同样的提示词,别人做的 Agent 可以连续跑很久、成功率很高,到了自己手里就总是差强人意。
你可能会想:
-
是不是模型不够强?
-
是不是提示词没调好?
-
是不是 RAG 没调明白?
这些都有影响,但都不是根本原因。
1.2 真正的答案
越来越多团队发现:真正决定系统能不能稳定跑起来的,不是模型本身,而是模型外面那套运行的系统。
这套东西,现在有了一个统一的名字------Harness。
Harness 原意是"马具、缰绳",放在 AI 系统里,就是在提醒我们:
当模型从"回答问题"走向"执行任务",系统不只要能够"喂信息",还要能够"驾驭整个过程"。
二、三阶演进:从 Prompt 到 Context 到 Harness
过去两年,AI 工程经历了三次明显的中心迁移:
| 阶段 | 核心问题 | 答案 |
|---|---|---|
| Prompt Engineering | 模型有没有听懂你在说什么? | 把任务讲清楚 |
| Context Engineering | 模型有没有拿到足够且正确的信息? | 把信息给对 |
| Harness Engineering | 模型在真实执行中能不能持续做对? | 驾驭整个过程 |
这三个词对应了 AI 系统发展的三个阶段性瓶颈,是一层一层往外扩张的。
2.1 第一阶:Prompt Engineering
"模型不是不会,是你没有把问题说明白。"
在大模型刚火起来的时候,大家最直观的感受是:同一个模型,你换一种说法,结果可能差很多。
markdown
# 不好的 prompt
总结这篇文章
# 好的 prompt
你是一个专业的编辑。请用以下格式总结这篇文章:
- 核心观点(1-2句话)
- 关键论据(3-5个要点)
- 我的建议(基于文章内容的延伸思考)
为什么有效?
大模型本质上是一个对上下文非常敏感的概率生成系统:
-
你给它什么身份,它容易沿着那个身份去回答
-
你给它什么样的样例,它容易沿着那个范式去补全
-
你强调什么样的约束,它容易把那部分当成重点
Prompt Engineering 的本质:不是命令模型,而是塑造一个局部的概率空间。
局限性:
Prompt 擅长的是"约束输出、激发已有能力",但不擅长:
-
弥补缺失的知识
-
管理大量动态信息
-
处理长链路任务里的状态
Prompt 解决的是"表达"的问题,不是"信息"的问题。
2.2 第二阶:Context Engineering
"模型未必是知道的,系统必须在合适的时机把正确的信息送进去。"
当 Agent 开始火了,模型不只是要回答问题,而是要进到真实环境里做事情:多轮对话、调浏览器、写代码、查数据库、在多个步骤之间传递中间结果、根据外部反馈不断修订计划。
这时问题变了:系统面对的已经不是"一次回答对不对",而是"整条链路的任务能不能跑通"。
Context Engineering 的核心:
Context 不只是几段背景资料。在工程意义上,它代表了所有影响模型当前决策的信息的总和:
-
用户的输入
-
历史对话
-
检索结果
-
工具返回
-
当前任务的状态
-
中间产物
-
系统规则
-
安全约束
-
其他 Agent 传过来的结构化结果
Prompt 只是 Context 的一部分。
典型实践:RAG
RAG 的价值很直接:模型参数里面没有的知识,怎么在运行时补进去?先检索,再把相关内容塞到上下文。
但成熟的 Context Engineering 关注的不只是检索,而是整条完整的链路:
-
文档怎么切块
-
结果怎么排序
-
长文怎么压缩
-
历史对话什么时候保留、什么时候摘要
-
工具返回要不要全部暴露给模型
-
多个 Agent 之间到底传原文、摘要还是结构化字段
进阶实践:渐进式披露(Progressive Disclosure)
这是 HomeSense 的核心创新之一。
传统做法(MCP)的问题:把十几个不同工具的说明、所有参数定义全部一上来就塞给模型。理论上模型知道得更多,但实践往往更糟------因为上下文窗口是稀缺资源,信息一多,注意力就会涣散。
Skill 采用的思路:
-
不是一开始就把所有能力给模型看
-
只给它看最少量的元信息
-
等它真正要触发某些能力时,再把那部分的 SOP、详细参考信息、脚本动态加载进来
Context Engineering 的启示:上下文的优化不只是"给更多",而是"按需给、分层给、在正确的时机给"。
局限性:
Context Engineering 解决的是"输入侧"的问题------提示词优化意图的表达,上下文优化信息的供给。
但复杂的任务里还有一个更难的问题:当模型开始连续行动的时候,谁来监督它、约束它、纠偏它?
2.3 第三阶:Harness Engineering
"Harness 原意是缰绳、马具。放到 AI 系统里,就是提醒我们:当模型从回答问题走向执行任务,系统不只要能够喂信息,还要能够驾驭整个过程。"
如果前两代工程关注的是"怎么让模型更会想",那 Harness 关注的就是:
-
怎么让模型别跑偏
-
怎么让模型跑得稳
-
怎么让模型出了错还能拉回来
一个通俗的比喻:
假设你要派一个新人去完成一次重要的客户拜访:
| 阶段 | 对应 | 做法 |
|---|---|---|
| Prompt Engineering | 把任务讲清楚 | "见面先寒暄,再介绍方案,最后确认下一步" |
| Context Engineering | 把资料准备齐全 | 客户背景、过往沟通记录、产品报价、竞品情况 |
| Harness Engineering | 驾驭整个过程 | 带 checklist、关键节点实时汇报、会后核实纪要、发现偏差马上纠正、按明确标准验收 |
Harness 的核心公式:
Agent = Model + Harness
Harness = Agent - Model
翻译:在一个 Agent 系统里,除了模型本身以外,几乎所有能决定它能不能稳定交付的东西,都可以算进 Harness。
三、一个成熟 Harness 的六层架构
基于 HomeSense 的实践和行业研究,一个成熟的 Harness 应该包含六层:
3.1 第一层:上下文边界控制
模型能不能稳定发挥,很多时候不仅取决于它聪不聪明,而取决于它看到了什么。
包含三件事:
-
角色的目标和定义:模型要知道自己是谁、任务是什么、成功的标准是什么
-
信息的裁剪和选择:上下文不是越多越好,而是越相关越好
-
结构化的组织:固定的规则放哪、当前任务放哪、任务运行的状态放哪、外部的证据放哪------分层清晰,信息一旦乱掉,模型就容易漏重点、忘约束、甚至自我污染
3.2 第二层:工具系统
没有工具,大模型本质上还是一个文本预测器------会解释、会总结,但接触不到真实的世界。
Harness 在这里要解决三个问题:
-
给它什么工具:工具太少能力不够,工具太多模型会乱用
-
什么时候该调用工具:本来不需要查的时候别乱查,该查的时候也别硬答
-
工具结果怎么重新喂回模型:搜索过来的几十条结果不应该原封不动塞回去,要提炼、筛选、保持相关性
HomeSense 的实现:
typescript
// 工具返回统一格式
interface ToolResult {
success: boolean;
result?: any;
error?: string;
}
// 工具执行器
async function executeToolAction(action: ToolAction): Promise<ToolResult> {
const tool = getTool(action.tool);
if (!tool) return { success: false, error: `Tool ${action.tool} not found` };
return await tool.execute(action.action, action.params);
}
3.3 第三层:执行编排
这一层解决的核心问题是:模型下一步该做什么?
很多 Agent 的问题不是"某一步不会",而是"不会把所有的步骤串起来"。它会搜索、也会总结、也会写代码,但整个过程想到哪做到哪,最后交付一堆半成品。
一个完整的任务需要这样的轨道:
-
理解目标
-
判断信息够不够(不够就继续补)
-
基于结果继续分析
-
生成输出
-
检查输出(不满足要求就修正或重试)
HomeSense 的实现:LangGraph 状态图
typescript
// graph.ts - 七节点主链
const workflow = new StateGraph(AgentState)
.addNode("context_builder", contextBuilderNode)
.addNode("rule_engine", ruleEngineNode)
.addNode("local_intent", localIntentNode)
.addNode("success_paths", successPathsNode)
.addNode("llm_agent", llmAgentNode)
.addNode("tool_executor", toolExecutorNode)
.addNode("write_back", writeBackNode)
.addConditionalEdges("rule_engine", (state) => {
if (state.ruleMatched) return "tool_executor";
return "local_intent";
});
3.4 第四层:记忆与状态
没有状态的 Agent,每一轮都会像失忆一样------不知道自己刚做了啥,也不知道哪些结论已经确认了、哪些问题还没解决。
Harness 至少要分清三类:
-
当前任务的状态:正在执行的步骤、中间结果
-
会话中的中间结果:已经确认的结论
-
长期的记忆和用户偏好:跨会话的经验
HomeSense 的实现:
sql
-- 对话历史
CREATE TABLE messages (
id INTEGER PRIMARY KEY,
role TEXT,
content TEXT,
created_at TIMESTAMP
);
-- 成功路径(经验库)
CREATE TABLE success_paths (
id INTEGER PRIMARY KEY,
user_input TEXT,
intent TEXT,
actions JSON,
success_count INTEGER,
embedding BLOB
);
3.5 第五层:评估与观测
很多系统不是生成不出来,而是生成完了之后根本不知道自己做得好不好。
这一层包括:
-
输出的验收与环境的验证
-
自动的测试、日志和指标
-
错误的归因
系统不仅要会做,还要知道自己有没有真的能够做对。
HomeSense 的实现:
typescript
// /api/chat 返回结构
{
reply: string;
matched: boolean;
stage: string;
trace: StageTraceEntry[];
outcomeType: 'success' | 'failure' | 'fallback';
resolutionSource: 'rule_engine' | 'local_intent' | 'success_paths' | 'llm_agent';
}
3.6 第六层:约束、校验、失败与恢复
这一层往往才是真正决定系统能不能上线的关键环节。
在真实环境里,失败不是例外,而是常态:
-
搜索可能不准
-
API 可能超时
-
文档格式可能混乱
-
模型可能误解任务
一个成熟的 Harness 必须包括三件事:
-
约束:哪些能做,哪些不能做
-
校验:输出之前、输出之后要怎么检查
-
恢复:失败之后怎么重试、切入降级、回滚到稳定状态
HomeSense 的实现:
typescript
// tool_executor 的失败归因
const stageResult = createStageResult({
ok: successCount === toolResults.length,
stage: "tool_executor",
reason: toolResults.length === 0 ? "no_actions" : "tool_execution_completed",
data: {
toolResults,
failureAttribution: toolResults.filter(r => !r.success).map(r => r.error)
}
});
四、一线公司的实践验证
4.1 LangChain
在底层模型完全不变的情况下,只通过改造和迭代 Harness,就把自家的智能体体验从一个榜单上的排名直接从 30 开外杀到了前五。
4.2 OpenAI
依靠一个只有几名人类工程师的团队,用 Agent 从零构建了一个超百万行代码的生产级应用。百分之百的代码由 Agent 编写,耗时只有纯人工开发的 1/10。
关键实践:
-
生产验收分离:Planner 负责扩展需求,Generator 负责实现,Evaluator 负责真实测试
-
渐进式披露 :把巨大的
AGENT.md变成目录页,只保留核心索引,详细内容放到子文档 -
让 Agent 看见结果:接浏览器、能截图、能点页面、能查日志监控
4.3 Anthropic
构建了一个可以完全自主编码的系统,只凭一句自然语言的需求,就能在无需人类干预的情况下连续运行几个小时,最后做出完整的游戏、完整的数字音频工作站。
关键发现与解决方案:
-
上下文污染 :上下文越来越满,模型开始丢细节、丢重点 → Context Reset:换一个全新的 Agent,把工作交接给它
-
自评失真 :模型自己干活再自己打分,往往偏乐观 → 生产验收分离:Evaluator 真实操作页面检查结果
五、HomeSense 的 Harness 实现全景
5.1 六层对应关系
| Harness 层 | HomeSense 组件 |
|---|---|
| 上下文边界控制 | Context Builder + IntentSchema |
| 工具系统 | rule_engine / local_intent / success_paths / adb / hami |
| 执行编排 | LangGraph + 七节点主链 |
| 记忆与状态 | messages 表 + success_paths + write_back |
| 评估与观测 | trace + stage + outcomeType + resolutionSource |
| 约束校验恢复 | tool_executor 失败归因 + 重试 + fallback |
5.2 完整数据流
text
用户输入
↓
/api/chat → graph.invoke()
↓
┌─────────────────────────────────────────────────────────────┐
│ Fast Layer │
├─────────────────────────────────────────────────────────────┤
│ context_builder → rule_engine → local_intent → success_paths │
└─────────────────────────────────────────────────────────────┘
↓(未命中)
┌─────────────────────────────────────────────────────────────┐
│ Deep Layer │
├─────────────────────────────────────────────────────────────┤
│ llm_agent(入口已接,真实能力待补) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Execution Layer │
├─────────────────────────────────────────────────────────────┤
│ tool_executor → 执行 actions → 返回结果 │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Reflection Layer │
├─────────────────────────────────────────────────────────────┤
│ write_back → 存经验到 success_paths │
└─────────────────────────────────────────────────────────────┘
↓
返回 StageResult(含 reply、trace、intent、stage、next)
5.3 统一协议
typescript
// StageResult - 所有节点统一输出
interface StageResult {
schemaVersion: "v0";
ok: boolean;
stage: string; // 当前阶段
next: string; // 下一个节点
message?: string; // 给用户的回复
reason?: string; // 原因
confidence?: number; // 置信度
intent?: IntentSchema; // 意图
actions?: ToolAction[]; // 要执行的动作
data?: Record<string, unknown>;
meta?: { source?: string; latencyMs?: number; trace?: Record<string, unknown> };
}
六、核心理念总结
| 阶段 | 核心问题 | 答案 | HomeSense 实现 |
|---|---|---|---|
| Prompt Engineering | 模型有没有听懂? | 把任务讲清楚 | 规则引擎 + 本地意图 |
| Context Engineering | 信息有没有给对? | 按需供给、渐进披露 | Context Builder + Skills |
| Harness Engineering | 执行能不能做对? | 驾驭整个过程 | Graph 调度 + 经验写回 + 治理 |
三者不是替代关系,而是包含关系:
-
Prompt 是对指令的工程化
-
Context 是对输入环境的工程化
-
Harness 是对整个运行系统的工程化
它们的边界是一层比一层大的。
七、写在最后
7.1 核心结论
真正决定上限的可能是模型,但真正决定能不能落地、能不能稳定交付的,是 Harness。
当任务还是简单的单轮生成时,Prompt 很重要。
当任务开始依赖外部知识、运行时信息时,Context 很关键。
当模型真正进入长链路、可执行、低容错的真实场景时,Harness 几乎就是不可避免的。
7.2 我们的实践验证
HomeSense 从一个简单的"规则匹配返回字符串"的原型,演进到了拥有完整 Harness 六层架构的通用 Agent 框架:
-
Fast Layer:规则引擎、本地意图、成功路径检索
-
Deep Layer:LLM Agent 规划与执行(入口已接)
-
Execution Layer:工具执行与失败归因
-
Reflection Layer:经验写回与自我增强
-
治理面板:经验聚类、合并、异常筛选、规则生命周期
7.3 下一步
AI 落地的核心挑战,正在从"让模型看起来更聪明"转向"让模型在真实世界里稳定地工作"。
Harness Engineering 不是终点,而是新起点。