Agent工作流与Skills:工程化约束让智能体稳定交付

给 Agent 配工作流这件事,我琢磨了挺久。这段时间接触了不少做 Agent 的项目,大家都有同一个感受:单次调用模型很容易,但让 Agent 稳定完成一个多步骤任务,难得多。你可以给模型写一百条提示词,它还是会在某个环节突然跑偏——该调工具时不调,调错工具,或者做到一半把上下文忘干净。这个问题靠“换个更大的模型”解决不了,靠提示词堆砌也基本无效,真正能兜住底的方案,是给 Agent 配一套工程化的工作流。Skills 在其中扮演的角色,就是把 Agent 能做的事拆成一个个边界清晰、可验证、可独立测试的能力单元,再用工作流把零散能力串成一条能稳定交付的生产线。

这篇文章不讲大道理,就聊聊我在实际项目中怎么设计这套东西:为什么需要工作流、Skills 该怎么定义、调度逻辑怎么落地、以及我踩过的那些坑。如果你正在做 Agent 相关的项目,或者打算把一个“会对话的 Demo”升级成“能干活的系统”,可以参考这套思路少走点弯路。

1. 为什么 Agent 需要一套工程化工作流,而不是“When-Then”提示词

先聊一个最基础的问题:Agent 的本质是什么?拆开看,它就是“大模型 + 工具 + 循环”。大模型负责理解意图和生成决策,工具负责执行具体的动作(查数据库、发请求、写文件),循环负责让决策-执行-观察结果这个过程反复发生。听上去很简单,但一旦把这三样东西拼在一起,立刻会暴露出大量工程问题。

1.1 从“会聊天”到“能干活”之间的那道坎

对话式的 Demo 和真实的任务执行,差别非常大。你和一个模型聊天,它只需要生成一段合理的文字,正确与否的判定是模糊的。但当你让 Agent“根据订单状态表筛选出逾期订单,给对应客户生成提醒消息,并通过 Webhook 推送到通知服务”,每一步都有确定性要求:查询 SQL 必须语法正确、筛选逻辑必须准确、推送接口必须按格式传参。

这些要求不是提示词能完全约束住的。模型是概率系统,同样一句话在不同温度、不同上下文下的输出会有波动。提示词可以降低出错的概率,但没法把概率降到零。工程工作流解决的就是这个:把那些确定性强的环节从“模型自由发挥”中剥离出来,由代码接管;只把真正需要理解和判断的部分留给模型。

这么说可能有点抽象,打个比方。你把一个新人放进团队,如果只给他一个目标、不给流程,他大概率会产出各种奇怪的结果。正常的做法是给他一份 SOP:先做什么、怎么做、做完之后怎么检查、遇到异常找谁。Agent 也是这样,Skills 就是 SOP 里的操作卡片,工作流就是把这些卡片按顺序串起来的流程框架。

1.2 我见过最典型的 Agent 失效场景

说几个我在项目里实际遇到过的案例,都是很典型的翻车现场。

第一个是“做到一半失忆”。一个多步骤任务,Agent 在第三步需要用到第一步的计算结果。如果这个中间值没有被妥善保存,模型会因为上下文过长或者注意力漂移,直接引用一个错误的数据继续往下做。用户拿到最后的输出时,根本不知道中间哪一步已经错了。

第二个是“乱调工具”。给模型挂了四个工具,它总喜欢挑那个名字看起来最顺眼的,而不是语义上最匹配的。比如任务明明是“汇总本周销售数据”,模型却调用了“查询用户详情”的接口,参数还传错了一位。这个问题不是模型能力不行,而是工具选择的决策空间太大,缺少约束机制。

第三个是“异常后不会恢复”。外部 API 超时了,Skill 抛出一个异常。没有工作流兜底的 Agent 通常会怎么做?要么把报错信息原样丢给用户,要么自己编一个“系统暂时不可用”的解释,然后任务就终结了。稍微强一点的会盲目重试,在非幂等操作上重试两次,结果给用户发了重复通知。

这些场景有一个共同点:不是模型的“智商”不够,而是缺乏确定性的流程约束。工程工作流要做的,就是把这类问题通过结构设计挡住。

1.3 Skills 在工作流里的真实定位

明确了痛点之后,就能解释为什么不能只用提示词,还要引入 Skills 这个概念了。

