Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 35 additions & 197 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,211 +32,49 @@

### 架构一览

code-bee 采用 **四层分层架构**:CLI 入口 → pipeline 薄封装 → runtime 核心引擎 → schema 配置定义。调度策略完全由 `workflow.yaml` 驱动,runtime.Engine 遍历 Pipeline 并按终止语义决定提前返回或继续。

#### 分层组件架构

```mermaid
flowchart TB
subgraph CLI["cmd/worker · CLI 入口"]
main["main() → runCLI()"]
build["buildService()<br/>parseExtraFlags + loadWorkflow"]
report["reportDispatchResult()<br/>Result → 退出码"]
end

subgraph Schema["internal/schema · 配置定义"]
loader["Loader<br/>YAML + 三层 JSON Schema 校验"]
types["Workflow / Tool / Stage<br/>Loop / Condition / LoopJudge"]
end

subgraph Pipe["internal/pipeline · 薄封装层"]
svc["Service<br/>持有 *Engine + *Workflow"]
arts["ArtifactSet<br/>文件契约目录"]
adapt["ArtifactResolverAdapter<br/>ArtifactSet ⇄ ArtifactResolver"]
contracts["contracts.go<br/>typed result loaders"]
end

subgraph RT["internal/runtime · 核心引擎"]
eng["Engine<br/>遍历 Pipeline + 终止语义"]
reg["ToolRegistry<br/>name/alias → Tool"]
pb["PromptBuilder<br/>embed 内置 + overlay 外部"]
ec["ExecutionContext<br/>stages map + loopStack"]
se["StageExecutor"]
pe["ParallelExecutor<br/>fork-join 写隔离"]
le["LoopExecutor<br/>max_iter / exit_when / judge"]
at["AgentTool<br/>render + runner.Run"]
ct["CommandTool<br/>exec.CommandContext"]
ft["FunctionTool (桩)"]
arIface["«interface»<br/>ArtifactResolver"]
runnerIface["«interface»<br/>Runner"]
end

subgraph Ext["外部依赖"]
agentRunner["agent.Runner<br/>Reasonix × DeepSeek"]
platformClient["platform.Client<br/>GitHub"]
end

main --> build
build -->|"加载 workflow"| loader
loader --> types
build --> svc
main -->|"Dispatch(ctx, cfg)"| svc
platformClient --> svc
svc --> eng
svc --> arts
arts --> adapt
eng --> ec
eng --> se
eng --> pe
eng --> le
se --> reg
reg --> at
reg --> ct
reg --> ft
at --> pb
at --> runnerIface
runnerIface -.->|"实现"| agentRunner
at -->|"LoadResult"| arIface
arIface -.->|"实现"| adapt
adapt --> contracts
svc -->|"EngineResult → Result"| report
```
code-bee 现在不再强调“把系统讲成一张大架构图”,而是强调两个更重要的判断:它到底在做什么,以及它为什么要保持薄。

**分层职责**:
#### 核心思想

| 层 | 包 | 职责 |
|----|----|------|
| CLI | `cmd/worker` | flag 解析、workflow 加载、构造 Service、退出码映射 |
| pipeline | `internal/pipeline` | 薄封装层:持有 Engine、管理文件契约目录、typed 结果校验 |
| runtime | `internal/runtime` | 核心引擎:编排原语执行器、工具注册表、prompt 渲染、上下文管理 |
| schema | `internal/schema` | 配置定义:YAML 加载 + 三层 JSON Schema 语义校验 |

**关键解耦**:runtime 包通过 `ArtifactResolver` 和 `Runner` 两个接口与外部解耦——pipeline 层用 `ArtifactResolverAdapter` 桥接文件契约,CLI 注入真实的 `agent.Runner` 实现。runtime 不依赖 pipeline(避免循环依赖)。

#### Dispatch 调用链路

下图展示单次 `Dispatch` 从 CLI 到智能体执行的完整调用链,含结果文件读写时序:

