首先我们要分析清楚cc现有的几个处理信息的模式:
核心维度 | ReAct 隐式 plan | Plan → Do 显式 plan | Workflow 编排脚本 | /loop 定时轮询 | /goal 目标驱动 |
|---|
一句话理解 | 边想边做 | 先计划,再执行 | 用脚本编排多个 agent | 定时重复跑任务 | 给目标,自动跑到收敛 |
计划可见性 | 低,计划藏在模型内部 | 高,plan 可审查 | 最高,控制流写在脚本里 | 基本无计划 | 中低,目标明确但路径隐式 |
执行方式 | 单 agent 串行 | 单 agent 串行 | 多 agent 并行 / pipeline | 单 agent 周期执行 | 单 agent 持续尝试 |
用户参与度 | 低 | 高,需要看 plan / 改 plan | 中,前期写脚本,运行时少管 | 低,设好后巡逻 | 低,设目标后放手 |
最适合场景 | 小修小改、查 bug、局部问题 | 重构、新功能、高风险改动 | 批量 review、批量调研、多文件审计 | CI、PR、部署、网页状态监控 | 测试全过、lint 清零、任务收敛 |
主要风险 | 容易跑偏,事后才发现 | plan 质量决定上限 | 脚本错会批量错 | 轮询浪费 token / 漏状态 | 目标不清会死循环 |
成本与可控性 | 成本不可控,可控性低 | 成本较可控,可控性中高 | 成本最可控,可复用性最高 | 成本取决于轮询频率 | 成本最不确定 |
可见对于不同的任务,需要不同的agent infra去执行不同的任务,在生产环境中,很难有一套系统高效而且准确agent infra能解决所有的问题。
需求类型 | Weft 场景 | 推荐模式 |
|---|
明确、局部、低风险任务 | 用户问一个小问题、改一个局部文件 | ReAct |
复杂、多步、需要先确认方案 | 用户要新增复杂功能、重构模块 | Plan → Do |
大规模、批量、并行、可复用流程 | 批量调研、批量审计、多个 agent 并发入库 | Workflow |
需要持续观察状态变化 | 监听 PR / CI / 新文章 / 任务状态 | /loop |
有明确终点,但路径不确定 | 持续修到测试全过、持续优化到指标达标 | /goal |
我们可以用一套方式来组合起这五个应用:
/loop 做定时哨兵 → 发现任务后交给 /goal 驱动整体进度
/goal 内部按任务复杂度分派给 React(简单)、Workflow(批量)或 Plan(复杂)
这就是 loop engineering 的核心——人定义顶层循环结构,Claude 在循环内自主执行。
由此我们可以毫不犹豫的设计出来一种框架:
flowchart LR
U[用户 prompt] --> CLS["阶段①\nLLM 读 prompt\n选执行模式"]
CLS --> |"mode: react"| R[直接回答]
CLS --> |"mode: goal+react"| GR[CC /goal 驱动]
CLS --> |"mode: goal+workflow"| GW[CC workflow 批量]
CLS --> |"mode: loop+goal"| LG[CC /loop 持续]
CLS --> |"mode: plan→do"| PD[CC plan 模式]这种控制面和执行面分离的思考非常常见,但是也带来了一个问题,就是这个控制面,是给Weft系统来控制呢,还是在CC中进行控制呢?
考虑到后续可能会对接别的agent,那么这个控制模式的选择,还是要放到Weft中,这里就定下来一个准则:Weft 决定怎么做,agent 只管执行
Weft和CC的系统设计
开门见山的说,整体的设计方案如下:
flowchart TB
subgraph "Weft 进程"
CHAT[Chat Loop]
CLS[意图分类器 L1]
MAP[模式映射 L2]
DISPATCH[执行分发 L3]
MCP_S["MCP Server\n(stdio)"]
DB[(SQLite)]
PATCH[sendPatch]
end
subgraph "CC 进程(执行面)"
CC_LOOP[CC Agent Loop]
CC_WF[CC Workflow Engine]
CC_GOAL[CC /goal]
CC_CRON[CC /loop]
MCP_C[MCP Client]
end
subgraph "GUI"
CHAT_UI[聊天面板]
TASK_UI[任务面板]
CANVAS[Canvas]
end
CHAT_UI -->|用户 prompt| CLS
CLS -->|"chat"| CHAT
CLS -->|"非 chat"| MAP --> DISPATCH
DISPATCH -->|"控制通道\nspawn 进程"| CC_LOOP
DISPATCH -->|"控制通道"| CC_WF
DISPATCH -->|"控制通道"| CC_GOAL
DISPATCH -->|"控制通道"| CC_CRON
CC_LOOP --> MCP_C
CC_WF --> MCP_C
CC_GOAL --> MCP_C
CC_CRON --> MCP_C
MCP_C -->|"数据通道\nMCP 协议"| MCP_S
MCP_S --> DB
CHAT --> DB
DB --> PATCH
PATCH --> CANVAS
PATCH --> TASK_UI
CHAT -->|流式文本| CHAT_UI两条通道职责明确
GUI 只监听 sendPatch,不关心数据来自 Weft Loop 还是 CC。当然这里可以用别的消息机制:
方案 | 核心优势 | 核心短板 | 最适合场景 |
|---|
MCP | CC 原生支持、工具自发现 | 同步模型,难做推送和长任务进度 | LLM 调用工具、读写数据 |
消息队列 | 异步、并发、进度、事件驱动都强 | 集成成本和协议设计成本高 | 任务系统、多 worker、长任务 |
HTTP REST | 简单、通用、Weft 侧成本低 | 推送和并发调度要额外设计 | CRUD、简单同步 API |
文件监听 | 最轻量、原型快、天然异步 | 协议弱、可靠性和并发要自建 | 本地原型、低耦合事件通知 |
为什么要选MCP呢,这里存在一个问题:CC 在执行任务时,如何读取 Weft 的数据,又如何把结果写回 Weft?
比如 CC 正在执行一个「批量调研 React Server Components」的 workflow,它可能需要:
读取已有 topic spec
读取历史 materials
搜索 Weft 内部知识库
写入新的 material
更新某个 research task 的状态
把整理好的 evidence 写入 SQLite
这类操作,本质上是 agent loop 中的工具调用。
所以 MCP 在这里非常合适。
因为在 CC 看来,Weft MCP Server 暴露出来的能力就是一组 tools:
search_materials()
get_topic_spec()
ingest_material()
update_task_status()
write_evidence()
CC 不需要知道 Weft 内部是 SQLite、Postgres、文件系统,还是向量库。它只需要调 MCP tool。