从 1211 次测试全绿说起:构建高可靠自动化工作流(Agentic Workflow)的工程实践

0 阅读4分钟
> **前言**:大多数开发者搭建的 Agent 只要跑出 Demo 就算完工。但在商业化落地时,环境的不确定性、网络超时、状态爆炸,会把你脆弱的循环打得粉碎。本文分享一下,如何用传统后端架构思维,构建一个容错率极高、带“自我反省”机制的自动化工作流系统。

## 一、 问题背景:失控的自动化

最近在重构一个自动化安全测试系统(PCVL-Agent)。它的核心任务是从输入一个 URL 开始,爬取、检测、验证、直到输出结果。

最初的设计是典型的 `while` 循环 + `try-catch`。但随着任务复杂度的上升,灾难出现了:
1. **状态爆炸**:多步请求中,Cookie 突然过期,导致后续的验证全部误报。
2. **死循环**:遇到返回 403 的 WAF,系统判定失败,重新生成 Payload,再次返回 403,无限重试。
3. **长超时**:同步执行整个流程,导致外部网关经常报 504 Timeout。

为了解决这些问题,我引入了六个核心模块,最终实现了全量 1211 项检查 100% 通过。

## 二、 核心架构设计

### 1. 目标分解(Planner):避免一锅粥
不要试图用一个函数搞定所有事情。系统启动时,首先将目标拆分为独立的子任务(Task DAG)。
身份切换(匿名/管理员)、预算限制、流量特征,全部在这一层被切分并存入队列。

```python
# 伪代码
class TaskNode:
    def __init__(self, url, auth_level, priority):
        self.url = url
        self.auth_level = auth_level
        self.priority = priority # 由 EIG 期望信息增益决定

2. 在线适应(Policy):UCB 算法在任务调度中的应用

在探测过程中,有无数个端点需要测试。先测哪个?我们引入了强化学习中的 UCB(置信区间上界) 算法。
系统会根据历史的投入产出比,动态调整任务的优先级。高价值的任务前置,死胡同任务直接降权。

3. 经验回写(ExpBook):给系统安装长时记忆

为了避免重复劳动,系统建立了 ExpBook。
如果同一个接口,第一次测试 SQLi 失败了。第二次再遇到它,ExpBook 会给这个动作乘上 0.5 的权重惩罚。这使得系统越跑越快,消耗的请求数直降 30%。

三、 智能化的一小步:元认知(Metacog)

这是该工作流中最像“人类”的一个模块。
我们写了一个 metacog.py,它不是用来做检测的,而是用来 “审视系统当前状态” 的。

如果系统发现:

  • 连续发了 10 个请求,状态码全是 502。
  • 所有生成的变种 Payload 都被 WAF 拦截。
    系统会立刻触发元认知判断:
  1. 判定目标环境异常(触发环境怀疑)。
  2. 判定自身策略失效(封顶声明)。
  3. 将当前状态打包存入 Plan 轨迹(Trajectory),切换完全不同的攻击策略(比如从注入改为逻辑漏洞测试)。

这种能力极大地避免了“一条路走到黑”。

四、 自动化工作流的“断路器”设计

做工作流一定要有熔断机制:

  1. Scope 熔断:越权测试绝对是红线。所以在发包前,必须强制校验 URL 是否在 white_list.txt 里。不在就抛出异常。
  2. 时间硬上限:无论当前链路多么诱人,单个 Task 执行超过 300 秒,强制 Kill 并释放资源。
  3. 沙箱隔离:任何由外部输入动态生成的可执行代码(如 Payload 脚本),必须在受限的 Docker 容器中执行,防止反序列化攻击打穿宿主。

五、 总结:Agent 的尽头是传统的软件工程

现在大家都在卷大模型。但当你真正要在生产环境跑一个 24 小时不间断的 Agent 时,你会发现:

  • 怎么防止内存泄漏?
  • 怎么设计断点续传?
  • 怎么把长任务拆成异步队列(Celery/RabbitMQ)?
    这些传统的软件工程问题,才是决定 Agent 能不能活下来的关键。

与其苦思冥想怎么写出更好的 Prompt,不如静下心来,把图状态机、状态机回溯、异常处理这几块代码写得像艺术品一样严谨。这才是 AI 落地在垂直领域的真正护城河。

欢迎交流你在构建 Agent 时踩过的坑。