Skills 本质上是对“能力”的封装:一个名字、一段自然语言描述、一套输入输出的格式定义、一份可执行的逻辑。它把 Agent 的某项能力从“模型的隐性行为”变成了“系统里的显式物件”。显式有什么好处?第一,可以被检索,工作流可以根据任务语义匹配到正确的 Skill;第二,可以被校验,输入输出都按照 JSON Schema 检查,脏数据进不来;第三,可以被测试,每一个 Skill 都是独立的单元,能单独跑测试用例,不用每次验证效果都跑一遍完整 Agent。

所以我的结论是:Skills 和工作流不是两个并列的概念,Skills 是“积木”,工作流是“图纸”。图纸定义了积木之间的顺序、条件分支、异常处理,而积木本身的质量决定了最终建筑的上限。

2. 先给 Agent 搭一个三层工作流骨架

讲清楚了为什么,下面说说具体怎么做。我在项目里落地工作流时,习惯先搭一个固定的骨架,再往骨架里面填充 Skills。骨架固定了,之后加新能力、换模型、调参数,都不会导致整体结构崩掉。

2.1 三层架构:意图解析层、技能执行层、反馈收敛层

整个工作流我拆成三个层次,层与层之间通过结构化的数据对象通信,不直接让模型输出跨层的东西。

第一层是意图解析层。这一层拿到用户原始输入后,做两件事:识别任务类型,生成执行计划。执行计划是一个结构化的数组,每个元素包含一个 Skill 名字、目标、依赖关系和参数来源。这个计划可以由模型生成,也可以由规则模板生成,或者两者混合。我的经验是,能用规则模板搞定的场景就少让模型参与,比如“查 X 数据然后发 Y 通知”这种固定套路,直接走模板,稳得多。

第二层是技能执行层。它负责按执行计划逐个调用 Skill,管理参数传递、超时、重试、并发。这一层是纯代码逻辑,不掺任何模型判断,核心目标是“按计划执行,不偏不倚”。

第三层是反馈收敛层。Skill 执行完会返回结果,这一层要判断结果是否满足预期,比如检查输出 Schema、校验业务规则、比对期望值。如果通过,就推进到下一个 Skill;如果失败,根据失败类型决定是重试、换 Skill 还是返回给人类。

这三层各司其职,互不越界。意图解析层只负责“定计划”,技能执行层只负责“执行”,反馈收敛层只负责“判定”。模型被限制在第一层和第三层的部分环节里,第二层完全由工程代码接管。

2.2 工作流状态怎么流转,才不失控

状态管理是工程化工作流跟“调模型玩”最明显的分水岭。我建议给每个任务实例维护一个显式的状态机,而不是靠模型自己“记住”现在进行到哪了。

状态集合大致是这样的:PENDING(排队中)、PLANNING(生成计划)、WAITING_SKILL(等待技能执行)、VALIDATING(校验结果)、RETRYING(准备重试)、DONE(完成)、FAILED(失败)、CANCELLED(取消)。状态机的流转规则在代码里写死,比如只有 VALIDATING 判定失败且尚有重试次数时才进入 RETRYING,否则直接 FAILED。任何状态都能被外部信号中断并转入 CANCELLED,这是很多系统会忽略的——用户等不及了想取消任务,结果 Agent 还在自顾自地跑循环。

用状态机的理由很简单:状态是可观测的,哪个环节出问题一眼就能定位;状态是可恢复的,进程挂掉之后可以根据持久化的状态断点续跑;状态是可约束的,非法流转根本走不通。相比之下,如果让模型在对话记录里隐式夹带状态,那排查问题就像在一堆散文里找错别字。

2.3 为什么要做“技能路由”,而不是让模型直接挑工具

市面上很多 Agent 框架的做法是给模型一堆工具函数,让它自己选。听起来很灵活,实际用起来很让人头疼。模型选工具的准确率跟工具数量、描述质量强相关,工具一多,描述稍微含糊,就开始乱点鸳鸯谱。

我建议在模型选择之前,加一层“技能路由”。这层可以是规则逻辑(比如任务里包含关键词“订单”就匹配订单查询 Skill)、可以是一个小型分类模型,也可以是让大模型在“候选集”里做选择——关键点是先通过确定性逻辑把候选范围从十个缩小到两三个,再做决策。

这背后的思路是“决策空间收缩”。模型的优势在于语义理解,劣势在于精确选择。你让它从一千个选项里挑正确的,和从三个选项里挑正确的,准确率天差地别。技能路由就是干这件事的,先用便宜的确定性手段缩小范围,再把不确定的判断交给模型,成本低、效果好。

