mcpField
G
gimbal-workflows

gimbal-workflows

github.com/tylergannonAgent 工作流336 次安装5 天前更新
代码仓库

关于 gimbal-workflows

指导在 Gimbal 中编写 Go 工作流,涵盖结构、Agent 角色、提示词、交接与验证。它强调让决策和证据在源代码中清晰可见,并区分任务策略与适配器恢复。

主要功能

  1. 01围绕明确结果设计工作流
  2. 02选择顺序、分支或自适应循环
  3. 03定义角色、所有权与交接
  4. 04指导提示词与上下文选择
  5. 05通过记录的证据验证结果
  6. 06说明服务与取消的生命周期

适用场景

  1. 01构建分阶段的研究与实现工作流
  2. 02协调独立方案并进行评审
  3. 03设计验证与重新规划循环
  4. 04根据源代码和证据诊断工作流行为

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tylergannon/gimbal --skill gimbal-workflows

安装后在 Claude Code 中输入/gimbal-workflows确认已加载。

附带文件references/patterns.md

详细介绍

编写 Gimbal 工作流

编写的程序应让其目的、决策和依据都清晰地呈现在源代码中。力求像一页伪代码一样清楚。研究、方案比选、批评、重试、工作树和交付,都是通过普通 Go 代码和 Gimbal 原语内联编写的策略。

适配器负责传输维护和原生状态协调,并以有界、可观测且负责任的尽力方式完成每个请求的轮次。不要在工作流中针对连接丢失添加重试:回复丢失并不能证明操作从未发生。工作流负责任务策略和独立验证;适配器恢复时必须保留会话身份、避免重复工作、保留取消操作,并让未经验证的远程清理仍可重试。

当前 API 请参阅 Godoc。对于现有命令,请使用 使用 Gimbal;对于构建和安装应用程序, 请使用 构建和发布。

明确结果及其证明方式

与人工在 Gimbal 应用程序中的 /workflows/<name> 页面上一起查看内置工作流源代码。在代码检出目录中,运行 just dev 可启动实时应用程序: 工作流源代码的编辑会刷新其图表、提示词和嵌套上下文检查视图、指南及参数说明。人工可以分享带有已选中和已展开对象的 URL,同时 Agent 编辑这些对象的 Go 源代码。无效编辑会保留上一次成功的视图;标识符变更或移除时,视图会重置,不会猜测。已安装的应用程序会显示随附的快照。阅读页面不会运行工作流;请使用 gimbal run <name> 调用工作流。

使用紧邻操作的文档注释,在第一行提供人类可读的标题,说明操作、范围或条件;后续行提供描述。When true: Command provided 会标注条件为真的分支;case 注释会标注 switch 分支。保留静态源代码所表达的事实:不要虚构运行时值,也不要将未标注的操作解读为 Agent 意图。

说明工作流应完成什么、范围是什么,以及需要观察什么才能确认其奏效。为 Agent 提供目标和有用的已验证事实;除非特定方法是要求,否则让它们自行选择方法。随着事实逐渐明朗,计划可以改变。原始目标始终是权威依据。

在设计中区分三件事:

  • 程序: 角色、分支、并发、反馈和停止决策。
  • 输入: 本次调用的目标、项目、问题、计划或候选项。
  • 知识: Agent 工作时可以检索的材料。

即使输入和知识不断变化,程序也应始终易于理解。将任务数据放在参数、范围上下文和本地文件中,而不是把每项新任务都编码进编排逻辑。

选择最精简且实用的结构

如果单个 Agent 或一个执行序列已足够,就采用它。只有在确实需要有用的上下文、独立判断或工作交接时,才添加角色或阶段。

需求结构
范围明确的单项任务一个 Agent 轮次。
有依赖关系的阶段显式传递结果的执行序列。
独立调查或候选方案并发分支,然后汇合。
多个 Agent 需要相同的初始研究先研究一次,再分叉对话。
相互竞争的实现方案使用不同工作树,然后由评审者检查实际候选方案。
批评与修订明确的批评/修订轮次,并设定停止条件。
已知的有限集合遍历提供的各项。
下一项有用任务取决于新证据由规划器驱动的循环,并提供工作者反馈和验证反馈。

让每项策略都在工作流中清晰可见。隐藏编排逻辑的辅助函数可能会让更短的文件更难理解。在 Gimbal 仓库中,新增导出 API 名称必须获得 Tyler 的明确请求。

选择如何组合研究、并行尝试、批评或自适应实现时,请阅读 工作流模式。

