3.3 Harness 构建——把模型包成可运行的系统
概念
Harness 直译是"马具"或"安全带",在 AI 工程语境里,指的是包裹在模型外围的那层工程框架。光有一个模型不够,你得给它配上输入管道、输出管道、错误处理、安全护栏和监控仪表盘,它才能在客户现场稳定跑。
打个比方:模型是发动机,Harness 是整辆车。发动机再好,没有方向盘、刹车、仪表盘,你也没法开上路。
用法
一个能交付的 Harness 需要补齐五件套:
| # | 组件 | 作用 | 没有它会怎样 |
|---|---|---|---|
| 1 | 工具接入 | 让模型能调用外部 API/数据库/搜索 | 模型只会"说",不会"做" |
| 2 | 输入输出契约 | 定义输入 Schema 和输出 Schema 的校验 | 客户系统集成时格式不匹配 |
| 3 | 错误处理 | 工具调用失败、模型超时、格式异常时的兜底 | 一个 API 报错就整个 Demo 崩 |
| 4 | 护栏门禁 | 输入侧过滤敏感请求,输出侧检查合规性 | 模型输出违规内容,客户投诉 |
| 5 | 可观测 | 日志、Trace、指标监控 | 出了问题不知道哪一步坏了 |
🖼 图:harness five components
示例
假设你在给客户搭一个"智能运维诊断 Agent",五件套长这样:
① 工具接入——定义模型能调用的工具:
工具清单:
- get_server_logs(server_id, time_range) → 拉取服务器日志
- query_monitoring_metrics(server_id, metric) → 查询监控指标
- search_kb(keyword) → 搜索知识库历史案例
② 输入输出契约——定义进出格式:
输入 Schema:
{
"server_id": "string, 必填",
"symptom": "string, 必填, 用户描述的症状",
"time_range": "string, 选填, 默认最近1小时"
}
输出 Schema:
{
"diagnosis": "string, 诊断结论",
"evidence": "array, 支撑诊断的证据列表",
"suggestion": "string, 处理建议",
"confidence": "number, 置信度 0-1"
}
预期输出:
{
"diagnosis": "磁盘空间不足导致服务异常",
"evidence": ["/var/log 使用率 98%", "syslog 报 No space left on device"],
"suggestion": "清理 /var/log 下 7 天前的日志文件",
"confidence": 0.92
}
③ 错误处理——每个失败点都有兜底:
工具调用超时(>10s)→ 返回 "当前监控系统响应较慢,请稍后重试"
工具返回空结果 → 返回 "未找到相关指标,建议人工核查"
模型输出非 JSON → 重试 1 次,仍失败则返回固定兜底模板
④ 护栏门禁——输入输出双向过滤:
输入侧护栏:
- 检测是否包含敏感信息(密码、密钥)→ 脱敏后处理
- 检测是否超出业务范围(如问天气)→ 拒绝并提示"仅支持运维诊断"
输出侧护栏:
- 检查诊断是否涉及危险操作(如 rm -rf)→ 追加"请人工确认后执行"
- 检查 confidence < 0.5 → 标记"低置信度,建议人工复核"
⑤ 可观测——三个维度的监控:
| 维度 | 记录什么 | 为什么要记 |
|---|---|---|
| 日志 | 每次输入、模型输出、工具调用入参出参 | 出问题能回溯 |
| Trace | 一次请求经过的每一步耗时 | 定位瓶颈在哪 |
| 指标 | 调用成功率、平均耗时、Token 消耗、置信度分布 | 量化系统健康度 |
**⚠️ 风险提示:**最常见的交付事故是"Demo 能跑但上了量就崩"。原因通常是第 3 件(错误处理)缺失——Demo 环境一切顺利,到了客户现场某个 API 偶尔超时,模型拿到错误结果继续推理,越走越偏。所以五件套不是"有就行",是"每一件都要在客户场景下测过"。
随堂测
逐题作答,即时反馈
1. 关于 Harness 的概念,下列说法与课文一致的是?
2. 一个能交付的 Harness 需要补齐的“五件套”不包括下列哪一项?
3. 最常见的交付事故是“Demo 能跑但上了量就崩”,课文指出其原因通常是五件套中哪一件缺失?