3. Skills 的工程化定义,以及和普通函数调用的区别

很多人会把 Skills 理解成“给 Agent 写几个函数”,这个理解不算错,但差了一点。Skills 和普通函数的关键差异在于,它是一种带有自描述能力、可被工作流动态发现和校验的“元能力”。换句话说,函数是“别人调你,你要干活”;Skill 是“别人能找到你,知道你能干什么活,确定传什么参数给你,你才动手”。

3.1 Skills 的标准组成:Manifest、执行体、验证器

我在实践中把每个 Skill 拆成三部分:Manifest(清单)、执行体(Implementation)、验证器(Validator)。

Manifest 是这个 Skill 的“身份证”。它包含 Skill 的名字、一句话功能描述、输入参数的 JSON Schema、输出数据的 JSON Schema、鉴权要求、还有运行在什么环境里。Manifest 的作用是给路由层和工作流调度层看的:要不要选这个 Skill、参数该拼成什么样子、返回值应该长什么样,全部由 Manifest 说了算。

执行体是真正干活的代码。它可以是内部函数、外部 API 封装、命令行脚本,甚至是一个子 Agent 的入口。关键点在于执行体不负责“思考”为什么执行,工作流调度器已经给出了原因;执行体只需要按参数干活,成功返回结构化数据,失败抛异常。

验证器往往被忽略,但它的价值非常高。验证器分两层:一层是格式验证,检查输出是否符合 Schema 定义;另一层是业务验证,比如查询结果是否为空且不允许为空、数值字段是否超出合理范围、状态字段是否属于预期枚举。两层验证都通过,工作流才认为这个 Skill 执行成功。

提示:执行体尽量不要自己吞掉异常然后返回一段“成功”的假数据。宁可让异常上抛,让反馈收敛层做决策,也不要让脏数据往流程下游流。

3.2 一个完整的 Skill 定义长什么样

我直接给一个例子。假设我们要给一个数据运营场景配工作流,其中有一个 Skill 是“查询订单汇总”。定义如下:

{ "name": "get_order_summary", "description": "根据日期范围查询订单汇总数据,返回订单数、销售额、客单价。仅用于汇总统计,不返回明细。", "input_schema": { "type": "object", "properties": { "start_date": { "type": "string", "format": "date" }, "end_date": { "type": "string", "format": "date" }, "channel": { "type": "string", "enum": ["all", "app", "web", "mini_program"] } }, "required": ["start_date", "end_date"] }, "output_schema": { "type": "object", "properties": { "order_count": { "type": "integer", "minimum": 0 }, "total_amount": { "type": "number", "minimum": 0 }, "avg_order_amount": { "type": "number", "minimum": 0 } }, "required": ["order_count", "total_amount", "avg_order_amount"] }, "validation_rules": { "business": [ "avg_order_amount 必须等于 total_amount / order_count,误差不超过 0.01", "如果 order_count === 0,则 avg_order_amount 必须为 0" ] }, "auth": { "scope": "read_only" }, "runtime": { "timeout_seconds": 15, "retry_policy": "safe_retry" } }

我解释一下这里的设计意图。description写得非常具体,直接说“仅用于汇总统计,不返回明细”,这能有效防止模型拿这个 Skill 去查订单明细(那是另一个 Skill 的职责)。input_schema里限制了渠道的可选枚举值,避免模型编一个不存在的渠道名称。output_schema不仅声明了数据类型,还加了minimum约束。validation_rules更进一步,把业务规则直接写进去,工作流执行完这个 Skill 后会立即判断销售金额和订单数是否自洽,不自洽就直接标记失败,而不是把可疑数据发给用户。

3.3 上下文边界与数据传递的工程约束

Skills 很多、任务很复杂的时候,最怕的就是数据流失控。A Skill 产生的结果被 B Skill 修改后,又反过来污染了 A 的作用域;或者 B Skill 误读了 A Skill 的中间变量,导致下一步决策错误。这个问题的根因是“共享状态”太多。

我的做法是:工作流层面维护一个上下文对象,上下文里只保存“需要跨 Skill 传递的数据”。Skill 自身产生的局部数据禁止写入全局上下文,除非显式声明为“输出变量”。每个 Skill 执行前,调度器把它的输入参数从上下文里拷贝出来;执行后,只把输出 Schema 里声明过的字段写回上下文。其他一切内部实现细节都不流过上下文。