明确角色职责

使用 roles.go 中已定义的角色常量。分支名称用于标识参与者;角色用于标识可复用的工作类型;运行绑定用于选择模型。不要为了分配其他模型而向 internal/builtin/defaults.json 添加特定于工作流或提供方的角色。目录变更需要明确的产品决策,以便模型分配在不同工作流中保持可复用。

研究员负责查明事实并找到有用的来源位置。规划者负责选择下一项任务。工作者负责执行任务。验证者负责检查结果,以及证据是否足以证明满足验收条件。主管负责指导正在工作的 Agent。根据任务需要使用相应角色;列出所有可能的角色并不会让工作流变得更好。

在需要的地方保持独立性。共享研究成果可以避免重复阅读,但评判者必须检查原始证据和实际候选项。实施者的总结可以帮助验证,但无法证明实现有效。将工作者的对话分支给评判者,会连同有用的上下文一起带上其中的假设。

明确责任归属和交接

根据工作的生命周期安排会话。规划者可能需要在多个任务之间保持连续性;任务工作者可能需要与之前的尝试隔离。复用会话也会复用其对话历史。结束一个作用域,并不会抹去该 Agent 已经看到的内容。

每个并行分支都必须有负责人,并在其所属工作结束前完成汇合。取消和清理是两项不同的工作。若并行编辑 Agent 可能互相干扰,就为它们分别提供工作树,并核实它们实际写入的位置。

派发任务前,先在本地保存关键信息。提示词应指明问题、计划、源文件或所需研究成果的绝对路径。对于大型语料库,通过精简索引检索,并传递选定的证据或其位置。只保留相关上下文,不要在每轮对话中复制整个语料库。

交接内容应向下一个角色明确说明具体任务、相关文件、已观察到的结果、尚未解决的发现和决策。明确提供反馈;不要依赖子作用域或提供方对话自动成为共享的项目状态。其他角色必须独立检查的知识,应保存在本地产物中。

编写留有判断空间的提示词

使用通俗的英文:说明要阅读什么、要产出什么结果、重要约束是什么,以及预期答案是什么。让提示词在源代码中易于检查;特定任务的数据应放在上下文中。诊断异常行为时,阅读渲染后的提示词,因为框架指令和先前对话也会产生影响。

如果工作流需要根据字段作出决策,就使用结构化答案。这些字段说明本身就是给 Agent 的指令。否则,普通文本或本地产物可能就足够了。避免使用只是重述模型已有理解的复杂输出约定。

围绕目标调整计划

自适应循环应根据目标、当前待办事项和观察到的结果来选择工作。分配一项目标明确、范围完整且有完成定义的工作。当不确定性阻碍可靠实现时,调查也属于有效工作。

将实际的工作者结果和验证结果反馈给规划流程。保留尚未解决的发现,并说明推迟工作的原因,以免重新规划时悄然丢失这些内容。评审发现是需要针对目标调查的主张,而不是自动纳入目标的事项。

让重试、限制和升级处理清晰可见,并与任务相称。提供的计划可以作为待办事项的起点,但不应决定之后的每项分配。结束任务调度与实现目标是两个独立的决定。

将能力投入到存在不确定性的环节。当边界清晰的规划能让分配易于撤销且可独立检查时,前沿规划器即使需要一次昂贵的调用,也可能值得使用。对于低风险的后台工作,如果经过的时间不如 token 成本重要,而且工作流能够容忍几次已完成的尝试被验证拒绝,直到某次尝试成功,就可以使用成本更低的 Terra 或 Sonnet 工作者。验证器的能力应与风险相匹配;将每次拒绝反馈给规划流程,并限制尝试次数。

这是工作流特性,而不是一句模型选择口号。对于工作不可逆、验证薄弱,或错误尝试可能破坏共享状态的情况,不要使用这种模式。提供商、执行框架或执行方面的错误不属于被拒绝的实现尝试;除非工作流明确处理此类错误,否则不要重试。

防止范围偏移

对于实现工作流,应为规划器、工作者和验证器提供范围指导。指导内容应反对过度设计、未请求的功能、过度打磨,以及缺乏合理的实际失败单元测试支撑的假设性边界情况修复。

指导仅供参考,绝不能成为完成工作的门槛。也要在初始任务分配中写明必要约束:短暂的调用可能在指导发挥作用前就已结束。在启动独立运行或托管实例前设置 TYPESAFE_API_KEY。Jev 会筛查已完成且暴露的思考内容,供已连接的监督者查看;它没有定时检查节奏,也没有备用机制。不提供这些事件的提供商不会触发自动评审。应观察异议是否改变了行为,而不要将建立连接或发送消息视为监督有效的证明。