```mermaid
sequenceDiagram
participant CLI as runCLI
participant Svc as Service.Dispatch
participant Eng as Engine.Run
participant SE as StageExecutor
participant Tool as AgentTool
participant PB as PromptBuilder
participant Runner as agent.Runner
participant AR as ArtifactResolver
participant FS as 文件系统

CLI->>Svc: Dispatch(ctx, cfg)
Svc->>Svc: 创建 ArtifactSet + PlatformContext
Svc->>Svc: 包装 ArtifactResolverAdapter
Svc->>Eng: Run(deps{Artifacts, Platform, Config})
Eng->>Eng: NewExecutionContext
loop 遍历 workflow.Pipeline
Eng->>SE: Execute(step, ec)
SE->>SE: 求值 when 条件
SE->>SE: registry.Resolve(tool)
SE->>AR: ResolveResultFile(stageName)
AR-->>SE: resultFilePath
SE->>FS: ResetResultFile(删除旧文件)
SE->>SE: ec.Lookup(input_from)
SE->>Tool: Execute(Invocation)
Tool->>PB: Build(promptTemplate, data)
PB-->>Tool: rendered prompt
Tool->>Runner: Run(ctx, kind, prompt)
Runner-->>Tool: RunResult{Output}
Tool->>AR: LoadResult(stageName, path)
AR->>FS: 读取结果文件
AR-->>Tool: map[string]any
Tool->>Tool: extractStatus → StepResult
Tool-->>SE: StepResult
SE->>SE: ec.SetResult
SE-->>Eng: StepResult
alt Blocked / ManualRequired / Completed
Eng-->>Svc: 提前返回 EngineResult
end
end
Eng-->>Svc: EngineResult
Svc-->>CLI: pipeline.Result
```
![code-bee 核心思想](docs/images/readme/03-orchestrator-not-runtime.png)

**关键时序点**:
1. **StageExecutor 先 reset 结果文件**——防止读到上一轮残留数据
2. **AgentTool 渲染 prompt 后才调 runner**——prompt 数据由 `buildPromptData` 从 ExecutionContext 派生
3. **结果文件是 stage 间通信媒介**——`ec.SetResult` 存内存快照供 `when`/`exit_when` 求值,`LoadResult` 读磁盘文件做 typed 校验
4. **终止语义即时生效**——任一 stage 返回 `Blocked`/`ManualRequired`/`Completed`,Engine 立即跳出 Pipeline 循环返回

#### 配置加载与数据流

下图展示 workflow + prompt 模板的加载链,以及结果文件在 stage 间的流转:

```mermaid
flowchart LR
subgraph 配置加载["配置加载(启动时一次性)"]
direction TB
embedWf["default_workflow.yaml<br/>(go:embed)"]
extWf["--workflow xxx.yaml"]
loader["schema.Loader<br/>YAML + Schema 校验"]
wf["*schema.Workflow"]

embedP["prompts/*.md<br/>(go:embed, 5 个内置)"]
extP["--prompts-dir ./dir/"]
pb["PromptBuilder<br/>overlay 同名覆盖"]
templates["templates map"]

embedWf --> loader
extWf --> loader
loader --> wf
embedP --> pb
extP --> pb
pb --> templates
end

subgraph 运行时["运行时数据流(Dispatch 时)"]
direction TB
cfg["Config<br/>Repo/Issue"]
arts["ArtifactSet<br/>.code-bee/runs/repo/issue-N/"]
ec["ExecutionContext<br/>stages map"]

s1["stage: issue-handling<br/>→ issue_intake_result.json"]
s2["stage: coding<br/>→ coding_result.json"]
s3["stage: review<br/>→ review_result.json"]

cfg --> arts
s1 -->|"写入"| arts
arts -->|"读取"| ec
ec -->|"input_from"| s2
s2 -->|"写入"| arts
arts -->|"读取"| ec
ec -->|"input_from"| s3
s3 -->|"写入"| arts
end

wf --> ec
templates -->|"渲染 prompt"| s1
templates -->|"渲染 prompt"| s2
templates -->|"渲染 prompt"| s3
```
- **核心定位**:code-bee 是一个编排台,不是一个臃肿的编码运行时平台。
- **输入输出**:左边接住 GitHub Issue 里的 `@agent` 任务,右边只关心 PR、Issue 回复和状态结果是否闭环。
- **边界原则**:真正写代码、做审查、跑执行流程的是外部智能体与外部环境;code-bee 只负责路由、约束、校验和收口。
- **设计取舍**:宁可保持一个薄内核,也不在调度器内部堆一大堆工具能力和业务执行逻辑。

