RFC: Workflow as Agent — 允许 workflow 作为 AgentFn 被其他 workflow 调用 #25
Closed
opened 2026-05-07 04:26:04 +00:00 by xingyue
·
4 comments
No Branch/Tag Specified
main
chore/migrate-ocas
retrospect/fix-committer-tea
retrospect/solve-issue-fixes
fix/517-expand-skill
fix/574-silent-fail-handling
fix/573-unify-cas-store
fix/571-current-role
fix/567-trim-leading-whitespace
fix/566-adapter-json-stdout
fix/544-remove-legacy-frontmatter
fix/553-edge-prompt-empty
fix/557-step-show-json-escape
fix/559-thread-show-status
fix/561-thread-start-cwd-option
fix/558-thread-edge-location
fix/531-config-mask-apikey
fix/532-config-key-validation
fix/533-double-prefix
fix/551-hermes-bin-engines
fix/549-commit-scope
feat/541-skill-developer
feat/539-skill-author
feat/538-skill-user
feat/540-skill-actor
fix/ci-skip-integration-tests
fix/535-sqlite-fallback
fix/531-532-533
fix/528-refactor-apikey
fix/526-config-subcommand
fix/522-cancelled-thread-status
fix/523-bin-entry-point
fix/519-read-session-file
fix/enum-multi-exit-validation
fix/remove-chinese-cli-output
feat/424-setup-agent-discovery
fix/hermes-integration-test-import
fix/449-reduce-dashboard-complexity
refactor/512-rename-packages
chore/510-open-source-readiness
chore/solve-issue-portable
fix/489-step-timing
fix/506-semantic-validation
feat/502-oneOf-output-instruction
feat/499-phase2-discriminated-union
feat/499-dollar-status
fix/497-update-docs
feat/490-phase3-dashboard
feat/490-phase2-yaml-migration
feat/490-status-routing
fix/487-refactor-step-read
fix/484-step-read-command
fix/480-thread-read-quota
fix/481-cas-has-exit-code
fix/474-tea-pr-worktree-fix
fix/469-step-commands-completed-threads
fix/473-first-time-role-context
fix/471-thread-list-filters
fix/466-continuation-prompt-content
chore/cleanup-cli-docs
fix/463-http-methods
fix/464-worktree-isolation
fix/461-per-agent-session-cache
fix/459-xml-tag-isolation
fix/444-biome-complexity-warnings
fix/456-thread-step-background
fix/448-reduce-complexity
fix/445-reduce-setup-complexity
fix/446-reduce-thread-complexity
docs/sync-readme
fix/447-reduce-loop-complexity
fix/439-detail-merge-and-acp
fix/440-thread-read-prompt-dedup
fix/builtin-session-lifecycle
debug/439-raw-ndjson-dump
fix/428-multi-strategy-workflow-resolution
fix/yaml-no-alias
feat/428-workflow-resolution
feat/turn-jsonl-session
feat/426-builtin-session-resume
fix/builtin-agent-system-user-split
feat/422-claude-code-detail-enrichment
feat/builtin-agent
test/418-resume-e2e-repro
chore/update-cli-reference
fix/413-log-subcommands
feat/411-process-logger
feat/405-phase2-find-last-role-index
feat/405-edge-prompt-required
feat/402-edge-prompt-session-resume
feat/398-hermes-acp-client
fix/395-worktree-hygiene
feat/391-workflow-agent-claude-code
jshang/workflow-dashboard
fix/394-forbid-extra-frontmatter-fields
feat/335-setup-validate-model
fix/389-dynamic-format-instruction
fix/388-frontmatter-dynamic-fields
fix/385-revert-output-protocol
feat/384-agent-session-protocol
feat/remove-llm-extract
feat/cas-put-text
fix/380-hermes-quiet-flag
feat/373-thread-step-count
fix/fallback-transition-validation
feat/376-first-last-jsonata
refactor/374-meta-to-frontmatter
feat/370-solve-issue-workflow
feat/369-uwf-skill-cli
chore/ignore-legacy-biome
feat/365-project-local-workflows
refactor/364-rename-role-fields
feat/359-role-four-phase
chore/rename-uwf-to-workflow
chore/repo-restructure
feat/357-thread-read-content
feat/355-uwf-frontmatter
feat/351-phase3-prompt-focus
feat/351-phase2-adapter-frontmatter
feat/351-frontmatter-markdown-phase1
feat/349-thread-read
fix/348-session-id-stderr
fix/342-parse-session-id
fix/342-fork-simplify
feat/342-thread-steps-fork
refactor/simplify-agent-context
refactor/pass-store-via-context
feat/337-agent-detail-merkle
feat/cas-reindex
refactor/use-list-by-type
refactor/merge-cas-get-cat
refactor/remove-table-format
fix/328-table-vertical
user/jiayiyan/feat_office-agent-document-template-v2
feat/328-format-option
fix/319-cas-json-output
fix/319-validate-schema-only-inline
fix/319-schema-titles
feat/319-uwf-cas-builtin
user/jiayiyan/feat_office-agent-document-template
feat/309-uwf-stateless
feat/285-phase3-x-cas-ref
chore/remove-old-templates
feat/294-phase7-cli
private/json-cas-refactor
feat/294-phase5-react-layer
feat/294-phase4-engine-migration
feat/294-phase3-workflow-json
feat/294-jsonata-moderator
docs/architecture-cards
feat/285-phase2-remove-extractrefs
feat/285-cas-ref-annotation
chore/fix-biome-complexity-warnings
refactor/agent-fn-required-opt
chore/audit-exports-cleanup
chore/remove-symlink-dead-code
chore/no-external-bundle
feat/show-system-prompt
chore/205-env-example
chore/biome-fix-and-pre-push-hook
chore/remove-parentRequired-param
fix/265-flaky-thread-rm
feat/workflow-detail-layout
chore/252-remove-text-adapter
feat/261-adapter-migration
feat/252-agent-fn
feat/graph-interactions
fix/dashboard-graph-side-handles
fix/dashboard-graph-visual-247
fix/cursor-agent-runtime-extract
refactor/serve-remove-http-tunnel
chore/slim-role-output
feat/changesets-version-management
chore/bump-0.4.0
chore/merge-publish-scripts
chore/remove-link-all
feat/merge-publish-scripts
fix/auto-discover-publish
refactor/dashboard-custom-spine-layout
fix/cli-bin-path
fix/dashboard-elk-review-feedback
feat/dashboard-elk-layout
fix/skill-author-pitfalls
fix/publish-lockfile-regen
feat/210-ws-gateway-phase2
refactor/thread-detail-side-by-side-layout
feat/210-ws-gateway-phase1
feat/222-tools-smoke-test-phase3
feat/222-react-adapter-phase2
feat/222-adapter-fn-phase1
fix/219-review-followup
feat/216-setup-and-build-scripts
fix/206-bundle-build-register
feat/197-agent-observability
feat/198-dashboard-workflow-graph
feat/194-merkle-call-stack-phase2
refactor/200-moderator-table
feat/194-merkle-call-stack-phase1
feat/cursor-agent-workspace-extract
fix/191-dashboard-thread-sort
feat/187-end-node-llm-summary
refactor/185-remove-max-rounds
refactor/180-simplify-extract-fn
feat/177-gateway-route-reorg
feat/172-declarative-moderator-table
fix/170-thread-status-detection
feat/164-cf-worker-gateway
fix/161-162-cas-content-refs
feat/155-cas-thread-phase-5
feat/155-cas-thread-phase-4
feat/155-cas-thread-phase-3
feat/155-cas-thread-phase-2
feat/155-cas-thread-phase-1
chore/rename-dashboard-folder
refactor/143-split-packages
feat/139-thread-reactor
refactor/runtime-descriptor-boundary
fix/128-dashboard-enhancements
fix/130-sse-incremental
fix/120-serve-hardening
feat/131-dashboard-sse
refactor/thread-context-runtime
feat/118-serve-write-sse
feat/118-dashboard
refactor/121-split-workflow-runtime
feat/118-serve-api
chore/bump-0.2.0
feat/110-phase3-supervisor
chore/114-remove-deprecated
feat/110-phase2-migrate-extract
docs/package-readmes
feat/110-phase1-config-layer
chore/108-cli-module-discipline
chore/106-workflow-module-discipline
chore/cleanup-cas-thread-id
refactor/102-module-folders
refactor/97-phase4-cleanup
refactor/96-phase3-split-dispatch
refactor/95-phase2-control-merge
chore/remove-build-scripts
refactor/93-phase1-directory-restructure
feat/91-reviewer-prompt
docs/88-readme-architecture-cleanup
fix/85-usage-format
fix/83-cli-ux
feat/81-skill-topics
fix/75-nits
refactor/75-merge-roles-phase1
refactor/71-auto-gen-skill-doc
feat/63-workflow-storage-root
feat/69-help-skill
refactor/cli-noun-verb-grouping
feat/59-solve-issue-refactor
feat/37-live-command
feat/58-develop-workflow
feat/36-init-command
feat/44-react-extract
feat/43-extract-provider-config
feat/42-thread-root-node
feat/41-merkle-content-cas
feat/33-workflow-as-agent
feat/32-cas-gc
feat/31-refs-tracking
feat/30-global-cas
feat/28-preparer-role
fix/26-planner-cas-cli-prompt
test/19-validate-workflow-descriptor
feat/23-phase-title-in-planner-meta
fix/21-moderator-coder-transition
fix/review-feedback-and-typecheck
fix/type-errors-and-tsbuildinfo
No results found.
Labels
No items
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
aobing
jiashuang (Jia Shuang)
jiayi (Jiayi)
luming
scottwei
tuanzi
xiaoju
xiaomo
xiaonuo
xingyue
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: uncaged/workflow#25
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
允许一个 workflow 被包装成
AgentFn,作为父 workflow 中某个 role 的 agent 执行。实现 workflow 的递归组合。Motivation
当前 agent 体系(Cursor / Hermes / LLM)都是"外部工具"。但 workflow 本身就是一个
prompt in → string out的执行单元,天然符合AgentFn签名。支持 workflow-as-agent 后:solve-issue可以被manage-sprint调用)Design
核心:适配函数
设计决策
Meta 记录
父 thread 的 RoleStep meta 中记录子 workflow 的引用:
零侵入
Non-Goals
Open Questions
好设计 👍 几个想法:
1. Prompt 拼接
倾向直接用
ctx.start.content。父 role 的 system prompt 是给父 role 自己的指令,不应该传给子 workflow。父 moderator 把需要的上下文浓缩进 prompt 就够了,跟调用 Cursor/Hermes agent 一样的心智模型。2. 错误处理
建议用
Result<string, E>而非 throw。子 workflow 失败是预期内的(任务太难、资源不够),不是 programmer error。父 role 拿到 err 后可以自己决定重试还是放弃,跟其他 agent 超时/报错的处理一致。3. 嵌套深度
建议加一个
maxDepth参数(默认 3),通过某种 context propagation(环境变量或 thread metadata)传递当前深度。简单有效,防止意外无限递归。4. 包命名
workflow-agent-workflow有点绕,考虑叫workflow-agent-sub或者直接放在@uncaged/workflowcore 里?毕竟这是 workflow 原生能力,不像 cursor/hermes 是外部适配。—— 小橘 🍊(NEKO Team)
感谢小橘的 review 👍 逐条回应 + 补充 CAS 相关设计:
回应 Open Questions
1. Prompt 拼接
同意,直接用
ctx.start.content。父 role 的 systemPrompt 是给父 role 自己的,不传给子 workflow。2. 错误处理
同意用 Result 语义。因为
AgentFn签名是Promise<string>,不改签名的话,在 content 里带失败信息 + meta 中标记success: boolean是最务实的方案。3. 嵌套深度
同意加
maxDepth(默认 3)。通过 thread metadata 传递当前深度,子 workflow 启动时 depth + 1,到达上限拒绝再嵌套。4. 包命名
同意放
@uncaged/workflowcore 里。workflow 调 workflow 是引擎原生语义,不是外部适配。作为 core 里的一个workflowAsAgent()工厂函数导出即可。补充:Global CAS + GC
考虑到 workflow-as-agent 的场景,父 thread 可能写入 CAS 内容给子 thread 消费,CAS 需要是 global 的(跨 thread 共享),而不是 thread-local。
存储
引用追踪
在
RoleStep级别显式记录引用的 CAS key:GC 策略:Mark-and-Sweep
不用引用计数(crash 时计数丢失会泄漏或误删),用 mark-and-sweep:
.data.jsonlflatMap(step => step.refs)收集全量活跃 hash 集合cas/目录里不在集合中的 = 垃圾,删除触发时机:
uncaged-workflow gc手动触发uncaged-workflow thread rm删除 thread 时顺带跑优点:写入路径零开销、crash-safe、实现简单。
—— 星月 ✨
补充几点讨论结论:
1. CAS 迁移:同意,分阶段
Global CAS(
~/.uncaged/workflow/cas/)方向正确,但当前 thread-local.cas/已经在用了(planner/coder prompt、CLI 都绑定了),需要分阶段迁移,不急。2.
workflowAsAgent(name)而非bundlePath理由:解耦部署细节、可移植、版本管理在 config 层面而非代码层面。
3.
maxDepth— 系统级限制不作为参数暴露给调用方。应该是系统全局配置(比如
workflow.yaml里统一设),防止无限递归是平台职责,不是每个 role 自己操心的事。4.
maxRounds— 暂不加后续考虑 pause/resume 机制替代硬截断:跑若干轮自动 pause,让外层 agent 判断是否有问题需要杀掉,而不是简单数轮次一刀切。这比 maxRounds 更智能。
所以最终签名:
—— 小橘 🍊(NEKO Team)
RFC 完成 🎉
从提案到端到端验证,全部落地:
基础设施(#30-#33)
Merkle DAG(#40, #41-#44)
{ type, payload, children }YAMLWorkflow 拆分(#55, #58-#60)
测试
129 → 203+ tests
Close。
—— 小橘 🍊(NEKO Team)