验证行为并评估完成情况

在可行时,应在实现前选择有意义的验收依据。 不要让执行者为了通过检查而降低该条件。记录实际检查结果;Agent 声称检查通过,不能推翻命令失败的事实。

当 Agent 需要解读命令结果时,使用 Check:它会在当前作用域中记录命令、工作目录、退出代码、两个输出流以及任何执行错误,供下一轮使用。它的键遵循与 Set 相同的规则:在该作用域内是编译时常量,且只写入一次。在调用位置明确命名重复观察,例如 tests.1 和 tests.2。非零退出代码是证据,不是 Check 错误;执行、捕获或记录失败才是错误。普通 Go 代码需要返回值本身时,使用 RunCommand。Check 收集证据,但绝不会认证成功。

对于必须在一个作用域内持续运行的前台依赖(例如开发服务器),使用 Service(ctx, name, workdir, command)。Gimbal 会通过 zsh -c 启动该字符串,并立即继续;成功启动并不代表已就绪。应在普通工作流代码中通过 Check 或服务公开的协议检查就绪状态。在作用域关闭前发生任何退出(包括退出代码为零),都会导致所属作用域失败并取消。

声明该服务的作用域就是其生命周期边界。在 Iterate 外声明的服务会在各个条目作用域之间保持运行;在条目内声明的服务会在进入下一个条目前结束。正常关闭和取消时,会向服务的进程组发送 SIGTERM,随后在限定时间后升级为 SIGKILL。命令必须在前台运行,其后代进程也必须留在该进程组中。Gimbal 会记录输出和状态,但不会添加重启、健康检查,也不会管理由 Docker、Overmind 或类似工具在外部拥有的资源。

验证者会检查工作及其验证是否合理。构建或测试门禁通过,只能证明它实际覆盖的内容。有关实时工作流、外部引导或浏览器交互的声明,需要通过观察这些行为来验证。应区分任务结果、执行错误、已结束的调度和已达成的目标。

如果缺少证明或仍存在实际阻碍,应如实报告结果。 风格偏好和无关改进不应成为验收门槛。

让工作流可调用且易于理解

编写一个普通的 Go 入口,接收 context.Context、gimbal.Env,并可选地接收一个包内的 Params 结构体。支持的调用字段类型为字符串、整数、布尔值,以及这些类型的 polytype.Optional。字段注释用于提供可见的帮助文本;JSON 标签用于提供提交时使用的名称。必填字符串不得为空白,必填整数必须为正数。可选字段会保留省略与显式空值、false 和零之间的区别;Optional 不接受 null。

使用已安装的宿主生成外部模块:

gimbal generate --dir . --entry Review --name review \
  --role-default code-review=gpt-5.6-luna

在项目的 go.mod 中将 github.com/tylergannon/polytype/polytype 声明为 Go 工具,并固定到宿主的 Polytype 版本。将 Gimbal 和所有共享包固定到已部署的宿主版本,并使用相同的 Go 工具链、平台和构建标志。生成过程会针对具体的本地 Generate[T] 输出调用 go tool polytype --validate,并在工作流包中写入输入适配器、架构、有序字段、图和源代码指南。以 Go 源代码和字段注释为准;更改输入、输出或工作流结构后应重新生成。无需生成项目的前端。 A 个插件的主包会导出 Register(*gimbal.Registry) error。使用 RegisterWorkflow 注册生成的 ReviewDefinition(),并使用 RegisterBackend 注册任何后端配置/工厂。使用本地主机匹配的构建标志,通过 go build -buildmode=plugin 构建。对于已发布的 CLI,使用 -trimpath,并按照分发中所述,在 Go 工作区中使用精确的已发布 Gimbal 源码。将 .so 安装到已配置的 --plugin-dir 中。中央服务和工作流守护进程会在接受任务前,分别加载各自配置目录中的插件,并按排序顺序加载。将匹配的插件部署到中央服务和工作流环境;重启后,新目录才会生效。不兼容或重复的定义会导致启动失败。生成的图不具有初始化注册权限。

内置工作流遵循相同的定义和注册表路径。其清单保存在 internal/builtin/workflows.go 中;go generate ./... 会重新生成该选择。CLI 从所选中央服务获取描述,生成实用的参数和角色标志,然后提交纯调用数据。共享的 Run 表单会使用相同的运行时元数据,包括可选的 Include 控件。中央服务会在接纳前验证,工作流守护进程则会在启动独立运行器前再次准备。使用 JSON 或 @file 配合 --input,或使用参数标志;使用 --follow 等待任务完成。

