研发团队里有一类任务,价值高、频次高,却长期在"人肉接力":合并请求进来,先跑安全扫描,扫出漏洞要修复,修完要回归,回归通过再评审,评审结束才合入。每一步都有工具,但把它们串起来的,往往是工程师手动操作,或者是散落在各处的脚本加 Webhook 拼凑。任何一个环节断了,整条链就断了。
Agent 智能体解决的是"单步自动化"------比如一个智能体能自动创建 MR、能自动审查代码、能自动诊断流水线失败。但端到端的多步流程 ,光靠单个 Agent 不够,还需要一层"编排"能力。这正是极狐GitLab Duo 的**自定义 Flow(Custom Flow)**要解决的问题。
本文基于官方文档,拆解 Custom Flow 的核心机制、YAML 编排语法、触发器与服务账号模型,以及落地时最容易踩的坑。
一、先厘清两个概念:Agent 与 Flow 的区别
在 Duo Agent Platform 里,二者分工明确:
- Agent:一个完成特定任务的智能体。比如内置的 Planner Agent 负责规划与拆解工作,Security Analyst Agent 负责安全漏洞的 triage 与修复,也可以自定义一个"只负责创建 MR"的智能体。
- Flow :一个组合多个 Agent、按编排逻辑串起来的 AI 工作流,用来自动化复杂的多步任务。
打个比方:Agent 是流水线上的"单台工位",Flow 是"整条产线"------它决定先走哪个工位、数据如何在工位之间传递、什么时候结束。
关键认知:自定义 Flow 并不能直接调用某个已经建好的自定义 Agent。官方文档明确说明,Flow 会根据自身的 YAML 配置"创建并使用自己的 Agent"。所以你在 Flow 里写的是"我要一个怎样的智能体 + 它们之间怎么流转",而不是"调用我上次建的那个 Agent"。
二、从零创建一个 Flow
入口在项目的左侧边栏 AI > Flows。创建流程分四步:
- 基本信息 :填
Display name与Description。 - 可见性与访问 :选
Private(仅管理项目可见)、Restricted(同一顶级群组内可见可用)或Public(实例内任何人可见)。 - 配置 :选择
Flow类型,在编辑器里写 YAML 编排配置。 - 创建:Flow 会出现在 AI Catalog 中。
创建之后还需启用 (Enable)并绑定触发器(Triggers) ,才能被真正触发。目前支持的触发事件包括:在 Issue / MR / 讨论中 @提及 Flow 服务账号、指派/指派为审查人 、以及流水线事件。
启用后,系统会为该 Flow 自动创建一个服务账号,命名规则是 ai-<flow>-<group>。比如在 GitLab Duo 群组里启用名为 Security scanner 的 Flow,服务账号就是 ai-security-scanner-gitlab-duo。之后只要在 Issue 或 MR 里 @ 这个账号,Flow 就会自动跑起来,跑完要么产出"可直接合入的改动",要么留一条行内评论。
三、YAML 编排:一套声明式的"智能体流水线"
Custom Flow 采用 flow registry v1 规范。一个最精简的示例长这样:
yaml
version: v1
environment: ambient
coding_environment: none
components:
- name: "api_agent"
type: AgentComponent
prompt_id: "my_api_prompt"
inputs:
- "context:goal"
routers:
- from: "api_agent"
to: end
flow:
entry_point: "api_agent"
几个关键字段的含义:
version: v1:flow registry 版本。environment: ambient:Custom Flow 只支持ambient,chat、chat-partial两个值不被支持。coding_environment:声明运行环境。默认full(含仓库克隆、依赖缓存、Git hooks),适合要读写仓库文件的 Flow;设为none则跳过克隆与依赖缓存,适合"纯 API 调用、不碰本地仓库"的 Flow,能省下不少启动开销。components:编排单元,type: AgentComponent表示这是一个智能体组件,prompt_id指向prompts里定义好的提示词。inputs:声明数据来源。context:goal是触发器传入的目标,context:project_id是当前项目 ID,可以用from ... as ...重命名。routers:定义组件之间的流转关系,to: end表示该组件结束后 Flow 结束。flow.entry_point:入口组件。
触发器类型决定了 context:goal 的值形态。以"指派为审查人"为例,当 Flow 服务账号被指派为 MR 审查人时,context:goal 就是该 MR 的 IID,通常配合 context:project_id 一起用:
yaml
components:
- name: "review_mr"
type: AgentComponent
prompt_id: "review_mr_prompt"
inputs:
- from: "context:project_id"
as: "project_id"
- from: "context:goal"
as: "mr_iid"
而"@提及"事件传入的,是完整的评论文本加上资源上下文;"流水线事件"传入的,则是完整的 pipeline webhook 载荷。设计 Flow 时,要先想清楚用哪种触发器、goal 是什么形态,再决定 inputs 怎么接。
四、安全与权限:Flow 凭什么"不越权"
这是 Custom Flow 最值得讲清楚的一点。一个会自动改代码、自动调 API 的编排单元,权限一旦失控就是事故。
官方设计了三道闸:
- 服务账号 + Composite Identity(复合身份) :Flow 的服务账号采用复合身份认证,保证 Flow 永远无法访问超出"触发它的那个用户"权限范围的资源。也就是说,谁触发的 Flow,Flow 最多只能碰到谁能看到的东西。
- 令牌作用域收紧 :Flow 内置
GITLAB_TOKEN(也暴露为GITLAB_OAUTH_TOKEN),但这个令牌只拥有ai_workflows作用域 ,只能访问被允许的 API 端点;越界端点即便带正确令牌也会被拒绝。调用时要用Authorization: Bearer,用PRIVATE-TOKEN头会返回401。 - 可见性分档 :
Public / Restricted / Private三档,把"谁能启用、谁能看到"控制到群组粒度。
一个需要留意的点:跨顶级群组共享 Flow 服务账号会带来权限风险。官方建议不要让同一个 Flow 服务账号横跨多个顶级群组,否则可能造成非预期的访问权限扩散。
五、踩坑复盘:最容易踩的五个点
- Flow 不能复用现成的自定义 Agent。想复用团队已经建好的 Agent,请直接建 Agent 用,而不是在 Flow 里"引用"它;Flow 是基于 YAML 自建智能体的。
environment只能写ambient。照搬 v1 规范里的chat会直接校验失败,Flow 不运行。prompts里不要写model字段。模型由群组/实例级配置决定,自定义 Flow 里写模型是受限字段。coding_environment按需选 。纯 API 编排的 Flow 选none,避免每次运行都先做一次仓库克隆;要改仓库文件的 Flow 才用默认的full。- 触发器与
goal形态要对齐 。"@提及"、"指派为审查人"、"流水线事件"传入的goal格式完全不同,inputs映射错了,Flow 拿到的就不是你期望的数据。
六、落地建议:从一条高频流程开始
不建议一上来就把所有流程都 Flow 化。更务实的路径是:
- 选一条高频、步骤清晰、可标准化的流程做试点------比如"依赖升级 MR 的破坏性变更自动修复"或"SAST 漏洞的发现---修复---复核闭环"。
- 先理解内置的 Foundational Flows(Code Review Flow、Fix CI/CD Pipeline Flow、SAST 漏洞修复 Flow 等)是怎么编排的,再照着思路写自己的。
- 把权限边界想清楚再启用:选对可见性档位,避免服务账号跨顶级群组共享。
当"一个 Agent 做一件事"进化为"一条 Flow 编排一串 Agent",研发团队真正被释放的,是那些原本需要人肉接力的端到端流程。
本文功能信息均出自极狐GitLab 官方文档(docs.gitlab.cn),YAML 片段为基于官方 flow registry v1 规范的示意配置。想上手体验,可前往极狐GitLab 官方文档中心查看「GitLab Duo Agent Platform --- Custom flows」完整说明。