news 2026/9/16 20:03:54

Hatchet CLI 触发工作流并轮询完成:trigger-and-watch 实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Hatchet CLI 触发工作流并轮询完成:trigger-and-watch 实战指南

Hatchet CLI 触发工作流并轮询完成:trigger-and-watch 实战指南

【免费下载链接】hatchet🪓 An orchestration engine for background tasks, AI agents, and durable workflows项目地址: https://gitcode.com/GitHub_Trending/ha/hatchet

本篇指南围绕 Hatchet CLI 的triggerruns命令,完整讲解如何在命令行中手动触发一个工作流、捕获 run ID、轮询其运行状态直至终态,并在失败时通过日志与事件进行诊断。该流程面向自动化场景(尤其适合 AI Agent 与脚本化集成),读完即可掌握一套可复制的"触发—轮询—诊断—清理"闭环,并理解命令背后的源码实现。

前置条件

在开始触发工作流之前,需要确认以下三点:

  1. 必须有一个正在运行的 Hatchet worker。worker 通过hatchet worker dev -p HATCHET_PROFILE启动(HATCHET_PROFILE为你要使用的 profile 名称)。如果没有任何 worker 在运行,任务会永远停留在QUEUED状态,永远不会被执行。worker 启动的完整配置(hatchet.yaml、自动重载、pre-commands)参见 start-worker.md。
  2. 必须知道工作流名称,并准备好对应的输入 JSON。
  3. 这些命令需要一个 profile(通过-p HATCHET_PROFILE指定)。如果你的本地开发场景希望免去 token 和服务器,可以使用嵌入式模式(embedded mode)——在该模式下引擎在 worker 进程内启动,由代码直接触发任务而不是走 CLI,详见 local-dev-embedded.md。

关于 profile 的创建与选择,可参考 setup-cli.md。CLI 的trigger命令同时支持交互式选择器与非交互模式;本文档给出的非交互流程专为自动化场景设计。

步骤一:将输入写入临时文件

为避免多个会话之间互相冲突,请将工作流输入 JSON 写入一个唯一命名的临时文件。使用时间戳与进程 ID 组合命名可以保证唯一性:

HATCHET_INPUT_FILE="/tmp/hatchet-input-$(date +%s)-$$.json" cat > "$HATCHET_INPUT_FILE" << 'ENDJSON' INPUT_JSON ENDJSON

INPUT_JSON替换为工作流实际需要的 JSON payload。使用 heredoc 的'ENDJSON'(带引号)可以防止 shell 对$、反引号等字符做变量展开,确保 JSON 内容原样写入。这一步的意义在于:后续的hatchet trigger通过-j参数接收文件路径而非内联字符串,避免长 JSON 在命令行中转义出错。

从源码看,CLI 对输入 JSON 的校验发生在读取文件之后——runManualNonInteractive先调用os.ReadFile(jsonPath)读取文件内容,再通过json.Unmarshal校验其合法性(validateJSON),任何非法 JSON 都会直接报错退出(见 trigger.go)。因此写入后如果立即触发失败并提示 "invalid JSON in file",通常是文件内容本身有问题。

步骤二:触发工作流并捕获 run ID

使用hatchet trigger manual子命令进行非交互式手动触发,并开启-o json输出:

RUN_ID=$(hatchet trigger manual -w WORKFLOW_NAME -j "$HATCHET_INPUT_FILE" -p HATCHET_PROFILE -o json | jq -r '.runId')

各参数含义如下:

参数简写说明
manualtrigger的保留子命令名,表示"通过 API 手动触发工作流"
-w WORKFLOW_NAME--workflow要触发的工作流名称(非交互模式必须与-j同时提供)
-j "$HATCHET_INPUT_FILE"--json输入 JSON 文件的路径
-p HATCHET_PROFILE--profile连接 Hatchet 时使用的 profile
-o json--output以 JSON 格式输出,跳过交互提示