简单说,Skill 之间不直接对话,数据交换全部经过调度器的“关卡”。这个约束让工作流的执行路径变得非常清晰,也方便之后做审计和重放——你只要记录每次调度时的上下文快照,就能完整还原整个任务的执行过程。

4. 实操:把一套工作流真正跑起来

前面讲的是设计思路,很多人看完会觉得有道理,但动手又不知道从哪里开始。这一章就按实操顺序走一遍,你会发现落地其实没那么玄乎,核心就是先把状态机打通,再把 Skills 挂进去。

4.1 先规划节点图,再写代码

我建议动手敲代码之前,先用表格把任务流程写出来。举例来说,一个“每日销售播报”任务可以拆成这样:

节点编号节点名称输入来源输出去向失败策略
1解析播报范围(日期、渠道)用户输入节点2直接失败并询问用户
2get_order_summary 查汇总节点1节点3安全重试最多 2 次
3检查汇总数据是否异常节点2节点4标记失败并告警
4生成中文播报文案节点2、节点3节点5重新规划文案生成方式,最多换 1 次
5推送到群机器人节点4结束非幂等操作,禁止自动重试,转人工

这个表格就是工作流的“图纸”。你先别急着想“要不要引入一个复杂框架”,拿一张纸列清楚每个节点的输入输出和出错之后怎么办,比选什么框架都重要。有了这张表,后面写代码就是把每个节点翻译成函数而已。

4.2 调度器核心逻辑:一个顺手的循环结构

工作流调度器不需要花哨,一个带状态记录的单线程循环就完全够用,等你真正遇到性能瓶颈时再引入并发模型也不迟。我给你一个参考的实现思路,用伪 Python 描述:

def run_workflow(task): ctx = TaskContext(task_id=generate_id(), status="PENDING") try: # 阶段一:意图解析,产出执行计划 plan = planning_service.create_plan(task.input) ctx.status = "PLANNING" for step in plan: # 为当前步骤匹配对应的 Skill skill = skill_registry.resolve(step.skill_name) if skill is None: raise SkillResolveError(f"skill not found: {step.skill_name}") ctx.status = "WAITING_SKILL" # 从上下文组装参数,执行前会做一次 schema 校验 step_input = ctx.assemble_input(step) validate_input(skill.manifest, step_input) # 执行,带超时控制 result = execute_with_timeout(skill, step_input, timeout=skill.runtime.timeout_seconds) # 两层验证:格式 + 业务 ctx.status = "VALIDATING" validate_output(skill.manifest, result) validate_business_rules(skill.manifest, result) # 通过后写回上下文,未声明的字段一律丢弃 ctx.commit_output(step, result) ctx.status = "DONE" return ctx.final_output() except RetryableError as e: ctx.status = "RETRYING" # 按配置决定是否重试 except FatalError as e: ctx.status = "FAILED" logging.error(f"workflow failed: {e}") raise

就这个结构,已经能跑通 80% 的场景。核心有两点:第一,每步执行之前和之后都有校验,不让脏数据进,也不让脏数据出;第二,整段循环简单地推进,出错就抛,由上一层决定怎么处理。这里的execute_with_timeout我建议自己封装一下,很多语言的标准库都支持对协程或线程加超时,不要依赖 Skill 内部实现自己的超时,那不可控。

4.3 关键参数的经验值:超时、重试、并发

写代码的时候,有几个参数需要你根据场景定,我给出我在生产环境里用过的一组经验和计算逻辑,你可以当作起点调试。

第一个是单次 Skill 执行的超时。这个值的设定取决于后端服务的 P95 响应时间。比如你调一个内部数据接口,线上统计 95% 的请求在 8 秒内返回,那超时建议设在 15 秒,留出一倍的余量。设得太短,正常偏慢的请求会被误杀;设得太长,一个大卡住的 Skill 会把整个工作流拖死。内部查询类 Skill 我给 15 秒,外部第三方 API 我给 30 秒,涉及文件处理的给 60 秒。

第二个是重试次数和重试策略。这里有一条铁律:非幂等操作禁止自动重试。什么是非幂等?比如“创建订单”“发送通知”“扣减库存”,执行两次就会产生两次副作用。幂等操作比如“查询数据”“读取文件”,可以放心重试。对于允许重试的场景,我的标准是内部接口 2 次、外部接口 1 次,采用指数退避(第一次等 2 秒,第二次等 4 秒),并加抖动(随机增加 0-1 秒),防止多个任务同时重试时把下游打挂。