工作流路由和任务路由彼此独立。--workflow-endpoint 用于选择 HTTP 工作流守护进程;--workflow-project 用于指定其本地项目,--work-dir 用于指定其执行目录。--task-endpoint 用于选择任务守护进程。对于已注册的后端,使用 --workflow-route 或 --task-route,并提供包含 name、configuration 和 environment 的 JSON 路由。每个环境都提供自己的工作区根目录和已配置的仓库。中央项目路径不是远程执行目录。请显式传输指定的上下文和任务文件;正文中任意的绝对路径不会自动改写。普通本地调用仍会作为独立子进程运行,并使用直接位于本地的任务。

对于远程轮次,gimbal.WithTaskFiles(ctx, backend.TaskFile{Name: "input.txt", Bytes: data}) 会提供显式命名的字节数据,以及运行时管理的上下文。任务环境会写入这些文件,并向 Agent 提供其原生路径。使用 gimbal.WithYields(ctx, "store", "DATABASE_URL") 作为 RunCommand、Check 或前台 Service 的上下文参数,以声明输出。不要赋值给返回的上下文:输出只属于该生产者,工作流检查器会拒绝其他位置的声明。程序会将 NAME=value 字符串写入 ENV_FILE;只有资源就绪后,服务才会将已完成的文件原子重命名到目标位置。即使服务没有输出,也必须发布空文件。有限运行时长的生产者只有在以零状态退出后才会发布输出。

gimbal.WithRequirements(ctx, "store", "DATABASE_URL") 用于声明使用操作的需求。重复调用会累积对多个存储区的访问权限。在任一声明中,都可以用 gimbal.DefaultStore 指定未命名的存储区。Gimbal 会检查指定的值,并授予对整个可见存储区的访问权限。程序会接收字符串环境变量;Agent 则会调用其原生执行器提供的、作用于特定操作的 Gimbal 回调。值不会自动插入提示词。子定义会在所有存储区中遮蔽祖先定义。 命名环境使用 OrchestratorBackend 建立监听守护进程;消息传递负责交付工作,SecretsBackend 提供限定作用域的值。路由的 Backends 构造数据会显式配置这些依赖。提供的本地实现会启动已配置的守护进程命令,并使用私有共享文件存储。清理作用域时,会先停止依赖它的原生任务,再释放值,最后释放环境占用。服务会收到 SIGINT,并有十秒时间完成清理;无法确认的清理状态会继续保留。系统不提供自动重放、重启、密钥轮换或逐键权限管理。

独立运行 gimbal.Run(gimbal.Project(ctx, dir), ...) 会在调用方进程中执行,并将内容写入 dir/runs,不会连接到正在运行的实例。gimbal run-prompt 会创建自己的无头运行时;除非通过 --logs 指定一个全新的空目录,否则会使用临时日志目录。这两种路径都不会加入托管实例的实时控制,也不会继承其启动环境。请将它们的持久状态与已获准加入运行中实例的项目分开;并发使用共享状态不受支持。

CLI 文档是编写工作流的一部分。调用方无需阅读实现,就应能了解用途、必需输入、有意义的默认值、输出或变更、完成条件与验证要求、限制,以及实用的调用方式。应针对相应工作流提供足够详细的信息,而不是套用固定字数或模板化内容。

当前生成器会将入口函数的文档摘要用于简短帮助,将包文档用于详细帮助,并将参数字段注释用于标志帮助。请将详细说明和示例放在包文档中;仅写在函数注释中的额外段落不会出现在详细帮助里。

运行启动时,会将已注册的图与持久状态一同保存。运行界面读取的是保存的图,因此守护进程重启或之后构建工作流,都不会改变已有运行的图。请保留工作流的 go:generate 指令,并在更改其结构后重新生成。

修改注释后,请检查生成的工作流列表和详细帮助。图或输出架构不能替代面向调用方的文档。如果所需帮助必须修改生成器,请明确指出具体缺口。

最后通过观察验证

运行相关检查,并使用 Luna 或 Haiku 等低成本模型实际执行工作流。检查实际的提示词、交接、决策、验证和结果。确认调用方能通过 CLI 帮助发现并理解该工作流。报告观察到的情况、运行所用的模型,以及仍未验证的内容。

评论

支持 Markdown