-o json会让命令向 stdout 输出{"runId": "...", "workflow": "..."}这样的 JSON 结构,上面的命令通过jq -r '.runId'直接把 run ID 捕获到$RUN_ID变量中,供后续轮询步骤使用。

源码视角:trigger manual内部发生了什么

在 trigger.go 中,trigger命令的入口逻辑如下:

  • 当提供了--workflow--json标志时,自动进入非交互手动模式runManualNonInteractive),此时manual以外的触发器名称会被拒绝("--workflowand--jsonflags can only be used with manual triggering"),且两个标志缺一不可。
  • 在非交互模式下,CLI 通过 REST API 拉取工作流列表,按名称精确匹配目标工作流;如果未找到,直接报错workflow '<name>' not found
  • 随后调用hatchetClient.Admin().RunWorkflow(workflowName, inputData)发起触发,整个过程有30 秒超时保护:如果超时未返回,会提示 "workflow trigger timed out after 30 seconds",通常表示与 Hatchet 服务器的连接有问题(见 trigger.go)。
  • JSON 输出结构由printJSON生成,字段为runIdworkflow(见 trigger.go)。

值得一提的还有trigger命令的多面性:不加manual时它会加载项目根目录的hatchet.yaml,展示triggers配置段定义的触发器列表供交互选择(hatchet trigger显示选择器、hatchet trigger <name>直接运行对应触发器);manual是保留关键字,hatchet.yaml中的触发器不允许命名为manualvalidateTriggerNames强制校验)。

步骤三:轮询直至运行结束

触发完成后,运行可能不会立即结束。需要每 5 秒执行一次以下命令,直到运行进入终态:

hatchet runs get <RUN_ID> -o json -p HATCHET_PROFILE

解析返回的 JSON 并检查状态:

  • 查看.run.status获取整个运行的总体状态,查看.tasks[].status获取每个任务的独立状态。
  • 终态(terminal statuses)COMPLETEDFAILEDCANCELLED。看到这些状态即可停止轮询。
  • 非终态(non-terminal statuses)QUEUEDRUNNING。看到这些状态需要继续轮询。

之所以用 JSON 输出而非默认模式,是因为runs get不带-o json时会直接启动交互式 TUI(终端界面),这不适合脚本化的轮询循环。从 runs.go 的源码看,runs get接受唯一一个 run ID 参数,JSON 模式下它调用V1WorkflowRunGetWithResponse获取完整运行详情后原样打印。返回的结构中不仅包含状态,还包含displayName、输入、各任务的输出/错误信息与时间戳,这些在后续诊断中非常有用(详见 debug-run.md)。

步骤四:失败处理

如果轮询发现运行状态为FAILED,按下面的顺序收集诊断信息。

获取日志(logs)

hatchet runs logs <RUN_ID> -p HATCHET_PROFILE

该命令打印任务代码产生的应用级日志输出(如 print 语句、logger 调用)。重点寻找错误信息、堆栈跟踪或非预期输出。日志按时间戳排序输出;对于多任务(DAG)运行,所有任务的日志会合并后按时间排序,并带有任务名前缀,方便区分来源。

从源码看,runs logs首先尝试把 run ID 当作工作流运行(DAG)来解析,逐个任务拉取日志后合并排序;若失败则回退为把 run ID 当作单个任务 ID 处理(见 runs.go)。此外它还支持几个实用的扩展参数:

参数说明
--tail N只显示最近 N 行日志
--since 5m只显示最近 5 分钟内的日志(支持1h24h7d等格式)
-f/--follow持续轮询新日志并实时打印,Ctrl+C 停止(每 2 秒轮询一次)

获取事件(events)

hatchet runs events <RUN_ID> -o json -p HATCHET_PROFILE

该命令返回生命周期事件日志,展示任务是如何被派发(dispatch)、开始(start)和失败(fail)的完整序列。重点关注eventTypemessage字段,理解失败的先后顺序。事件类型通常包括QUEUEDSTARTEDFINISHEDFAILEDCANCELLED等;非 JSON 模式下,每条事件会按时间 事件类型 任务名 消息的格式打印,便于人工阅读(见 runs.go)。