第三个是并发度。我的经验是:初始并发数不要超过下游服务限流的 80%。假设某个 API 允许每秒最多 5 个请求,工作流客户端并发就设在 4,同时每个工作流实例内部的 Skill 调用本身就是串行的。并发放到工作流实例之间,而不是单个实例内部,这样更容易控制节奏。

提示:在生产环境上线之前,建议花半天时间给每个 Skill 做一次“故障演练”。把下游 API 直接断掉,观察工作流的失败路径是否符合预期;再把返回数据改成畸形格式,看验证器能不能拦住。这一步没人替你做,但做一次比写十个测试用例都有用。

5. 常见问题与排查技巧实录

工作流写出来只是第一步,真正考验人的是排错阶段。我把自己遇到过的典型问题整理了一下,按“现象-原因-排查路径”的格式给你做了一张速查表,方便你以后当手册用。

5.1 典型故障速查表

现象可能原因排查路径
任务一直在“等待技能”状态卡住不动Skill 内部死循环或外部调用未设置超时检查 Skill 日志,看是否卡在网络 IO;确认execute_with_timeout是否真的生效
Agent 频繁选错 SkillManifest 里的 description 写得太含糊,路由的候选集没有收缩打开路由日志,观察候选 Skill 列表;逐条检查 description 是否具备区分度
输出结果通过格式校验但业务明显不对验证器只校验了类型,没有校验业务规则补充业务校验规则,比如数值范围、统计自洽性、引用完整性
任务失败后反复重试同一操作,造成重复扣款重试策略没有区分幂等性给非幂等 Skill 的 Manifest 标记retry_policy: "no_auto_retry",失败直接转人工
上下文数据被后续 Skill 篡改,导致最终结果错误上下文对象被多处直接修改,缺少写权限控制通过commit_output统一入口写回,Skill 局部变量禁止直接写入全局上下文
多个任务并发时,下游 API 偶尔返回 429并发数没按限流预留余量检查限流值,把工作流并发降到限流的 80% 以下,并开启限流熔断

这个速查表里的问题我基本都在真实项目里撞到过,没有一个是模型“变笨”导致的,全部是工程细节没做到位。所以排查问题的时候,先别怀疑模型,先从工作流的日志和状态流转找原因。

5.2 定位工作流卡死的三条检查路径

一个任务执行到某个节点就没了下文,这是最常被问到的排查场景。我一般按下面三条路径依次排查,基本能覆盖绝大多数原因。

路径一是查“状态和时间戳”。工作流每一步关键节点的状态变更都应该打审计日志,包含节点名、状态、时间戳、上下文快照的引用 ID。拿出任务 ID 一查,就能看到它到底卡在哪个节点。如果最后一条日志是“已调用 Skill 但无响应”,那问题大概率出在 Skill 的内部执行;如果最后一条是“计划已生成但待执行”,那问题出在调度器的循环上。

路径二是查“工具追踪”。如果你调用的 Skill 有外部依赖,比如 HTTP 接口,那么在日志里要记录请求的响应时间、状态码和返回体摘要。这一步能区分是“外部接口慢”还是“解析响应超时”。我之前排查过一个诡异的问题,外部网关返回 200,但响应体持续变大导致 JSON 解析耗时巨长,逻辑上像卡死了,查半天才发现是网络传输层的问题。

路径三是查“模型输出还原”。凡是模型参与决策的地方,比如生成执行计划、选择 Skill、修改参数,都必须把原始输出完整落盘。排查时把模型输出重新喂给解析器,看是不是解析器漏掉了某个返回字段。我遇到过一种情况:模型输出了一个不在白名单里的 Skill 名,解析器没有报错反而静默忽略,导致计划里少了一步。这类 bug 只有回看模型原始输出才能定位。

5.3 几个我踩过的坑,希望你别再踩一遍

第一个坑是“并发写共享状态”。早期版本我把所有 Skill 结果都往一个字典里塞,多个任务并发跑起来之后,偶尔会出现 A 任务读到了 B 任务的数据。这个 bug 相当隐蔽,排查了一天才找到根因。后来全部改成任务级上下文,一个任务一个实例,彻底根除。这也印证了前面说的:上下文隔离不是一个可选的优化项,而是必须从一开始就做对的设计。