#### 设计思想

**配置加载语义**:
- **workflow 双源**:`go:embed` 内置 `default_workflow.yaml` 作为兜底,`--workflow` 指定外部 YAML 完全替换(非 overlay)
- **prompt overlay**:内置 5 个模板(issue-handling/coding/review/issue-post/loop-judge),`--prompts-dir` 目录下同名 `.md` 文件**覆盖**内置,未覆盖的仍用内置(用户只需写想改的)
- **结果文件流转**:每个 stage 把结构化 JSON 写入 ArtifactSet 目录,下游 stage 通过 `input_from` 经 ExecutionContext 读取,`when`/`exit_when` 条件也基于这些字段求值
![workflow 驱动设计](docs/images/readme/04-workflow-driven-thin-kernel.png)

#### Engine 终止语义
- **workflow 驱动**:调度策略由 `workflow.yaml` 决定,而不是把流程写死在代码里。
- **薄内核原语**:内核只保留 `stage / parallel / loop` 这些必要原语,用最小集合表达编排能力。
- **结果回流**:每个阶段的结构化结果会落到文件契约目录,再回流给下一阶段判断,形成可追踪的状态闭环。
- **解耦实现**:CLI 负责入口,`pipeline` 负责薄封装和结果适配,`runtime` 负责执行原语,`schema` 负责加载和校验 workflow。

Engine 遍历 Pipeline 时,根据 `StepResult` 的状态字段决定是否提前返回:
#### 责任边界

![结果闭环与责任边界](docs/images/readme/05-result-loop-and-boundary.png)

- **外部负责执行**:真正的编码、审查与环境操作由外部智能体完成,code-bee 不替代这些执行者。
- **内核负责收口**:code-bee 只在结果闸门口做状态判断、结果校验与后续分流,不把业务执行硬塞进内核。
- **闭环优先**:无论阶段结果是继续、阻塞还是完成,最终都要回到统一的 PR / Issue 回复闭环中。

#### 技术收口

| 层 | 包 | 职责 |
|----|----|------|
| CLI | `backend/cmd/worker` | flag 解析、workflow 加载、退出码映射 |
| pipeline | `backend/internal/pipeline` | 文件契约、结果校验、ArtifactResolver 适配 |
| runtime | `backend/internal/runtime` | 编排原语执行、prompt 渲染、上下文与终止语义 |
| schema | `backend/internal/schema` | YAML 加载、Schema 校验、workflow 结构定义 |

| StepResult 字段 | Engine 行为 | EngineResult |
|----------------|------------|--------------|
| `Blocked = true` | 立即终止 | `{Success: true, Blocked: true}` |
| `ManualRequired = true` | 立即终止 | `{Success: true, ManualRequired: true}` |
| `Completed = true` | 立即终止 | `{Success: true, Completed: true}` |
| Pipeline 走完无终止 | 正常结束 | `{Success: true, Completed: true}` |
**更多细节**:

> ⚠️ **已知缺口**:Engine 遇 `Blocked` 立即终止,导致 `issue-post-blocked` 阶段(阻塞评论提交)无法运行。后续计划通过 `on_blocked: continue` 增强恢复该阶段。
- [Schema 定义](backend/internal/schema/schemas/v1/README.md) —— workflow 的结构与校验规范
- [默认 workflow](backend/internal/runtime/default_workflow.yaml) —— 内置调度配置参考
- [Prompt 模板](backend/internal/runtime/prompts/) —— 默认提示词模板
- [YAML 编辑器文档](docs/design/orchestration-yaml-schema-from-source.md) —— 编排 YAML 的来源与结构说明

