前言¶
智能体写代码,最容易出的问题是「一口气做完然后不知道该信什么」。需求、实现、验证、发布、复盘这几步如果不拆开,agent 往往在脑子里把 spec 和 build 混在一起,check 就变成走过场。已有的做法里,有的是给 agent 一堆结构化文档模板,有的是靠人在流程节点上手动把关,但这些办法要么没约束住 agent 的阶段跳跃,要么把负担转给了人。
下面介绍的 Galadon 走的是另一条路:它不试图让 agent 更聪明,而是把它限制在一个阶段一个阶段地走,每一步都留产物、设闸门。Galadon 由 Lumos-789 维护,也就是把现成的开源目录页上的插件拿来做对象,不夸大它的地位,只说明它能做什么、怎么用、有什么限制。
这是什么¶
一句话定位:Galadon 是一个面向 agent 构建项目的工程循环插件,把项目从 spec 到 learn 拆成五个阶段,并提供脚手架和门禁。
它解决的问题是:当 agent 负责写代码、跑测试、发布时,缺少一个稳定的阶段边界和产物检查机制。Galadon 初始化一个小型工程工作区,让 agent 一次只做一个阶段,核心层只认三样东西——阶段(phases)、产物(artifacts)、闸门(gates)。其余能力都通过 port 接口暴露,可以替换实现而不改五阶段循环。
分类上它属于「工作流」类。仓库地址为 https://github.com/Lumos-789/galadon ,目录页为 https://www.skillhub.cn/plugins/Lumos-789/galadon 。
核心功能¶
五阶段循环¶
Galadon 的主干是一个固定顺序的循环:
Spec -> Build -> Verify -> Ship -> Learn
这对应需求、实现、验证、发布、学习五个环节。agent 读 galadon.yaml,执行当前阶段,然后反复跑 galadon check,直到循环推进到 learn。闸门的作用是让不合格的产物直接失败,而不是让 agent 继续往下糊。
Port 接口¶
Galadon 把「谁来干」「用什么骨架」「怎么部署」这三件事抽成了三个 port:
| Port | 作用 | 内置参考实现 |
|---|---|---|
RolePort |
谁来干活 | solo |
TemplatePort |
写哪份 docs/profile.md;代码骨架由 --layout/--stack 决定 |
web, api, static |
DeployPort |
怎么构建、迁移、发布、探测、回滚 | local, ssh |
内置实现只是例子。一个项目可以替换其中任意 port,而不必改动五阶段循环本身。这也是它区别于「一个大模板包」的地方:流程是固定的,周边能力是可插的。
Layouts 与 stacks¶
init --layout 会加上生产项目里常见的项目内分层,默认的 none 保持基础模板、不带分层契约:
| Layout | 适用 | 生成内容(节选) |
|---|---|---|
none(默认) |
只想要裸循环 | 基础模板 |
webapp |
有后端和前端的产品 | server/, src/, web/, e2e/, tests/, deploy/, openspec/, spec/, wiki/, .agents/, config.md |
service |
后端服务或定时任务 | server/, src/, tests/, scripts/, deploy/, openspec/, spec/, wiki/, .agents/, config.md |
plugin |
可分发的 agent 插件 | bin/<project>, src/<project>/, skills/<project>/, docs/, tests/, openspec/, spec/, wiki/, .agents/, config.md |
除 none 之外,每个 layout 在 spec/ 下都带一层 spec 真值:INDEX.md(活动特性索引)、domains/README.md(每个 domain 一份行为契约)、TESTING.md(变更到检查的触发矩阵)、CONSTITUTION.md(硬性规则)。这四个文件放在 templates/layouts/_shared/ 中,在某个 layout 自己的 common/ 层之前渲染,所以 layout 可以覆盖某个文件,而 none 保持不变。
--stack 选择代码骨架和真实检查命令:
| Stack | build | test |
|---|---|---|
python(默认) |
python3 -m compileall -f -q src server;plugin 布局另跑 bash -n bin/<project> |
python3 -m unittest discover -s tests -v |
node |
node --check <layout entry>;plugin 布局另跑 bash -n bin/<project> |
npm test(node --test tests/) |
none |
无 | 无 |
带上 python 或 node stack 且 layout 非 none 时,初始化后至少有一个真实测试,galadon check 立刻是绿的;--stack none 没有检查命令,会明确报错而非静默通过。build 会对布局里每个源码根做编译或语法检查,并对插件的 bash 包装跑 bash -n,因此入口点损坏会直接让闸门失败。
gate 还会强制布局契约:AGENTS.md、openspec/config.yaml、spec/INDEX.md、spec/domains/、spec/TESTING.md、spec/CONSTITUTION.md、三个 wiki/ 目录、六个 .agents/ 槽位、非空 checks,以及 .gitignore 里的 out/ 和 .agents/。缺哪一项,gate 会失败并点名。仓库里模板中的 .agents/ 存储为 __agents__/,因为仓库自身忽略了 .agents/,渲染时再映射回来。
部署¶
远程部署用 deploy.adapter: ssh,把目录上传到运行 systemd 和反向代理的主机,有 releases、原子化的 current/previous 切换、部署锁,以及基于 commit 版本号的 JSON 探测:
deploy:
adapter: ssh
env: test
build: "mkdir -p dist && cp server.py dist/ && git rev-parse --short HEAD > dist/commit.txt"
probe_url: "https://demo.example.com/health.json"
probe_expect: "{{COMMIT}}"
artifact: "dist"
options:
host: 203.0.113.10
user: root
remote_root: /srv/demo
service: demo
domain: demo.example.com
listen: 127.0.0.1:18790
exec_start: "/usr/bin/python3 /srv/demo/current/server.py"
caddy_block: demo
bootstrap 创建系统用户、release 目录树、systemd unit 和一块带标记的反向代理配置(它会先备份代理配置,校验通过后才 reload)。teardown --yes 只删除仍带 bootstrap 标记的 root。
deploy.adapter: local 在 deploy.options.root(默认 .galadon/deploy)下使用同样的 release 目录树:releases/<timestamp>-<version>、原子 current 切换、保留 previous、shared/deploy.lock。持有锁时拒绝 ship;探测失败会把 current 恢复回 previous,重新探测那一个 release,并以非零退出并点名实际生效的 release。
安装与启用¶
插件把 skill 和 CLI 一起发布,不需要额外的安装步骤。对 DeepSeek Harness,官方命令是(路径或仓库占位符需填实际值):
dsh plugin --profile headless add <path-or-repo>
对另外两个宿主,分别是:
zcode plugins install galadon@<marketplace>
codex plugin add galadon@<marketplace>
工作区内 agent 会调用自带的 bin/galadon。如果要自己用 CLI,可以直接调插件目录里的 bin/galadon,或者安装它:
pip install <plugin-dir> # or: pipx install <plugin-dir>
依赖 Python 3.10+ 和 PyYAML。这些命令均来自插件 README 原文,安装时请把 <path-or-repo>、<marketplace>、<plugin-dir> 替换成实际路径或仓库名,不要凭名称自行拼接 github:owner/repo。
典型用法¶
初始化一个目录,再让 agent 推进循环:
galadon init --template api --role solo # 空目录;已有文件时用 --force
galadon next # 一次只给一个阶段的下一个动作
然后交给 agent:它读 galadon.yaml,做当前阶段,并反复跑 galadon check,直到循环到达 learn。默认 none layout 下第一个闸门是 spec:init 会写出一个满是 TODO 的 spec/spec.md 桩,于是 check 会报 “spec/spec.md still contains TODO”,直到你把它写完。init 也故意让 checks.build 和 checks.test 为空,所以 spec 完成后 check 会明确报 “no checks configured — declare checks.build/checks.test”,直到你声明真实命令。
常用完整命令:
galadon init --template web --role solo
galadon init --layout webapp --stack python --template web
galadon next
galadon check
galadon new
galadon bootstrap --env test
galadon ship --env test
galadon teardown --env test --yes
galadon init --list-layouts 会输出 stable text,列出可用 layouts 和 stacks。
ship 在没有真实探测的情况下不会报告成功;生产环境发布需要在当前会话里加 --yes-prod。
适用场景与注意¶
适合的场景:想让 agent 在一个工程里按固定阶段推进,同时要求每一步都有可检查的产物和闸门的项目。如果需要的是外部发布流程、CI 编排或团队协作权限体系,Galadon 只提供基础循环和两类 deploy adapter,覆盖不了这些。
运行时权限要注意:插件以当前 DSH 进程的权限运行。安装前应自行检查源码与许可证——其许可证信息以仓库和插件元数据为准,本次资料中 package.json 记为 MIT,仓库地址为 https://github.com/Lumos-789/galadon 。
安装命令不要凭插件名称自行拼接,优先使用 README 给出的命令和占位符。另外 bootstrap/ship 会在远程主机上写文件、重启服务,teardown --yes 会删目录,指向重要机器之前应先读一遍 README 的 Side effects 一节。
结尾¶
Galadon 的价值不在于它带了多少模板,而在于它把 agent 项目最缺的阶段边界和闸门固定了下来,其余能力留给 port 替换。目录页:https://www.skillhub.cn/plugins/Lumos-789/galadon ,仓库:https://github.com/Lumos-789/galadon 。