Agent技能工程:可测试、可编排、可治理的智能体落地实践
1. “agent-skills”不是新词而是智能体工程落地的临界信号最近在几个技术社区和内部项目复盘会上反复看到“agent-skills”这个组合被开发者随手写在白板角落、贴在PR描述里甚至出现在某高校AI课程实验手册的标题栏——但它既不是某个开源库的官方命名也不是某家大厂刚发布的SDK代号。它没有文档首页没有npm包没有GitHub star数却像一滴水渗进混凝土缝隙那样悄然定义着当前智能体Agent开发中最真实、最棘手、也最具实操价值的一类问题域。我把它理解为当一个智能体不再满足于“能思考”而必须“会做事”时它所依赖的、可拆解、可测试、可复用、可编排的最小能力单元集合。它不是LLM的推理能力不是RAG的检索能力更不是系统提示词的精巧程度它是让智能体真正走出沙盒、接入现实世界动作链的“肌肉群”。比如调用企业内部审批API完成请假单提交、从三份PDF合同中比对出违约金条款差异并高亮标注、根据用户语音指令自动重排Outlook日程且同步通知参会人——这些都不是单次prompt能闭环的事背后是一组经过验证、带错误兜底、有输入校验、可独立单元测试的技能模块。这个词之所以没进词典恰恰因为它太“脏”——它诞生于调试日志里反复出现的skill_not_found报错来自CI流水线中因某个技能超时导致的整条Agent工作流失败也来自产品经理指着原型说“这个‘查库存’按钮点下去得真的扣减库存不是只返回一句‘已查到’”。它不性感但它是横亘在Demo和生产之间的那堵墙。关键词虽为空但结合当前技术演进节奏它的隐含语义非常清晰技能封装规范、执行上下文管理、异步结果归集、失败重试策略、权限与审计日志嵌入、与外部系统身份凭证的安全传递。这不是纯算法问题而是典型的“最后一公里”工程问题——模型再强不会调用数据库连接池也不会处理OAuth2.0 token过期刷新。而“agent-skills”正是把这类问题从混沌中打捞出来、赋予结构、建立契约的实践锚点。如果你正在做以下任何一件事这个词就和你有关正在把一个LLM应用从“聊天机器人”升级为“自动化协作者”在设计Agent架构时发现“工具调用”模块越来越臃肿不同业务线的API封装逻辑互相污染被测试同学追问“这个‘生成周报’技能输入格式变更后你们怎么保证下游所有用到它的Agent都不崩”或者你只是在深夜改完第7版system prompt后突然意识到靠文本约束永远管不住一个要真正操作系统的智能体。它不承诺通用智能只解决一个朴素问题让智能体的每一次“动手”都像人类员工提交工单一样有据可查、有路可退、有责可溯。这才是当前阶段最值得沉下心来打磨的硬功夫。2. 技能不是函数是带契约的微型服务从代码片段到可交付单元的质变很多团队初期实现“agent-skills”就是写一堆Python函数塞进一个tools.py文件再用装饰器标记成tool。这没错但很快就会撞墙。我参与过三个不同规模的Agent项目无一例外都在第二迭代周期遭遇了同样的症状新增一个技能导致原有五个Agent行为异常测试环境跑通的功能在生产环境因权限配置差异直接静默失败运维同学拿着监控告警问“这个send_slack_alert技能为什么每分钟调用300次谁在用”根本原因在于把技能当成代码片段就等于把外科医生的手艺当成一把手术刀。刀本身不决定切口位置、不判断血管走向、不承担术后感染责任——而技能必须承担。真正的agent-skill是一个具备明确契约边界的微型服务。它必须回答六个不可回避的问题缺一不可问题维度具体内容为什么必须显式定义实际踩坑案例输入契约接收哪些参数类型、范围、必填/选填、默认值是否接受JSON Schema校验避免上游Agent传入非法数据导致下游系统崩溃或数据污染某财务Agent传入负数金额调用create_invoice发票系统未做校验生成了无效票据财务月结失败输出契约返回什么结构成功/失败分别返回什么字段错误码如何分类网络超时/业务拒绝/权限不足是否包含trace_id供全链路追踪让上游Agent能基于结构化响应做分支决策而非靠字符串匹配错误信息search_knowledge_base返回{result: []}和{error: timeout}混用导致Agent误判为“查无结果”而非“重试”执行边界单次调用最大耗时是否允许异步是否支持取消内存/CPU占用上限防止单个技能拖垮整个Agent调度器保障SLAgenerate_report_pdf在高并发时内存暴涨至2GB触发K8s OOMKilled连带杀死同Pod内其他技能安全契约需要哪些最小权限凭证如何注入环境变量/Secret Manager/临时Token是否记录操作日志谁、何时、对什么资源、做了什么满足等保/ISO27001审计要求避免权限过度暴露update_user_profile技能硬编码了数据库密码被扫描工具抓取导致横向渗透重试契约哪些错误可自动重试最多几次间隔策略固定/指数退避是否需要幂等性保障如重复调用不产生重复订单平衡用户体验与系统稳定性避免雪崩charge_payment技能对网络抖动重试3次结果用户银行卡被扣4次款可观测契约上报哪些指标调用量、P95延迟、错误率关键路径是否埋点是否支持分布式链路追踪快速定位故障根因区分是技能自身问题还是上游调用不当运维无法判断send_email高延迟是SMTP服务器问题还是Agent调度器排队导致提示不要试图在一个tool装饰器里塞进所有契约逻辑。我们团队最终采用分层封装底层是纯业务函数如def _send_email_raw(to, subject, body)中层是契约包装器EmailSenderSkill类内置输入校验、重试策略、日志埋点最上层才是Agent框架可识别的注册接口如register_tool(EmailSenderSkill())。这种分离让技能可独立单元测试也便于灰度发布——先上线新版本技能类再逐步切换Agent引用。一个典型技能类的骨架长这样以Python为例强调结构而非语法细节class SendSlackAlertSkill: 向指定Slack频道发送结构化告警消息支持Markdown和附件 # 输入契约严格定义自动生成OpenAPI Schema供Agent框架校验 INPUT_SCHEMA { type: object, properties: { channel_id: {type: string, minLength: 1}, severity: {type: string, enum: [low, medium, high, critical]}, message: {type: string, maxLength: 2000}, attachment_url: {type: string, format: uri, optional: True} }, required: [channel_id, severity, message] } def __init__(self, slack_client: SlackClient, logger: Logger): # 依赖注入非全局单例便于测试隔离 self._client slack_client self._logger logger def execute(self, **kwargs) - dict: # 执行契约统一入口强制遵循所有约定 try: # 1. 输入校验自动基于INPUT_SCHEMA validated_input self._validate_input(kwargs) # 2. 权限检查此处检查当前token是否有该channel写权限 if not self._check_channel_permission(validated_input[channel_id]): raise PermissionDeniedError(fNo write access to channel {validated_input[channel_id]}) # 3. 执行核心逻辑带超时和重试 result self._client.chat_postMessage( channelvalidated_input[channel_id], textf[{validated_input[severity].upper()}] {validated_input[message]}, attachmentsself._build_attachments(validated_input), timeout10.0 # 执行边界硬性超时 ) # 4. 输出契约结构化成功响应 return { status: success, message_id: result[ts], channel_id: validated_input[channel_id], trace_id: self._logger.get_trace_id() # 可观测契约 } except SlackApiError as e: # 5. 错误分类与契约化输出 error_code self._map_slack_error(e.response[error]) self._logger.error(fSlack API error: {error_code}, extra{slack_error: e.response[error]}) return { status: error, error_code: error_code, error_message: str(e), trace_id: self._logger.get_trace_id() } except Exception as e: # 6. 未预期错误兜底 self._logger.exception(Unexpected error in SendSlackAlertSkill) return { status: error, error_code: INTERNAL_ERROR, error_message: Service unavailable, trace_id: self._logger.get_trace_id() } def _validate_input(self, raw_input: dict) - dict: # 使用jsonschema.validate失败抛出ValidationError pass def _check_channel_permission(self, channel_id: str) - bool: # 调用Slack Admin API检查权限带缓存 pass def _build_attachments(self, input_data: dict) - list: # 构建Slack附件结构 pass def _map_slack_error(self, slack_error: str) - str: # 将Slack原始错误映射为业务错误码 mapping { not_in_channel: CHANNEL_ACCESS_DENIED, rate_limited: RATE_LIMIT_EXCEEDED, invalid_auth: INVALID_CREDENTIALS } return mapping.get(slack_error, UNKNOWN_SLACK_ERROR)这个类本身就是一个可独立部署、可独立压测、可独立监控的单元。你可以把它打包成gRPC服务也可以作为本地库被Agent进程直接调用——契约不变实现可换。这才是“技能”该有的样子不是代码快照而是服务契约。3. 技能编排不是流程图是状态机驱动的韧性协作当单个技能足够健壮后下一个深渊是如何让多个技能像一支训练有素的特勤小队那样协同作业而不是一群各自为战的散兵游勇很多人第一反应是画流程图、写YAML编排文件、或者堆if-else逻辑。但我们在某跨平台客服Agent项目中发现这种思路在复杂场景下必然失效。举个真实案例用户请求“帮我取消昨天下午3点预约的杭州西湖区门店美甲服务并退还预付款”。这个需求需要至少5个技能串联find_appointment_by_time查预约verify_user_identity核验身份需短信验证码check_refund_policy查退款规则可能涉及阶梯费率cancel_appointment取消预约refund_payment原路退款表面看是线性流程但实际充满不确定性用户可能输错手机号verify_user_identity失败需重新发起验证check_refund_policy可能返回“需人工审核”此时流程要暂停等待运营后台确认refund_payment调用第三方支付网关失败需降级为“退款待处理”并通知用户预计时间用户在流程中途退出App系统需保存当前进度下次回来继续。如果用传统流程引擎如Airflow DAG、Camunda BPMN你会陷入无穷无尽的状态管理泥潭每个节点都要定义“成功跳转”、“失败跳转”、“超时跳转”、“人工干预跳转”配置爆炸且难以测试。我们最终采用事件驱动有限状态机FSM的方式重构技能编排。核心思想是不预设完整路径而是定义每个技能执行后的“事件”由状态机根据当前状态和事件决定下一步动作。3.1 状态机设计用最少状态覆盖最大变数我们为上述美甲取消场景定义了7个核心状态状态名触发条件允许的转入事件下一状态示例关键动作INIT流程启动USER_REQUEST_RECEIVEDWAITING_FOR_IDENTITY_VERIFICATION解析用户意图提取时间/地点/服务类型WAITING_FOR_IDENTITY_VERIFICATION等待身份核验VERIFICATION_SUCCESSFINDING_APPOINTMENT发送短信验证码启动倒计时VERIFICATION_FAILEDWAITING_FOR_IDENTITY_VERIFICATION重发验证码记录失败次数VERIFICATION_TIMEOUTFAILED标记流程超时通知用户FINDING_APPOINTMENT查预约中APPOINTMENT_FOUNDCHECKING_REFUND_POLICY加载预约详情校验门店/服务有效性APPOINTMENT_NOT_FOUNDFAILED返回友好提示“未找到对应预约”CHECKING_REFUND_POLICY查退款规则POLICY_AUTO_APPROVEDCANCELLING_APPOINTMENT计算应退金额生成退款单POLICY_REQUIRES_MANUAL_APPROVALWAITING_FOR_MANUAL_APPROVAL创建工单通知运营暂停流程WAITING_FOR_MANUAL_APPROVAL等待人工审核MANUAL_APPROVAL_GRANTEDCANCELLING_APPOINTMENT恢复流程继续执行MANUAL_APPROVAL_DENIEDFAILED通知用户“退款申请未通过”CANCELLING_APPOINTMENT取消预约中APPOINTMENT_CANCELLEDREFUNDING_PAYMENT更新预约状态为“已取消”CANCELLATION_FAILEDRETRYING_CANCELLATION记录错误按策略重试最多3次REFUNDING_PAYMENT退款中REFUND_SUCCESSCOMPLETED发送成功通知关闭流程REFUND_FAILEDREFUNDING_PAYMENT降级为“退款待处理”更新状态并通知注意状态机不关心“谁”执行了技能只关心“执行结果”触发了什么事件。find_appointment_by_time技能成功后主动发布APPOINTMENT_FOUND事件失败则发布APPOINTMENT_NOT_FOUND事件。技能与编排完全解耦。3.2 事件总线轻量级、高可靠的消息中枢我们没有引入Kafka或RabbitMQ这类重型消息中间件而是用Redis Streams构建了一个极简事件总线。原因很实在Redis Streams天然支持消费者组Consumer Group确保每个事件只被一个编排实例处理支持消息持久化和ACK机制断电重启后不丢事件延迟低P99 5ms满足实时交互需求运维成本几乎为零与现有Redis集群共用。事件结构极其简单符合“最小必要信息”原则{ event_id: evt_abc123, event_type: APPOINTMENT_FOUND, payload: { appointment_id: app_789, user_id: usr_456, scheduled_time: 2024-05-20T15:00:00Z, store_id: st_hangzhou_xihuxi }, source_skill: find_appointment_by_time, timestamp: 2024-05-20T14:22:33.123Z }编排服务Orchestrator作为消费者组成员持续监听agent-skill-events流。收到事件后查询当前流程实例的状态查表得到下一动作然后如果是调用新技能则向技能执行器Executor发送RPC请求如果是等待人工审核则向工单系统创建记录并向用户推送消息如果是流程结束则更新数据库状态发送完成通知。3.3 失败处理不是重试而是优雅降级与用户共担状态机最大的价值是让失败处理变得可预测、可设计。我们彻底抛弃了“无限重试直到成功”的幻想代之以分级降级策略失败类型降级动作用户感知后台动作瞬时性失败网络超时、DB连接池满自动重试指数退避最多3次无感显示“处理中...”记录重试日志监控重试率业务性失败余额不足、库存为零中断流程返回结构化错误显示“抱歉您的账户余额不足请充值后重试”记录业务错误触发风控告警需人工介入失败政策变更、资质过期暂停流程创建人工工单显示“您的请求需人工审核预计2小时内回复”通知运营附带完整上下文快照系统性失败技能服务宕机、认证中心不可用切换备用技能如降级为邮件通知显示“系统繁忙已通过邮件发送处理结果”触发熔断告警值班工程师关键经验永远假设技能会失败但绝不假设用户会容忍失败。每次失败都必须提供明确的下一步指引——要么自动恢复要么告知用户做什么要么承诺后续动作。这比“请稍后再试”有力一万倍。4. 技能治理从个人英雄主义到可审计、可演进的工程体系当团队拥有20个技能、5个Agent应用、每天处理数万次技能调用时“agent-skills”就不再是技术选型问题而是组织工程能力的试金石。我们曾经历过这样的混乱新人入职花两天时间才搞懂get_weather技能为什么在测试环境返回北京天气生产环境却返回上海安全部门突击检查发现3个技能仍在使用已废弃的旧版API密钥A团队优化了translate_text技能的性能B团队的Agent却因此出现乱码——因为B团队依赖了旧版返回的language_code字段格式。症结在于技能缺乏统一治理变成了一个个孤岛式的“黑盒”。解决之道是建立一套轻量但坚实的技能治理框架核心围绕三个支柱注册中心、契约仓库、生命周期看板。4.1 技能注册中心让每个技能都有“身份证”我们基于Consul构建了一个极简注册中心每个技能部署时必须向其注册。注册信息不是简单的服务地址而是包含契约元数据的完整描述{ skill_id: send_slack_alert_v2, version: 2.1.0, description: 向Slack发送结构化告警支持附件和优先级标记, owner: infra-team, contact: infracompany.com, health_check_url: /health, input_schema: { ... }, // 同前文INPUT_SCHEMA output_schema: { ... }, sla: { p95_latency_ms: 800, availability_percent: 99.95 }, tags: [notification, alerting, slack], environments: [ { name: prod, address: https://skills-prod.company.com/send-slack-alert, auth_method: bearer_token, credential_scope: slack:write:channels }, { name: staging, address: https://skills-staging.company.com/send-slack-alert, auth_method: api_key, credential_scope: slack:read:channels } ] }提示注册中心不是配置中心它不存储运行时配置如API密钥只存储技能的“静态契约”和“环境路由信息”。密钥等敏感信息由独立的Secret Manager管理技能在启动时按需拉取。注册中心带来的直接收益Agent开发者的自助服务在内部Wiki搜索send_slack_alert立刻看到最新版本、输入输出示例、SLA指标、负责人邮箱自动化的契约校验Agent框架在启动时自动从注册中心拉取所依赖技能的input_schema在调用前做严格校验杜绝“传参错误”类线上事故环境隔离的天然保障Agent只需声明依赖send_slack_alert_v2框架自动根据当前环境prod/staging选择对应environments中的地址和认证方式无需硬编码。4.2 契约仓库用Git管理技能的“宪法”所有技能的INPUT_SCHEMA、OUTPUT_SCHEMA、SLA定义都必须以JSON Schema文件形式存放在一个专用Git仓库agent-skills-contracts中遵循严格的分支策略main分支生产环境使用的契约受保护合并需2人Code Review 自动化Schema校验develop分支开发中的契约变更可自由提交特性分支如feat/refund-policy-v2用于重大契约升级。每次契约变更尤其是破坏性变更如删除必填字段、修改错误码必须在develop分支提交新Schema运行自动化脚本对比main与develop的差异生成影响报告列出所有可能受影响的Agent通知相关Agent负责人协商升级计划在main分支合并时自动触发CI生成新版OpenAPI文档并部署到内部Swagger UI。这让我们彻底告别了“改一个技能崩一片Agent”的噩梦。契约即文档文档即契约Git历史就是完整的演进地图。4.3 生命周期看板可视化每个技能的健康度与进化轨迹我们用一个简单的内部Dashboard基于Grafana构建聚合展示所有技能的关键指标指标类别具体指标监控意义健康阈值告警动作可用性uptime_percent_7d连续7天服务在线率≥99.9%通知负责人检查基础设施性能p95_latency_ms95%请求的响应延迟≤1000ms分析慢查询优化SQL或缓存质量error_rate_1h每小时错误率非4xx业务错误≤0.5%检查日志定位异常模式治理last_updated_days距离上次契约更新天数≤90天提醒维护评估是否需重构依赖upstream_deps_count依赖的外部服务数量≤3个评估架构复杂度推动解耦看板不是摆设。每周站会团队会聚焦在“红色指标”上send_email技能的error_rate_1h连续3天超1%排查发现是SMTP服务商调整了发信频率限制立即切换备用通道generate_report_pdf技能的last_updated_days达120天触发重构任务用现代PDF库替代老旧的wkhtmltopdf性能提升4倍verify_user_identity技能的upstream_deps_count为5依赖短信、邮件、人脸识别、公安库、风控引擎推动将其拆分为sms_verification和biometric_verification两个独立技能。注意治理不是增加负担而是把隐形成本显性化。当一个技能的last_updated_days超过阈值不是批评开发者而是问“是什么阻碍了你及时更新是测试环境缺失是文档不全还是缺乏重构带宽”——然后移除障碍。5. 技能测试超越单元测试构建端到端的韧性验证体系写测试是程序员的本能但为agent-skills写有效的测试却是多数团队的盲区。我们见过太多这样的“测试”单元测试只覆盖execute()函数的happy path对超时、网络错误、权限拒绝等分支置之不理集成测试用Mock模拟所有外部依赖结果测试通过上线后第一次调用真实API就失败性能测试只测单次调用完全不考虑高并发下连接池耗尽、线程阻塞的真实场景。真正的agent-skills测试必须是分层、真实、面向失败的。我们建立了四层测试金字塔每一层都针对不同风险5.1 第一层契约合规性测试100%覆盖率这是最基础也最关键的测试。它不关心技能内部怎么实现只验证它是否严格遵守注册中心声明的契约。输入校验测试用JSON Schema Validator穷举所有非法输入空字符串、超长文本、非法枚举值、缺失必填字段确保技能返回标准错误响应status: error, error_code: VALIDATION_FAILED输出结构测试对每个成功/失败分支断言返回JSON的status字段、必填字段是否存在、字段类型是否正确错误码映射测试模拟各种外部API错误如Slack返回rate_limited验证技能是否准确映射为预定义的error_code如RATE_LIMIT_EXCEEDED。这类测试运行极快毫秒级可集成到CI的pre-commit钩子中。一个技能提交代码前必须通过所有契约测试否则禁止合并。这是防止“契约漂移”的第一道闸门。5.2 第二层沙盒集成测试覆盖80%真实依赖我们搭建了一个轻量级沙盒环境其中外部API如Slack、支付网关被替换为可控的Mock服务但行为高度拟真Slack Mock会真实模拟rate_limited错误随机返回429、not_in_channel错误需先调用join_channel接口支付网关Mock支持设置“成功率”可模拟99%成功、1%失败的场景数据库使用真实的PostgreSQL但数据是隔离的测试库认证服务使用真实的JWT签发但密钥是测试专用。测试用例设计原则每个技能必须覆盖其“黄金路径”和“三条最可能失败的路径”。例如refund_payment技能黄金路径调用成功返回REFUND_SUCCESS失败路径1支付网关返回INSUFFICIENT_FUNDS验证技能映射为INSUFFICIENT_FUNDS_ERROR失败路径2网络超时验证技能执行重试策略记录2次重试日志失败路径3用户账户被冻结验证技能返回ACCOUNT_FROZEN_ERROR。沙盒测试在CI中每日全量运行是发现集成问题的主力。5.3 第三层混沌工程测试每年2次深度验证当技能进入生产稳定期我们会进行混沌工程演练主动注入故障检验其韧性网络层用chaos-mesh随机丢弃5%的出向HTTP请求包依赖层将Slack Mock服务设置为50%概率返回503 Service Unavailable资源层用stress-ng消耗CPU至90%观察技能是否因超时被Kill数据层故意让数据库主从延迟至30秒测试读写一致性。演练不是为了“找出Bug”而是为了验证预案是否有效。例如当send_slack_alert在混沌中大量超时时我们验证是否触发了降级策略切换为邮件通知降级后的邮件是否包含了完整的上下文如原始Slack消息内容、trace_id监控告警是否准确指向send_slack_alert技能而非模糊的“Agent整体延迟”。每次混沌演练后必须更新《故障应对手册》明确“当X发生时Y技能应如何响应Z团队需在T时间内做什么”。5.4 第四层生产金丝雀测试100%流量0风险这是最高阶的测试也是我们最信赖的验证方式。新版本技能上线时首先部署到生产环境但不注册到注册中心处于“隐身”状态通过内部工具手动指定10个特定用户ID他们的Agent请求会被路由到新版本技能监控新版本的所有指标延迟、错误率、日志并与老版本实时对比若一切正常逐步扩大金丝雀比例1% → 10% → 50%若发现异常一键回滚老版本无缝接管。金丝雀测试的价值在于它用真实用户、真实数据、真实网络环境验证了技能在最严苛条件下的表现。没有比这更真实的测试了。经验之谈测试不是越多越好而是要精准打击风险。我们曾砍掉所有“覆盖率数字游戏”式的测试只保留这四层。结果是线上P0事故下降70%而测试维护成本反而降低。因为每个测试用例都明确对应一个曾经踩过的坑。6. 技能演进从工具调用到自主决策智能体能力的跃迁路径“agent-skills”绝非终点而是智能体能力演进的一个关键里程碑。当我们把技能打磨到可信赖、可编排、可治理的程度后真正的挑战才开始如何让智能体不再被动执行技能而是主动规划、动态选择、甚至创造新技能这不是科幻而是正在发生的工程实践。我们团队正沿着一条清晰的路径推进分为三个阶段6.1 阶段一确定性技能链当前主流特征Agent根据预设规则或简单条件判断从技能库中选择一个技能执行。示例“用户说‘查天气’调用get_weather技能说‘订餐厅’调用book_restaurant技能。”优势简单、可控、可解释局限无法处理模糊意图如“帮我搞定下周的出差安排”也无法应对技能执行过程中的意外如book_flight失败后自动尝试book_train。这是我们绝大多数项目的现状也是“agent-skills”概念最适用的阶段。重点是夯实基础契约、编排、治理、测试。6.2 阶段二规划式技能调度前沿实践特征Agent内部集成一个轻量级规划器Planner能将高层目标分解为技能调用序列并在执行中动态调整。示例用户请求“策划一次杭州三日游”规划器生成初始计划1. get_weather (杭州) → 2. search_attractions (杭州, spring) → 3. book_hotel (杭州, 3 nights) → 4. generate_itinerary_pdf若book_hotel返回“满房”规划器自动触发重规划3. search_hostels (杭州, 3 nights) → 4. generate_itinerary_pdf。关键技术规划器不是复杂PDDL而是基于LLM的轻量级Chain-of-Thought推理输入为“当前状态目标可用技能列表”输出为JSON格式的步骤序列状态跟踪每个技能执行后更新一个共享的execution_context对象包含已获取信息、已执行步骤、失败原因重规划触发器当技能返回特定error_code如RESOURCE_UNAVAILABLE或超时自动调用规划器。我们在某旅游Agent中落地此模式。规划器本身不处理业务逻辑只做“指挥官”所有执行仍由标准化技能完成。这保证了可解释性——你可以随时查看规划器生成的JSON计划理解它为何做出某个决策。6.3 阶段三生成式技能合成探索前沿特征Agent不仅能调用现有技能还能在运行时基于自然语言描述动态合成一个全新的、一次性的技能。示例用户说“把今天所有未读邮件的标题和发件人汇总成一个表格发给我”。Agent从未见过这个需求但它分析需求识别出需要list_unread_emails、extract_subject_sender、create_table_from_data、send_email_with_attachment四个原子技能动态生成一个Python函数将这四个技能按顺序编排并处理中间数据格式转换将此函数注册为临时技能执行后销毁。关键技术技能图谱Skill Graph将所有技能建模为图节点边表示“输出可作为输入”形成知识图谱程序合成Program Synthesis利用Code LLM根据用户需求和技能图谱