拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI Agent Harness Engineering 执行链路分层模型:从意图解析、规划、决策到工具调用

AI Agent Harness Engineering 执行链路分层模型:从意图解析、规划、决策到工具调用 1. 为什么 Agent 跑着跑着就“散架”了AI Agent 最让人头疼的不是模型不够聪明而是执行链路一长就开始“散架”用户说“帮我查下上周的订单退款到账没没到就催一下”结果 Agent 要么把“查订单”和“催退款”混成一个动作要么在工具调用时把参数传错最后返回一句“已完成”但什么都没做。这类问题的根因通常不是模型能力而是执行链路缺少清晰的分层边界——意图解析、任务规划、决策、工具调用四层揉在一起任何一层出错都会污染整条链路。Harness Engineering驾驭工程要解决的就是这件事把 Agent 的执行过程拆成可观测、可替换、可单测的四层每层只做一件事层与层之间用结构化数据通信。这样你才能定位“到底是意图理解错了还是规划漏了一步还是工具参数拼错了”。本文以意图解析、任务规划、决策、工具调用为主线结合 TaoToken 统一 Key/API 通道给出一套可复制的分层配置骨架含settings.json/config.toml示例和逐层验证动作帮你在本地跑通一条完整 Agent 调用链。适合有一定 Python 基础、正在搭 Agent 但被“链路不可控”卡住的开发者。2. TaoToken 前置统一 Key 与 API 通道分层模型要落地第一件事是让四层共用同一个模型入口。如果意图解析用一家 API、规划用另一家、工具调用再换一家排障时你根本分不清是层的问题还是通道的问题。TaoToken 在这里的角色是统一 Key/API 通道一个 Key 覆盖对话、编码、Agent 场景四层都走同一个base_url出问题时先排除通道因素。你需要准备的东西很少一个 TaoToken API Key以及确认本地能访问https://taotoken.net/api。Key 在控制台的 API Keys 页面创建建议按项目建独立 Key方便后续按层统计调用量。模型对话能力可以先在模型对话页验证确认 Key 可用再写代码。注意四层共用 Key 不代表共用模型。意图解析可以用小模型降本规划和决策用强模型工具调用层甚至可以不用模型纯函数路由。统一的是通道不是模型选择。配置上我习惯把通道信息抽到一个环境变量文件代码里只读变量避免 Key 硬编码进settings.json被误提交。下面第三节的配置骨架会体现这个思路。3. 可复制的分层配置骨架先给目录结构四层各一个模块配置集中在config/下agent-harness/ ├── config/ │ ├── settings.json # 通道与模型配置 │ └── config.toml # 分层行为配置 ├── layers/ │ ├── intent.py # 意图解析层 │ ├── planner.py # 任务规划层 │ ├── decision.py # 决策层 │ └── tool_call.py # 工具调用层 └── run_chain.py # 串联四层的入口settings.json负责“连哪里、用什么模型”{ channel: { base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY, timeout_seconds: 60 }, models: { intent: claude-3-5-haiku, planner: claude-3-5-sonnet, decision: claude-3-5-sonnet, tool_router: claude-3-5-haiku }, retry: { max_attempts: 3, backoff_seconds: 2 } }config.toml负责“每层怎么表现”这是分层模型真正可调的地方[intent] # 意图解析层要求输出严格 JSON置信度低于阈值触发澄清 output_format json confidence_threshold 0.7 max_clarify_rounds 2 [planner] # 任务规划层限制单次规划的最大步数防止无限展开 max_steps 8 allow_parallel false require_dependency true [decision] # 决策层候选动作打分低于阈值回退到规划层重规划 score_threshold 0.6 fallback_to_planner true [tool_call] # 工具调用层白名单 参数校验禁止未注册工具 tool_whitelist [search_order, check_refund, send_reminder] strict_params true dry_run false意图解析层的核心是把自然语言压成结构化意图。关键不是提示词写多花而是强制 JSON 输出 置信度字段import json, os, requests def parse_intent(user_input: str, cfg: dict) - dict: prompt f把用户输入解析为 JSON字段 intent_type, confidence(0-1), entities(list), slots(dict)。 只输出 JSON不要解释。 用户输入{user_input} resp requests.post( f{cfg[channel][base_url]}/v1/messages, headers{Authorization: fBearer {os.environ[cfg[channel][api_key_env]]}}, json{model: cfg[models][intent], max_tokens: 512, messages: [{role: user, content: prompt}]}, timeoutcfg[channel][timeout_seconds], ) resp.raise_for_status() text resp.json()[content][0][text] return json.loads(text)任务规划层接收意图输出带依赖的任务列表。这里最容易踩的坑是让模型自由发挥结果任务顺序乱掉。用max_steps和require_dependency两个约束把它框住def plan_tasks(intent: dict, cfg: dict) - list: prompt f根据意图生成任务列表最多 {cfg[planner][max_steps]} 步。 每个任务含 id, name, tool, params, depends_on。 只输出 JSON 数组。 意图{json.dumps(intent, ensure_asciiFalse)} # 调用逻辑同上模型换成 cfg[models][planner] ...决策层负责在多个候选动作里选一个工具调用层负责把选中的动作变成真实请求。这两层分开的好处是决策可以纯逻辑打分不调模型工具调用可以dry_run先验证参数再真跑。4. 逐层验证从单层到整链配置写完别急着串整链逐层验证能省掉大量“到底哪层错了”的时间。每层都设计一个最小可观测输出。意图解析层验证喂一句带歧义的话看置信度和槽位是否合理。intent parse_intent(上周那个订单退款到了吗没到帮我催下, cfg) print(json.dumps(intent, ensure_asciiFalse, indent2)) # 期望intent_typeorder_refund_checkslots 含 order_time上周 # confidence 若 0.7 应触发澄清而不是硬猜任务规划层验证确认任务有依赖、步数不超限。tasks plan_tasks(intent, cfg) assert len(tasks) cfg[planner][max_steps] assert all(depends_on in t for t in tasks) print([t[name] for t in tasks]) # 期望[查询订单, 检查退款状态, 发送催办]且后两步依赖前一步决策层验证给两个候选动作看打分和回退逻辑。candidates [{action: check_refund, score: 0.82}, {action: send_reminder, score: 0.55}] chosen decide(candidates, cfg) # 期望选 check_refund若最高分 0.6 应回退到 planner工具调用层验证先dry_runtrue看参数再真跑。result call_tool(check_refund, {order_id: A123}, cfg, dry_runTrue) print(result) # 期望打印将要发送的请求体不发真实请求整链跑通后成功结果长这样输入一句自然语言终端依次打印[intent]、[plan]、[decision]、[tool]四行结构化日志最后返回“订单 A123 退款已到账”。任何一层异常日志会停在那一层而不是给你一个笼统的失败。5. 本篇常见错排查报错一json.decoder.JSONDecodeError在意图解析层。模型返回了带 markdown 代码块的 JSON。解决解析前先剥掉 json 包裹或在提示词里强调“只输出 JSON不要代码块”。更稳的做法是加一层extract_json()兜底。报错二规划层任务数超限或死循环。模型把“催办”拆成了无限重试。解决max_steps硬限制 在提示词里写明“不要生成重试类任务重试由工具调用层负责”。报错三工具调用层KeyError: order_id。决策层选对了工具但参数名和工具签名不一致。解决strict_paramstrue时调用前用工具 schema 校验参数缺字段直接抛错并回退到决策层而不是带着错参数发请求。报错四四层共用 Key 但某层 401。通常是环境变量没加载或 Key 建在了另一个项目下。解决在run_chain.py启动时打印base_url和 Key 前 6 位做自检确认通道一致。报错五整链超时。四层串行调用每层都等模型总耗时叠加。解决意图解析和工具路由用小模型规划和决策用强模型timeout_seconds按层设别全局一个值。6. 把链路固定下来再谈优化分层模型的价值不在“跑通一次”而在“每次都能定位到哪层”。我试过把四层日志统一成[layer][step][status]格式后排障时间从半小时降到几分钟。下一步你可以做两件事一是把config.toml里的阈值做成可热更新调参不用重启二是给每层加单测意图层测歧义句、规划层测步数上限、决策层测回退、工具层测参数校验。如果你还在选通道阶段建议先用模型对话页验证 Key 和模型可用性再按本文骨架接入。长期跑编码类或 Agent 类任务Coding Plan 的额度模型更适合高频调用接入细节和参数说明在接入文档里有完整字段表。把四层配置骨架复制过去改掉tool_whitelist和模型名你就能拥有一条可解释、可控制的 Agent 调用链。
返回列表