---

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
theme: "编排台而非运行时平台"
character_variant: "教研机制版小黑"
character_variant_prompt: "Use 教研机制版小黑 as the default Xiaohei variant. Keep the same solid-black body and white dot eyes, but make the silhouette more steady, restrained, and authoritative. Give the head a clear abstract hair silhouette: full, swept back, slightly wavy on the outer edge, with some side volume. The character must not look bald. Use one fixed simplified Zhongshan-suit-like outer contour with the same stand collar, front placket, and overall clothing silhouette every time this character appears. In the same image, the character's hair shape, body proportions, and clothing outline must stay identical; only pose, gesture, viewing direction, and props may change. Use a straight standing posture, calm expression, and decisive gestures such as hands behind back, pointing the direction, reviewing papers, or making a judgment at a desk. This is not a realistic portrait of any historical person. It is an abstract, minimalist, teacher-like leadership aura inside the existing Xiaohei visual system."
appearance_lock: "同一张图里的教研机制版小黑必须保持同样的发型轮廓、头身比例和立领服装轮廓,只允许动作、手势、姿态、朝向和道具变化。"
character_reference_image: ""
scene_reference_image: ""
structure_type: "概念隐喻"
core_idea: "code-bee 只负责把 Issue 里的任务分发给外部智能体,并把结果收口为 PR 和回复,而不是自己长成一个庞大的运行时平台。"
composition: "左侧是一张简化的 GitHub Issue 任务卡,带有 @agent 标记;中间是一张很薄的分发台,教研机制版小黑站在台后认真分拣任务卡片并拨动一个小路由杆;右侧是两个外部执行工位,一个工位在敲代码,另一个工位吐出 PR 回执和 Issue 回复。画面左到右是清晰主流向,台子明显比右侧执行工位更薄、更克制。左下角放一个被闲置的大工具箱,暗示“不把一切都塞进内核里”。不要在左上角写任何标题。"
suggested_elements:
- "Issue任务卡"
- "薄分发台"
- "外部执行工位"
- "回执纸条"
labels:
- "@agent"
- "分发"
- "外部执行"
- "PR"
- "回复"
warning_or_feedback: "红色提醒:不要做大平台"
size_profile: "正文横图"
model: "z-image-turbo"
size: "1440*810"
prompt_extend: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Generate one standalone 16:9 horizontal Chinese article illustration.

Visual DNA:
Pure white background. Minimalist black hand-drawn line art. Slightly wobbly pen lines. Lots of empty white space. Sparse red/orange/blue handwritten Chinese annotations. Clean absurd product-sketch feeling. No gradients, no shadows, no paper texture, no complex background, no commercial vector style, no PPT infographic look, no cute mascot poster, no children's illustration, no realistic UI.

Recurring IP character required:
小黑, a small solid-black absurd creature with white dot eyes, tiny thin legs, blank serious expression, slightly uneven hand-drawn body shape. 小黑 must perform the core conceptual action, not decorate the scene. Make 小黑 serious, deadpan, and slightly bizarre, not cute.

Character variant override:
Use 教研机制版小黑 as the default Xiaohei variant. Keep the same solid-black body and white dot eyes, but make the silhouette more steady, restrained, and authoritative. Give the head a clear abstract hair silhouette: full, swept back, slightly wavy on the outer edge, with some side volume. The character must not look bald. Use one fixed simplified Zhongshan-suit-like outer contour with the same stand collar, front placket, and overall clothing silhouette every time this character appears. In the same image, the character's hair shape, body proportions, and clothing outline must stay identical; only pose, gesture, viewing direction, and props may change. Use a straight standing posture, calm expression, and decisive gestures such as hands behind back, pointing the direction, reviewing papers, or making a judgment at a desk. This is not a realistic portrait of any historical person. It is an abstract, minimalist, teacher-like leadership aura inside the existing Xiaohei visual system.

