Conductor 实战:零代码创建并运行你的第一个 HTTP 工作流
【免费下载链接】conductorConductor is an event driven agentic workflow engine providing durable and highly resilient execution engine for applications and AI Agents项目地址: https://gitcode.com/GitHub_Trending/co/conductor
本文是一份基于 Conductor 的入门实战指南,核心是讲解如何在不编写任何微服务代码的前提下,利用内置的 HTTP 系统任务(System Task)定义并运行一个真实可用的工作流:它会在运行时调用一个公开的 JSON 数据 API,并把返回结果作为工作流输出。读完本文,你将掌握 Conductor 工作流定义的 JSON 结构、HTTP 任务的参数语义与输出格式、通过 Swagger/REST API 注册与启动工作流的方法,以及如何在 Conductor UI 中追踪一次完整的工作流执行。
为什么可以“零代码”跑通第一个工作流
Conductor 最强大的特性之一,是它自带了大量系统任务(System Tasks)——这些任务直接运行在 Conductor 服务端,无需任何外部 worker 进程。也就是说,对于大量典型的“调用一个接口、等待一段时间、发布一个事件”之类的日常工作,完全不需要编写一行 worker 代码。
本实验使用其中的HTTP系统任务。它的作用就是发起一次 HTTP/HTTPS 调用,并把响应体、状态码、响应头等作为任务输出,供后续任务引用。你可以在 系统任务总览 中查看完整的内置任务清单,也可以在 HTTP 任务文档 中查看该任务的详细配置说明。
在开始之前,请确认你已经有一个正在运行的 Conductor 实例(包括 Server 与 UI)。如果还没有,可参考 部署指南 中的 Docker 说明快速启动,实验过程中会用到 cURL、Postman 或 Swagger UI 来发起 API 调用(参见 Guided Tutorial 前置说明)。
配置我们的第一个工作流
下面是一份可以直接用于实验的工作流定义。它查询 DataUSA 提供的公开人口统计 JSON API,整个工作流只包含一个HTTP系统任务:
{ "name": "first_sample_workflow", "description": "First Sample Workflow", "version": 1, "tasks": [ { "name": "get_population_data", "taskReferenceName": "get_population_data", "inputParameters": { "http_request": { "uri": "https://datausa.io/api/data?drilldowns=Nation&measures=Population", "method": "GET" } }, "type": "HTTP" } ], "inputParameters": [], "outputParameters": { "data": "${get_population_data.output.response.body.data}", "source": "${get_population_data.output.response.body.source}" }, "schemaVersion": 2, "restartable": true, "workflowStatusListenerEnabled": false, "ownerEmail": "example@email.com", "timeoutPolicy": "ALERT_ONLY", "timeoutSeconds": 0 }这个工作流不需要任何 worker 实现——任务由 Conductor 服务端自己托管执行。这正是 Conductor 系统任务的典型用法:对于很多常规工作,我们甚至不需要写任何代码。
工作流名称
"name" : "first_sample_workflow"name定义了工作流的名称,这里是first_sample_workflow。后续启动工作流时,会通过这个名称找到对应的定义。
工作流中的任务
工作流定义中的任务(tasks)列表承载了实际的执行逻辑。本例中只有一个任务,其关键字段如下:
{ "name": "get_population_data", "taskReferenceName": "get_population_data", "inputParameters": { "http_request": { "uri": "https://datausa.io/api/data?drilldowns=Nation&measures=Population", "method": "GET" } }, "type": "HTTP" }各字段含义:
name:任务的名称,即任务定义(TaskDef)的名字。taskReferenceName:任务在当前这个工作流实例中的引用名。同一个工作流中允许出现多个同名任务,但每个任务的taskReferenceName必须在整个工作流内保持唯一。后续其他任务或工作流输出参数通过${taskReferenceName.output.xxx}引用它。inputParameters:任务的输入。既可以直接硬编码(如本例),也可以通过workflow input或前序任务的输出动态注入。type:任务类型。这里为HTTP,即系统任务。Conductor 还支持多种任务类型,详见 系统任务总览。http_request:HTTP类型任务要求的输入对象,这里提供了公开 JSON API 的 URL 与请求方法GET。
定义中其余的字段(outputParameters、restartable、timeoutPolicy等)属于元数据或更高级的配置:outputParameters用于将任务输出映射为工作流级输出;timeoutPolicy: "ALERT_ONLY"表示工作流超时只告警不终止;restartable: true允许失败后重启。这些都可以在后续的详细文档中深入学习。
深入 HTTP 系统任务:参数与执行原理
为了用好这个工作流,值得深入理解HTTP任务本身。根据 HTTP 任务文档,请求参数可以直接写在inputParameters下(扁平形式),也可以嵌套在inputParameters.http_request中(传统形式),两种形式完全等价,扁平形式是新建工作流的推荐写法。
请求参数一览
| 参数 | 类型 | 说明 | 必填/可选 |
|---|---|---|---|
uri | String | HTTP 服务地址,支持动态引用,如${workflow.input.url} | 必填 |
method | String | HTTP 方法,支持GET、PUT、POST、PATCH、DELETE、OPTIONS、HEAD、TRACE | 必填 |
accept | String | 服务端要求的 Accept 头,默认application/json | 可选 |
contentType | String | 请求的 Content-Type,默认application/json | 可选 |
headers | Map[String, Any] | 随请求发送的附加 HTTP 头 | 可选 |
body | Map[String, Any] | 请求体,POST、PUT、PATCH方法必填 | 视方法而定 |
asyncComplete | Boolean | 是否异步完成任务,默认false;为true时任务保持IN_PROGRESS,等待外部事件将其标记为完成 | 可选 |
connectionTimeOut | Integer | 连接超时(毫秒) | 可选 |
readTimeOut | Integer | 读取超时(毫秒) | 可选 |
例如,一个更完整的扁平形式 POST 请求可以这样写:
{ "name": "http", "taskReferenceName": "http_ref", "type": "HTTP", "inputParameters": { "uri": "https://api.example.com/data", "method": "POST", "headers": { "Authorization": "Bearer ${workflow.input.api_token}", "X-Request-Id": "${workflow.correlationId}" }, "body": { "key": "value" } } }源码级的执行语义
从实现层面看,HTTP 任务的执行逻辑位于 HttpTask.java:
- 入参兼容:
start()方法首先从task.getInputData()中查找http_request键(常量REQUEST_PARAMETER_NAME,见 HttpTask.java);如果该键不存在,则直接把整个inputData当作请求对象处理(HttpTask.java)。这就是上述两种参数形式都能工作的底层原因。 - 必填校验:
uri或method缺失时,任务会直接标记为FAILED并写入失败原因(HttpTask.java)。 - 状态判定:远端返回 2xx 时任务置为
COMPLETED;否则置为FAILED,并以响应体作为失败原因(HttpTask.java)。 - 默认值:
Input类的默认accept与contentType均为application/json,默认连接/读取超时为 3000ms(HttpTask.java),你可以在任务输入中按需覆盖。 - 响应体解析:
extractBody()会尝试把响应字符串解析为 JSON 数组、JSON 对象或数值;解析失败时原样返回字符串(HttpTask.java)。
任务输出结构
HTTP任务执行完成后,会把完整响应写入输出参数response(由HttpResponse.asMap()组装,见 HttpTask.java):
| 输出字段 | 类型 | 说明 |
|---|---|---|
response | Map[String, Any] | 包含请求响应的 JSON 结构 |
response.headers | Map[String, Any] | 响应头 |
response.statusCode | Integer | HTTP 状态码 |
response.reasonPhrase | String | 状态码对应的原因短语 |
response.body | Map[String, Any] | 端点返回的响应体数据 |
因此本文示例工作流中的"data": "${get_population_data.output.response.body.data}"就是把 HTTP 任务响应体中 JSON 的data字段(DataUSA 返回的人口统计数据数组)暴露为工作流输出。
通过 Swagger API 注册工作流
定义准备好之后,下一步就是把工作流元数据注册到 Conductor。打开 Conductor Server 的 Swagger UI,进入 metadata 工作流创建接口:
http://{{ server_host }}/swagger-ui/index.html?configUrl=/api-docs/swagger-config#/metadata-resource/create如果链接没有定位到正确的 Swagger 分区,也可以手动导航到Metadata-Resource →POST {{ api_prefix }}/metadata/workflow。
把上面的工作流 JSON 整体粘贴进请求体,点击Execute。
从源码看,该接口由 MetadataResource.java 中的@PostMapping("/workflow")提供(即POST /metadata/workflow),用于创建/更新工作流元数据,随后即可在 UI 中看到。
注册成功后,切换到 Conductor UI 的工作流定义页面,就能看到first_sample_workflow这条新定义;点击进入还能看到它的可视化流程表示(单个 HTTP 任务节点)。
运行我们的第一个工作流
工作流注册完成,接下来启动它。同样在 Swagger UI 中,使用 workflow-resources 下的启动接口:
http://{{ server_host }}/swagger-ui/index.html?configUrl=/api-docs/swagger-config#/workflow-resource/startWorkflow_1点击Execute后,Conductor 会返回一个workflow id。请保存好它,之后需要用它来定位这次执行实例:
- 如果你的 UI 安装启用了搜索(依赖 Elasticsearch 等索引),可以直接在 UI 中按工作流名称搜索到这次运行;
- 如果没有启用搜索,请从 Swagger UI 的响应中复制该 workflow id。
从源码看,启动接口对应 WorkflowResource.java 中的两个端点:POST /workflow(接收StartWorkflowRequest,支持域名隔离等高级参数)和POST /workflow/{name}(按名称启动,支持version、correlationId、priority参数并直接传入输入 Map)。此外还有POST /workflow/execute/{name}/{version}用于同步执行并等待结果(WorkflowResource.java)。
用 cURL 启动(可选)
不依赖 Swagger UI 时,也可以用 cURL 完成同样的操作。注册与启动的 REST API 均挂载在{{ api_prefix }}前缀下(默认部署通常为/api,以你的实际部署配置为准):
# 1) 注册工作流定义(请求体为上文完整 JSON) curl -X POST 'http://{{ server_host }}/api/metadata/workflow' \ -H 'Content-Type: application/json' \ -d @first_sample_workflow.json # 2) 按名称启动工作流,返回 workflow id curl -X POST 'http://{{ server_host }}/api/workflow/first_sample_workflow' \ -H 'Content-Type: application/json' \ -d '{}'在 UI 中查看执行结果
启动之后,工作流应该很快执行完毕(整个工作流只有一次 HTTP 调用)。直接使用如下 URL 格式加载这次执行:
http://localhost:5000/execution/<WORKFLOW_ID>把<WORKFLOW_ID>替换为上一步获取的 workflow id,即可看到执行详情页面。可以点击不同的标签页,逐一查看输入、输出、任务列表等:
在输出标签页中,你应该能看到我们在outputParameters中定义的data(DataUSA 返回的人口统计数据数组)与source(数据来源描述),证明整条“定义 → 注册 → 启动 → 执行 → 输出”链路已经完整打通。
下一步:继续探索系统任务
本文只是 Conductor 的起点。既然第一个工作流已经跑通,你可以继续:
- 在同一个工作流中串联多个
HTTP任务,把前一个任务的输出(如response.body)作为后一个任务的输入,实现无代码的数据管道; - 尝试其他开箱即用的系统任务,例如
INLINE(服务端执行轻量脚本)、WAIT(等待定时器/外部信号)、EVENT(发布事件到 Kafka、NATS、SQS 等)、JSON_JQ_TRANSFORM(用 jq 表达式转换 JSON),完整清单见 系统任务总览; - 进一步学习 Kitchen Sink 示例工作流,它在一个定义里演示了并行分支(Fork)、子工作流、条件判断(Decision/Switch)、动态任务与 HTTP 任务等全部 schema 构造。
总结
通过本文,我们完成了一次完整的最小闭环:创建 → 注册 → 运行 → 查看一个基于系统任务的 Conductor 工作流。核心收获有三点:
- 工作流创建:理解了
WorkflowDefJSON 的结构,包括name、tasks、taskReferenceName、inputParameters、outputParameters等关键字段; - 系统任务(以 HTTP 为例):掌握了
HTTP任务的两种入参形式、请求参数与输出结构,以及它在 HttpTask.java 中的执行语义; - 通过 API 运行工作流:学会了在 Swagger UI(或通过 cURL 调用
POST /workflow/{name})中启动工作流,并在 UI 中用 workflow id 追踪执行结果。
正如实验所展示的:对于大量典型工作,我们不必编写任何 worker 代码,Conductor 的系统任务即可直接承担生产级编排职责。
【免费下载链接】conductorConductor is an event driven agentic workflow engine providing durable and highly resilient execution engine for applications and AI Agents项目地址: https://gitcode.com/GitHub_Trending/co/conductor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考