步骤五:清理临时文件

轮询结束、诊断完成后,删除之前创建的输入临时文件,避免在/tmp堆积垃圾文件:

rm -f "$HATCHET_INPUT_FILE"

常见问题排查

现象可能原因处理方式
任务一直停留在 QUEUEDworker 没有运行,或工作流/任务名称与 worker 注册的不一致启动或重启 worker(hatchet worker dev -p HATCHET_PROFILE),并核对任务名称
任务立即 FAILED任务代码抛出了异常检查日志(步骤四)中的堆栈跟踪
任务被 CANCELLED运行被外部取消检查事件日志,定位取消来源

结合 debug-run.md 的排查经验,针对上述问题还可以进一步细化:

  • QUEUED 但无 STARTED 事件:说明任务从未被任何 worker 拾取。除 worker 未启动外,还要检查 worker 是否注册了该任务类型、以及 worker 与触发命令是否使用了相同的-pprofile(不同 profile 指向不同租户,任务无法互通)。
  • FAILED:先看日志中的堆栈,再看事件中的FAILED事件消息。常见原因包括任务代码未处理异常、超时、或依赖(数据库、外部 API)不可达。
  • 运行 COMPLETED 但输出不符合预期:检查.tasks[].output看各任务实际返回了什么,核对.run.input确认输入是否正确。
  • 执行缓慢:对比每个任务的startedAtfinishedAt时间戳,找出瓶颈任务;若触发与首个任务启动之间有明显间隔,通常意味着排队延迟(worker 容量不足)。

补充:与其它 CLI 技能的配合

本文档是 Hatchet CLI Agent Skills 体系中的一环(见 SKILL.md)。按场景选择配套文档可形成完整闭环:

  • 启动 worker→ start-worker.md
  • 本地免 token 开发(嵌入式模式)→ local-dev-embedded.md
  • 深入诊断失败/卡住的运行→ debug-run.md
  • 使用相同或新的输入重放运行→ replay-run.md
  • CLI 与 profile 配置→ setup-cli.md

关键 CLI 惯例贯穿始终:本地开发优先嵌入式模式(无需 token/profile);指定 profile 用-p;机器可读输出统一用-o json;输入写入唯一命名的临时文件;使用完毕后清理临时文件。遵循这些惯例,触发—轮询—诊断的自动化流程就能稳定、可重复地运行。

【免费下载链接】hatchet🪓 An orchestration engine for background tasks, AI agents, and durable workflows项目地址: https://gitcode.com/GitHub_Trending/ha/hatchet

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 20:00:08

LibreTranslate 自托管指南:三步跑通自己的免费翻译API

LibreTranslate 自托管指南&#xff1a;三步跑通自己的免费翻译API 【免费下载链接】LibreTranslate Free and Open Source Machine Translation API. Self-hosted, offline capable and easy to setup. 项目地址: https://gitcode.com/GitHub_Trending/li/LibreTranslate …

作者头像 李华
网站建设 2026/9/16 19:59:54

TinyML到TinyDL:嵌入式AI从模型压缩到硬件加速的全栈部署

1. 项目概述&#xff1a;当“大象”真的要住进“冰箱”&#xff0c;我们到底在搬什么&#xff1f;“把深度学习模型塞进芯片&#xff0c;让大象住进冰箱”——这句标题不是段子&#xff0c;而是过去三年我在嵌入式AI一线踩坑、调参、烧板子、改PCB时最常对自己说的自嘲话。所谓…

作者头像 李华
网站建设 2026/9/16 19:57:08

Go 1.27标准库UUID全解析:go-modern-guidelines解读crypto/rand/uuid

Go 1.27标准库UUID全解析&#xff1a;go-modern-guidelines解读crypto/rand/uuid 【免费下载链接】go-modern-guidelines Help AI coding agents write modern Go 项目地址: https://gitcode.com/GitHub_Trending/go/go-modern-guidelines 写 Go 项目要生成或解析 UUID&…

作者头像 李华