Appearance lock:
同一张图里的教研机制版小黑必须保持同样的发型轮廓、头身比例和立领服装轮廓,只允许动作、手势、姿态、朝向和道具变化。

Theme:
编排台而非运行时平台

Structure type:
概念隐喻

Core idea:
code-bee 只负责把 Issue 里的任务分发给外部智能体,并把结果收口为 PR 和回复,而不是自己长成一个庞大的运行时平台。

Composition:
左侧是一张简化的 GitHub Issue 任务卡,带有 @agent 标记;中间是一张很薄的分发台,教研机制版小黑站在台后认真分拣任务卡片并拨动一个小路由杆;右侧是两个外部执行工位,一个工位在敲代码,另一个工位吐出 PR 回执和 Issue 回复。画面左到右是清晰主流向,台子明显比右侧执行工位更薄、更克制。左下角放一个被闲置的大工具箱,暗示“不把一切都塞进内核里”。不要在左上角写任何标题。

Suggested elements:
Issue任务卡 / 薄分发台 / 外部执行工位 / 回执纸条

Chinese handwritten labels:
@agent / 分发 / 外部执行 / PR / 回复

Color use:
Black for main line art and 小黑. Orange for main flow/path/arrows. Red only for key warnings/problems/results. Blue only for secondary notes or feedback/system state.

Constraints:
One image explains only one core structure. Keep the main subject around 40%-60% of the canvas. Preserve at least 35% blank white space. Use at most 5-8 short handwritten Chinese labels. Do not write a title in the top-left corner. Do not write the structure type on the image. Do not make it a formal diagram, course slide, or dense explainer. Do not copy prior examples or reuse known case compositions unless explicitly requested; invent a fresh visual metaphor for this specific article. It should be clear but not instructional, interesting but not childish, strange but clean.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
theme: "workflow 驱动薄内核"
character_variant: "教研机制版小黑"
character_variant_prompt: "Use 教研机制版小黑 as the default Xiaohei variant. Keep the same solid-black body and white dot eyes, but make the silhouette more steady, restrained, and authoritative. Give the head a clear abstract hair silhouette: full, swept back, slightly wavy on the outer edge, with some side volume. The character must not look bald. Use one fixed simplified Zhongshan-suit-like outer contour with the same stand collar, front placket, and overall clothing silhouette every time this character appears. In the same image, the character's hair shape, body proportions, and clothing outline must stay identical; only pose, gesture, viewing direction, and props may change. Use a straight standing posture, calm expression, and decisive gestures such as hands behind back, pointing the direction, reviewing papers, or making a judgment at a desk. This is not a realistic portrait of any historical person. It is an abstract, minimalist, teacher-like leadership aura inside the existing Xiaohei visual system."
appearance_lock: "同一张图里的教研机制版小黑必须保持同样的发型轮廓、头身比例和立领服装轮廓,只允许动作、手势、姿态、朝向和道具变化。"
character_reference_image: ""
scene_reference_image: ""
structure_type: "Workflow"
core_idea: "code-bee 的调度不是硬编码死流程,而是由 workflow 配置驱动一个很薄的内核,只保留最必要的编排原语。"
composition: "左侧是一卷写着 workflow 的纸带缓缓进入一台低科技细长机器;机器上只有三个小拨片或小闸位,教研机制版小黑站在机器上认真拉动其中一个拨片,表现少量原语驱动整体流程。机器右侧吐出一张执行纸条,底部有橙色箭头继续向前。整张图强调纸带驱动的小机器,不是复杂架构图,也不要堆太多模块盒子。不要在左上角写任何标题。"
suggested_elements:
- "workflow纸带"
- "细长机器"
- "小拨片"
- "执行纸条"
labels:
- "workflow"
- "stage"
- "parallel"
- "loop"
- "执行"
warning_or_feedback: "蓝色反馈:配置驱动"
size_profile: "正文横图"
model: "z-image-turbo"
size: "1440*810"
prompt_extend: false
Loading
Loading