第二个坑是“验证器只写死了类型校验”。有一个 Skill 返回订单数,Schema 里只要求“整数且大于等于 0”,但某个异常场景返回了 0,而业务上当天必须至少有几十单。格式校验通过,业务却不合理,最终工作流生成了“暂无销量”的错误播报。从那以后,我所有 Skill 的 validation_rules 里都强制要求写至少一条业务规则,能算自洽性的就算自洽性,不能算的就写范围约束。

第三个坑是“把不该自动重试的操作设成可重试”。有一个发送通知的 Skill,因为是外部接口偶尔超时,我给它加了自动重试一次。结果就是,一批客户收到了重复的通知。原因很简单,外部接口实际上创建成功了,只是响应超时,自动重试就发生两次调用。这个教训很贵,之后所有有副作用的操作,一律禁止自动重试,宁可多花人力去处理,也不要让系统自己制造更大的脏数据。

6. 工具选型与后续扩展方向

最后聊一下工具选型和这套体系将来还能长成什么样。很多读者肯定会纠结:要不要直接用现成的开源框架?还是自己写一套?我的建议是先想清楚你的主要诉求是什么。

6.1 从零搭建和用现成框架怎么选

可以参考这个简单的对照表:

考量维度自研轻量工作流使用现成框架
可控性高,每个环节都能改中,受框架约定限制
学习成本前期较高,需要自己设计状态机较低,按文档填配置即可
团队调试成本低,日志和代码完全透明不确定,需要理解框架内部行为
社区生态无有插件、扩展、示例可参考
适合场景业务逻辑复杂、需要深度定制场景通用、希望快速上线

我个人的经验是,如果你的工作流形态比较固定(比如统一的“规划-执行-验证”三步模型),自研一个轻量状态机完全够用,代码量其实不大,还能完全掌控日志和监控细节。如果你需要处理大量不同类型的任务,或者团队缺少工程资源,用现成框架来承载基础能力、自己只做业务扩展,会是更务实的选择。

不管选哪条路,前面讲的核心设计理念都是通用的:明确的状态流转、严格定义的 Skill 边界、两层输入输出校验、明确的重试和超时策略。框架可以变,这些工程底线不能丢。

6.2 后续值得加上的工程能力

这套工作流跑通之后,有几个方向我觉得很值得投入。

第一个是人工审批节点的引入。不是所有操作都适合让 Agent 自主完成。对于“发送大批量消息”“生成对外报表”这类动作,可以在工作流里加一个HUMAN_APPROVAL的中间状态,Agent 把结果草稿推给负责人,确认之后才继续执行。这很好地平衡了自动化效率和风险控制。

第二个是 Skill 的版本管理。Skill 会迭代,今天写的校验规则过一段时间可能就不适用了。每次修改 Skill 都建议打上语义化版本号,工作流的节点记录自己用的是哪个版本的 Skill。将来任务回溯审计时,你能知道当前这个结果到底是用哪一版逻辑算出来的,而不是面对一个“当前状态”摸不着头脑。

第三个是回归测试集的建设。挑一批典型的任务场景,每个场景绑定固定的输入和期望结果,组成 golden set。每次改了 Skills 或工作流逻辑,先跑一遍回归集,确保没有把之前正常的功能改坏。这比靠人工点点点有效得多,也是团队协作时保证稳定性的关键招。

第四个是给工作流增加可观测性面板。不用做得很花哨,把每个任务的状态分布、Skill 调用量、平均耗时、失败原因 TOP N 列出来就够了。这些数据能告诉你:哪个 Skill 是瓶颈、哪个环节经常失败、模型决策的准确率有没有下降。数据驱动优化,而不是靠感觉调参。

我在实际项目里最深的体会是,Agent 工程化这件事,难点不在于“把模型调聪明”,而在于“把不确定性锁进笼子里”。工作流负责给全过程搭架子,Skills 负责让每个能力单元足够小、足够清晰、足够可测。系统里的确定性越高,模型需要做的自由发挥就越少,整体交付的稳定性自然就上来了。

如果你正准备把一个 Agent 项目从 Demo 推向生产,我的建议特别简单:先把你的任务拆成一张能写清楚的流程表,再定义一个最小可用的 Skill 格式,其他花活都可以放后面。等工作流骨架跑顺了,其余的扩展项再逐个往上面挂就行。这套路我试过,稳。

相关新闻

