# Kestra实战:Agentic Automation如何治理自治AI工作流
传统自动化很脆弱。一个订单处理脚本,假如支付回调延迟5秒未到,就会判定失败。客服工单系统只能按关键词分派,遇到表达模糊的请求就陷入死循环。这些场景的共同点在于:真实世界的不确定性超出了预定义规则能覆盖的边界。
Agentic automation尝试解决这个问题。由LLM驱动的agent能够观察环境、自行规划下一步、调用工具并修正错误。但agent的自由度同时带来新的风险:可能调用危险工具、生成未经验证的回复、留下不可追溯的执行路径。如果把纯净的agent直接放进生产环境,没有人敢对结果负责。
Kestra这样的编排层因此变得关键。它不取代agent,而是给agent加上“围栏”:限定工具集、插入人工审批、记录全量审计日志。本文基于Kestra 0.20.0与ai-plugin 0.5.0,结合一个带审批的客服流程,说明Agentic Automation如何落地。
## 规则引擎的边界与Agent的补位
传统自动化是“IF-THEN”的线性展开,规则明确,结果可预期。Agentic自动化是“目标-计划-行动-观察”的循环,agent根据中间结果动态调整。一个直观的对比:
| 维度 | 传统自动化 | Agentic自动化 |
| --- | --- | --- |
| 核心逻辑 | 预定义规则/脚本 | LLM推理与规划 |
| 适应性 | 低,僵硬 | 高,动态目标导向 |
| 决策方式 | 规则显式 | 上下文感知自治 |
| 目标 | 执行特定任务 | 达成高层级结果 |
| 错误处理 | 程序化异常 | 自适应解决问题 |
| 适用场景 | 可预测任务 | 不可预测场景 |
| 人的角色 | 定义规则、监控 | 监督、审批、修正目标 |
传统工作流中,人的角色是“编程者”;Agent工作流中,人的角色是“审批者”。这个转变意味着系统必须支持人在环路的暂停、恢复与干预。否则,一个自主错误可能在无人察觉时影响数千个终端用户。
编排层需要提供四项核心能力:
1. **受限工具集**。agent能接触哪些工具,由编排层决定。客服agent不能直接调用退款API。
2. **人工审批**。高风险操作执行前,流程必须暂停,等待人类确认。
3. **审计追踪**。每一次LLM决策、每一次工具调用、每一次审批结果都要可查。
4. **可重放**。工作流实例能按相同输入重放,便于排障与优化。
Kestra的设计与这四点高度吻合。它是一个开源工作流引擎,支持Webhook、定时、队列触发;`Pause`节点可以把流程挂起等待人工输入;`If`节点依据审批结果决定分支;所有flow均保存revision,每个任务实例都有完整日志。
还需要区分两个层次:LangChain、AutoGen这类框架解决的是“agent如何思考”,Kestra解决的是“工作流如何运行”。前者是大脑,后者是身体。生产系统不能容忍大脑直接控制所有肢体,你需要一条可控制、可观测的反射弧。Kestra就是这条反射弧。
## 实战:带人工审批的客服Agent
下面这段YAML定义了一个完整的Agentic流程。它接收Webhook传入的客服请求,让`gpt-5-mini`生成回复草稿,暂停等待审批,审批通过则发送Slack通知,拒绝则记录原因。
```yaml
id: agentic-customer-support-with-approval
namespace: company.team.ai
revision: 2026.09.29
triggers:
- id: support-request-webhook
type: io.kestra.plugin.core.trigger.Webhook
key: replace-with-a-long-random-key
tasks:
- id: log-request
type: io.kestra.plugin.core.log.Log
message: "Received support request: {{ trigger.body | toJson }}"
- id: draft-response
type: io.kestra.plugin.ai.agent.AIAgent
provider:
type: io.kestra.plugin.ai.provider.OpenAI
apiKey: "{{ secret('OPENAI_API_KEY') }}"
modelName: gpt-5-mini
systemMessage: |
You are a customer support agent. Draft a short, professional reply.
Never promise a refund; say the request will be reviewed instead.
prompt: "Customer request: {{ trigger.body | toJson }}"
- id: human-review
type: io.kestra.plugin.core.flow.Pause
description: Review the drafted reply before it is sent.
onResume:
- id: approved
type: BOOL
defaults: false
- id: comment
type: STRING
defaults: ""
- id: send-if-approved
type: io.kestra.plugin.core.flow.If
condition: "{{ outputs['human-review'].onResume.approved }}"
then:
- id: post-approved-reply
type: io.kestra.plugin.slack.notifications.SlackIncomingWebhook
url: "{{ secret('SLACK_WEBHOOK_URL') }}"
payload: |
{
"text": {{ ("Approved reply: " ~ outputs['draft-response'].textOutput) | toJson }}
}
else:
- id: log-rejection
type: io.kestra.plugin.core.log.Log
message: "Draft rejected: {{ outputs['human-review'].onResume.comment }}"
```
这个流程可以拆成三层来看。
触发层负责入口与审计。Webhook触发器使用随机key保护端点,避免外部任意调用。`log-request`把原始请求写入日志,作为全链路审计的第一条记录。后续所有任务都能通过`trigger.body`回溯原始输入,这一步是生产环境的基本要求。
生成层承担LLM推理。`AIAgent`节点通过OpenAI provider调用`gpt-5-mini`。注意`systemMessage`里写了两条硬性约束:“Never promise a refund; say the request will be reviewed instead”。这是把组织策略注入系统提示词,而不是依赖模型自觉。实际生产中,你应该把退款、优惠、SLA承诺等敏感操作全部写成这种负面清单。生成结果存储在`outputs['draft-response'].textOutput`中,供后续节点引用。
审批层实现人在环路。`Pause`节点将流程挂起,Kestra UI会向审批人展示草稿,并要求勾选`approved`与填写`comment`。审批结果通过`onResume`结构注入工作流。随后`If`节点读取`outputs['human-review'].onResume.approved`,为true则发送Slack通知,为false则记录拒绝原因。整个流程中,agent从未获得退款、发货或直接回复客户的权限——这就是“受限工具集”的落地方式。
部署这个flow需要配置两个密钥:`OPENAI_API_KEY`与`SLACK_WEBHOOK_URL`。Kestra的secret机制避免明文密钥出现在flow定义中,比把密钥写进环境变量多一层安全控制。如果你希望超时未审批时自动降级处理,可以给`Pause`节点增加`timeout`策略,这留给读者自行扩展。
## 可观测性与成本控制
有人会担心:引入`Pause`后,流程吞吐会不会下降?真实影响取决于业务。客服场景中,人工审批是必须的,延迟几分钟远好于错发一条承诺退款的消息。真正需要关注的是agent调用本身。Kestra对每个任务实例都记录耗时、输入、输出和异常堆栈。你可以据此统计`gpt-5-mini`的响应时间与失败率,也可以按namespace汇总每个业务线的AI调用成本。这比单纯用一个LangChain脚本跑完所有逻辑要透明得多,无需额外搭建Prometheus数据管道。
Kestra还支持从失败任务重放实例。如果`post-approved-reply`因为Slack Webhook临时抖动失败,可以直接重放该实例,而不必重新调用LLM。LLM调用是不可控成本,重放时跳过已经成功的节点,能为团队节省一笔不小的开销。