拖车角度感知算法联调:从传感器配置到多传感器融合的仿真验证

拖车角度感知算法联调:从传感器配置到多传感器融合的仿真验证

拖车角度感知这活儿,一句话说难不难,就是把拖车相对牵引车转了多少度量出来。可真要做倒车辅助、自动倒车这类功能,这个角度就是命根子。最近我在aiSim上做了一轮半挂车拖车联调,核心任务就是把传感器视角下的拖车角度感知算法完整…

2026/10/20 5:29:08 阅读更多 →
OpenAI API平替指南:三大本地化方案横评与24小时驻场实战

OpenAI API平替指南:三大本地化方案横评与24小时驻场实战

1. 项目概述:一场面向开发者的“自主权回归”实践你有没有算过一笔账?一个中等活跃度的团队,每月在 OpenAI API 上的支出轻松突破百美元——这还只是基础调用,若叠加图像生成、长上下文推理、多轮对话缓存、私有知识库增强等进阶需…

2026/10/20 5:29:08 阅读更多 →
从技术路线到职业选择:具身智能从业者的真实对话

从技术路线到职业选择:具身智能从业者的真实对话

上个月我攒了一个线上圆桌,人不多,但阵容很有意思:一位在上海某高校带机器人实验室的老师,两位刚在海外读完博士回来的年轻朋友,再加上我一个常年在一线做机器人软件的老兵。我起初只是想找几个人聊聊具身智能最近到底…

2026/10/20 5:28:08 阅读更多 →

最新新闻

从单体到弹性扩展:高并发架构改造的完整实战复盘

从单体到弹性扩展:高并发架构改造的完整实战复盘

1. 项目背景与架构需求拆解1.1 最初的系统,和它一步步暴露出的问题先说下背景。这个代号为"arch-system"的架构改造项目,源于团队负责的一条核心业务链路。最初的系统是典型的三层单体:一个应用服务承载所有接口,MySQL …

2026/10/20 6:03:23 阅读更多 →
PPT-Master:用PowerPoint构建业务操作系统的方法论

PPT-Master:用PowerPoint构建业务操作系统的方法论

1. “PPT-Master”不是软件名,而是一类人的生存状态最近在几个技术协作群和设计交流社区里,“PPT-Master”这个词高频出现,但没人把它当产品名说——它更像一句带点自嘲又透着狠劲的行业暗号。我第一次听到是在某次跨部门复盘会上&#xff0c…

2026/10/20 6:03:23 阅读更多 →
图灵奖60年:人机环境系统智能的演进与落地

图灵奖60年:人机环境系统智能的演进与落地

六十年前,那个以一位计算机先驱命名的奖项第一次颁出时,大概没有人想到,它会成为一部无声的“智能观变迁史”。这六十年间,获奖成果背后的工作其实都在回答同一个问题:机器到底怎样才算有智能?答案从“会算…

2026/10/20 6:03:23 阅读更多 →
浙江高考VB排序系列:冒泡与选择排序代码实现及应试技巧

浙江高考VB排序系列:冒泡与选择排序代码实现及应试技巧

1. 从一道排序题说起:为什么VB排序值得单独拎出来讲每年到了技术科目备考的冲刺阶段,总有一批同学在排序算法这块反复栽跟头。选择题里问“冒泡排序第三轮结束后序列长什么样”,填空题里给一段残缺代码让你补全循环边界,上机操作题…

2026/10/20 6:03:23 阅读更多 →
图灵奖六十年:从机器能否思考到人机环境系统智能的跃迁

图灵奖六十年:从机器能否思考到人机环境系统智能的跃迁

图灵奖整整六十年了。作为计算机科学领域最负盛名的荣誉,它这些年一直被当作衡量学术巅峰的标尺。可如果你把六十年来历届获奖者所代表的方向串成一条时间线,会发现一个远比"学术成就"更有意思的东西正在浮现:整个领域对"智能…

2026/10/20 6:03:23 阅读更多 →
主动学习新思路:损失预测模块如何精准筛选高价值样本

主动学习新思路:损失预测模块如何精准筛选高价值样本

1. 为什么主动学习要换一种采样思路做深度学习项目,尤其在数据标注预算有限的时候,大家最先想到的办法多半是“先随便标一部分,训练一版模型,再用模型挑一些‘难样本’送给标注员”。这套逻辑本身没问题,难就难在“难样…

2026/10/20 6:02:23 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →