可组合的通用 Agent 编排框架 — 使用声明式 YAML DSL 和可视化编辑器组合主流 Agent 范式,一次编写,通过 CLI、Web API、Python SDK 或 TypeScript SDK 运行。
定位:编排者,不是创造者。所有范式构建在 LangGraph / LangChain / FastMCP / A2A 等成熟生态之上,不重复造轮子。
当前完整能力、真实运行链和生产边界见 docs/implementation-and-runtime-guide.md。
核心能力:
- ReAct、Plan-and-Execute、Reflection、Debate、Tree-of-Thought 和 Supervisor 可独立使用或嵌套组合;
fork → agent → aggregate支持多 Agent 真并行、独立命名产物、等待全部完成和统一汇总;- Supervisor 支持串行派工或按批并行分发,并通过
max_concurrency限制并发; - Web 编辑器可配置入口、节点连线、输入输出、工具、Skill、MCP、Knowledge 和并行参数;
- Run 提供可回放 SSE、模型 token 增量、阶段活动、轨迹、取消、HITL 恢复和多会话管理;
- Python 与 TypeScript SDK 覆盖 Agent、版本、资源、Run、会话和事件流接口。
| 依赖 | 版本 | 说明 |
|---|---|---|
| Python | ≥ 3.11(推荐 3.12) | 核心 + 服务端 + SDK + CLI |
| Node.js | ≥ 20(推荐 22) | Web 前端与 TypeScript SDK 构建 |
| uv | 最新版 | Python 包管理器(替代 pip/venv) |
| Docker | ≥ 24(可选) | 容器化部署时需要 |
本项目不依赖系统级数据库——SQLite 随 Python 自带,开箱即用。
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# 或 pip
pip install uvcd windagent
# 国内环境建议配清华镜像(直连 PyPI 不稳定)
export UV_DEFAULT_INDEX=https://pypi.tuna.tsinghua.edu.cn/simple
# 一键安装全部四个 Python workspace 包 + 开发依赖
uv sync --all-packages
# 使用 OpenAI provider 时,额外启用 windagent-core[openai]
uv sync --all-packages --extra openaicd web
# 国内环境建议配 npmmirror
npm install --registry=https://registry.npmmirror.com
npm run build # 产物输出到 web/dist/
cd ..前端开发热更新模式:
npm run dev(Vite :5173,自动 proxy API 到 :8000)
TypeScript SDK 可独立构建:
cd sdk-ts
npm install
npm run build# 向量库(RAG 后端)
uv pip install 'windagent-core[qdrant]' # 或 chroma / faiss / pgvector / milvus
# PostgreSQL checkpointer(生产部署)
uv pip install 'windagent-server[postgres]'
# A2A 协议支持
uv pip install 'windagent-server[a2a]'
# MCP 工具接入
uv pip install 'windagent-core[mcp]'
# 或一次装全部
uv pip install 'windagent-core[qdrant,chroma,faiss,pgvector,milvus,mcp]' 'windagent-server[postgres,a2a]'uv run python -m pytest -q # 全部测试通过
uv run windagent validate examples/react_demo.yaml # DSL 校验
uv run windagent run examples/react_demo.yaml -m "what is 2 * (3 + 4)?" # 离线运行
cd sdk-ts && npm run typecheck && npm run build在 YAML DSL 的 llm 字段配置。所有 provider 通过环境变量传递 API key:
| Provider | provider 值 |
需要的 env | 示例 model |
|---|---|---|---|
| DeepSeek | deepseek |
DEEPSEEK_API_KEY |
deepseek-v4-flash |
| OpenAI | openai |
OPENAI_API_KEY |
gpt-4o-mini |
| Anthropic | anthropic |
ANTHROPIC_API_KEY |
claude-sonnet-4-20250514 |
google_genai |
GOOGLE_API_KEY |
gemini-1.5-flash |
|
| Ollama(本地) | ollama |
无需 key | llama3.1 |
| Groq | groq |
GROQ_API_KEY |
llama-3.3-70b-versatile |
| Fake(离线) | fake |
无需 key | — |
# 示例:用 OpenAI 运行
# 先将 my_agent.yaml 中的 llm.provider 改为 openai,并设置所需 model
uv sync --all-packages --extra openai
export OPENAI_API_KEY=sk-...
uv run windagent run my_agent.yaml -m "hello"根目录的
my_agent.yaml和所有示例(examples/*.yaml)默认使用provider: fake+ 脚本化响应,零 API key 即可运行。
| 变量 | 说明 | 默认值 |
|---|---|---|
WINDAGENT_DATA_DIR |
数据目录(SQLite DB + checkpoints) | .windagent |
FORGE_CHECKPOINTER |
持久化后端:sqlite 或 postgres |
sqlite |
DATABASE_URL |
PostgreSQL DSN(FORGE_CHECKPOINTER=postgres 时必需) |
— |
FORGE_API_KEY |
API key 鉴权(设定后所有非 health 端点需 Bearer token) | —(关闭) |
LANGSMITH_TRACING |
true 启用 LangSmith 全链路追踪 |
—(关闭) |
LANGSMITH_API_KEY |
LangSmith API key | — |
LANGSMITH_PROJECT |
LangSmith 项目名 | windagent |
WINDAGENT_WEB_DIST |
前端 dist 目录路径 | ../web/dist |
WINDAGENT_MCP_CONFIG |
服务端 MCP catalog YAML | — |
WINDAGENT_KNOWLEDGE_CONFIG |
服务端 Knowledge catalog YAML | — |
WINDAGENT_SKILL_DIRS |
只读可信 Skill package 目录列表 | — |
WINDAGENT_AGENT_DIRS |
自动同步的 Agent YAML 目录列表 | CLI 默认 examples/deepseek |
WINDAGENT_AGENT_SYNC_INTERVAL |
YAML watcher 轮询秒数;0 表示仅启动同步 |
1.0 |
WINDAGENT_OTEL_ENABLED |
true 启用 OTLP Trajectory 导出 |
—(关闭) |
OTEL_EXPORTER_OTLP_ENDPOINT |
OTLP Collector/Langfuse endpoint | SDK 默认值 |
Server 启动时会发布三个版本固定的示例 Skill,可直接在编排器右侧的 Skills grant 中选择:
data-verification@1.0.0:通过calculator对计算、单位与边界条件进行核验;evidence-briefing@1.0.0:使用current_time、text_stats形成可审计决策简报;incident-coordination@1.0.0:组织调查、缓解、验证与沟通四条响应轨道。
示例 SKILL.md 均使用英文指令,源码位于 server/src/windagent_server/builtin_skills/。react-deepseek-analyst 已绑定 data-verification,可直接观察 Skill 激活与依赖 Tool 调用。
windagent 会在解析命令前通过 python-dotenv 加载当前工作目录的 .env,且不
覆盖 shell、容器或服务管理器已经导出的同名变量。例如仓库内 DeepSeek 示例可配置:
DEEPSEEK_API_KEY=your-deepseek-api-keyCLI 通过 --api-key 参数或 FORGE_API_KEY 环境变量传递服务端鉴权 token,自动
注入到 SDK 的 Authorization: Bearer header;它与 LLM provider 的 API key 是
两类不同的密钥。
编译 YAML DSL 在当前进程内执行,适合开发调试和单次运行:
# 离线运行(fake LLM,零配置)
uv run windagent run examples/react_demo.yaml -m "what is 2 * (3 + 4)?"
uv run windagent run examples/combined_demo.yaml -m "grow 100 at 5%"
uv run windagent run examples/debate_demo.yaml -m "is debate useful?"
uv run windagent run examples/tot_demo.yaml -m "solve it"
# 接真实 LLM(安装 provider、修改 YAML,再设置 API key)
uv sync --all-packages --extra openai
export OPENAI_API_KEY=sk-...
uv run windagent run my_agent.yaml -m "hello"
# 静默模式(只输出最终答案)
uv run windagent run examples/react_demo.yaml -m "hello" -q
# 校验 DSL 语法(不运行)
uv run windagent validate my_agent.yaml启动 FastAPI 服务端,通过 CLI 或 SDK 远程调用:
# 终端 1:启动 server(含 Web 控制台)
uv run windagent serve --host 0.0.0.0 --port 8000
# 终端 2:注册 agent + 运行
uv run windagent agents create examples/react_demo.yaml -s http://127.0.0.1:8000
uv run windagent run examples/react_demo.yaml -m "what is 2*(3+4)?" -s http://127.0.0.1:8000
# 查看运行历史与 trace
uv run windagent runs list -s http://127.0.0.1:8000
uv run windagent runs show <run_id> --trace -s http://127.0.0.1:8000浏览器打开 http://127.0.0.1:8000 即可使用 Web 控制台(需先 npm run build 构建前端)。
# 启动时设 FORGE_API_KEY
export FORGE_API_KEY=my-secret-key
uv run windagent serve --port 8000
# CLI 传 --api-key(或设 FORGE_API_KEY env)
uv run windagent run examples/react_demo.yaml -m "hello" \
-s http://127.0.0.1:8000 --api-key my-secret-key
# SDK 传 api_key 参数
# WindAgentClient(base_url="http://127.0.0.1:8000", api_key="my-secret-key")
# curl
curl -H "Authorization: Bearer my-secret-key" http://127.0.0.1:8000/agents# 1. 启动 PostgreSQL(或用 docker-compose 中的 postgres 服务)
docker run -d --name forge-pg \
-e POSTGRES_DB=windagent \
-e POSTGRES_USER=forge \
-e POSTGRES_PASSWORD=forge_secret \
-p 5432:5432 postgres:16-alpine
# 2. 配置环境变量
export FORGE_CHECKPOINTER=postgres
export DATABASE_URL=postgresql://forge:forge_secret@localhost:5432/windagent
export FORGE_API_KEY=my-production-key
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=lsv2_...
export LANGSMITH_PROJECT=windagent-prod
export OPENAI_API_KEY=sk-...
# 3. 启动
uv run windagent serve --host 0.0.0.0 --port 8000windagent serve 会把配置目录中的 YAML 自动发布为新的不可变
AgentVersion。仓库内运行时默认监控 examples/deepseek;生产环境可显式设置:
export WINDAGENT_AGENT_DIRS=/srv/windagent/agents
export WINDAGENT_AGENT_SYNC_INTERVAL=1.0
uv run windagent serve --host 0.0.0.0 --port 8000YAML 校验或编译失败时,数据库继续使用最后一个有效版本。删除 YAML 不会隐式 删除 Agent 或历史 Run。
FORGE_CHECKPOINTER=postgres只迁移 LangGraph checkpoint。Agent、Run、Event 与 Resource catalog 仍使用WINDAGENT_DATA_DIR中的 SQLite;内置 worker 只能 单副本部署,不能把此配置描述为完整 PostgreSQL 多副本生产模式。
# SQLite 模式(最简)
docker compose up # → http://localhost:8000
# PostgreSQL 模式:编辑 docker-compose.yml 取消注释 postgres 服务,然后
FORGE_CHECKPOINTER=postgres \
DATABASE_URL=postgresql://forge:forge_secret@postgres:5432/windagent \
docker compose up三阶段 Dockerfile:node build web → uv sync → python:slim runtime。
curl http://127.0.0.1:8000/health
# {"status":"ok","checkpointer":"sqlite","tracing":"off","auth":"off"}name: my-agent
llm: # 图级默认 LLM(节点可覆盖)
provider: openai # openai / anthropic / ollama / fake(离线脚本模式)
model: gpt-4o-mini
temperature: 0
nodes:
- id: kb # RAG 节点:检索 → context 注入
type: rag
rag:
backend: qdrant # inmemory / qdrant / chroma / faiss / pgvector / milvus
collection: docs
k: 4
texts: ["..."] # 可选种子文档(demo 用)
- id: solver # 范式节点
type: plan_execute # react / plan_execute / reflection / debate / tot
tools: [calculator] # 内置: calculator / current_time / echo / text_stats
max_iterations: 5
retry: { attempts: 3 }
timeout: 30
graph: # 可选:plan_execute 的每步用该子图执行
nodes: [{ id: step, type: react, tools: [calculator] }]
- id: reviewer
type: reflection # 内建私有循环计数的 Reflection
prompt: review@v2 # 提示词注册表引用(name@version)
max_iterations: 3
- id: gate
type: human # Human-in-the-loop:interrupt + resume
message: "Approve this plan?"
- id: debaters # 多 Agent 辩论(可选 debaters 参数)
type: debate
debaters: 3
max_iterations: 2
- id: thinker # Tree-of-Thought(可选 breadth/depth 参数)
type: tot
breadth: 3
depth: 2
edges: # 省略则按 nodes 顺序线性串联
- { source: kb, target: solver }
- { source: solver, target: reviewer, when: "len(state['plan']) > 1" }
- { source: reviewer, target: END }when 表达式运行在 AST 白名单沙箱中:仅比较/布尔/成员运算 + len/str/int/float/bool,无属性访问、无导入。
| 类型 | 说明 | 专有参数 |
|---|---|---|
react |
ReAct 推理+工具调用循环 | tools, system |
plan_execute |
规划→逐步执行→汇总 | tools, max_iterations, graph(执行子图) |
reflection |
生成→批判→修订循环 | prompt, max_iterations |
debate |
多辩手辩论→裁判收敛 | debaters, max_iterations |
tot |
广度搜索+评分择优 | breadth, depth |
llm |
单次 LLM 调用 | prompt / system |
tool |
直接调用注册工具 | tools, message |
rag |
检索并注入上下文 | rag.backend, rag.k |
human |
人工审批中断点 | message |
subgraph |
嵌套另一个图 | graph |
supervisor |
中央调度多个 worker(本地节点或 a2a://name 远程 Agent) |
workers, max_iterations, config.parallel, config.max_concurrency |
fork |
从所有无条件出边启动并行分支 | — |
agent |
调用已发布 Agent,并写入独立分支产物 | agent, input_template, output_key |
aggregate |
等待全部入边完成并汇总命名产物 | inputs, output_key, system |
memory_recall |
从会话记忆召回上下文 | config.k, config.state_key |
memory_save |
将指定状态字段写入会话记忆 | config.source |
compact |
截断或总结长上下文 | config.strategy, config.max_messages |
| 范式 | 实现方式 |
|---|---|
| ReAct | 编排 langchain.agents.create_agent(langgraph prebuilt),原生工具调用循环 |
| Plan-and-Execute | planner → executor 循环 → finalize,每步可内嵌任意子图(如 ReAct) |
| Reflection | generate → critique(VERDICT: OK/REVISE)→ revise,迭代上限守卫 |
| Multi-agent Debate | N 辩手独立作答 → 交叉批判 → 裁判裁决,见共识即收敛 |
| Tree-of-Thought | 每轮生成 breadth 个候选 → LLM 评分 → 贪心保留最优,扩展 depth 层 |
| Supervisor | 中央 supervisor 按 LLM 决策动态派活给 worker;默认串行,config.parallel: true 时一轮可选择多个 worker,等待整批完成后继续路由 |
| 自定义范式 | register_paradigm(name, builder) 一行接入 DSL |
组合示例(examples/combined_demo.yaml):RAG 检索注入 → PlanExecute(每步是 ReAct agent)→ Reflection 打磨——一个 YAML 文件完成三层范式嵌套。
WindAgent 提供两种并行机制,它们解决的问题不同:
| 机制 | 适用场景 | 产物语义 |
|---|---|---|
fork + agent + aggregate |
固定的专业分工,例如研究、数据和风险同时执行 | 每个 agent 使用唯一 output_key 发布独立产物;aggregate 等待全部入边后一次性汇总 |
| Supervisor 并行分发 | 由 LLM 根据任务和已有结果动态决定本轮需要哪些 worker | Supervisor 一轮可选择多个 worker,等待整批完成并记录结果,然后决定继续派工或 FINISH |
固定并行团队示例见 examples/parallel_agent_team.yaml:
nodes:
- {id: dispatch, type: fork}
- id: research
type: agent
agent: research-agent
input_template: "Research and cite evidence:\n{input}"
output_key: research
- id: risk
type: agent
agent: risk-agent
input_template: "Identify material risks:\n{input}"
output_key: risk
- id: summary
type: aggregate
inputs: [research, risk]
edges:
- {source: dispatch, target: research}
- {source: dispatch, target: risk}
- {source: research, target: summary}
- {source: risk, target: summary}aggregate.inputs 必须与所有入边 Agent 的 output_key 完全匹配。可视化编辑器会根据连线自动维护该列表,并从 START 连线同步 entry。
Supervisor 并行配置:
- id: lead
type: supervisor
workers: [researcher, writer, reviewer]
max_iterations: 6
config:
parallel: true
max_concurrency: 3Supervisor 到本地 worker 的画布连线表示归属关系;worker 由 Supervisor 私有调度,不会被外层图再次执行。
统一工厂 create_vector_store(spec),后端按需安装 extras:
uv pip install 'windagent-core[qdrant]' # 或 chroma / faiss / pgvector / milvusinmemory 后端零依赖,开箱即用;fake embedding(确定性哈希)支持完全离线开发测试。
import asyncio
from windagent_sdk import WindAgentClient
async def main():
async with WindAgentClient(
"http://127.0.0.1:8000",
api_key="my-secret-key", # 可选,服务端设了 FORGE_API_KEY 时必需
) as client:
await client.create_agent(open("examples/react_demo.yaml").read())
run_id = await client.start_run("react-demo", "what is 2 * (3 + 4)?")
async for event in client.stream_run(run_id): # SSE 实时事件
if event["type"] == "token":
print(event["content"], end="", flush=True)
record = await client.get_run(run_id)
print(record["status"], record["output"], record["trace"])
asyncio.run(main())同步封装(脚本/Notebook 用):
from windagent_sdk import WindAgentClientSync
client = WindAgentClientSync("http://127.0.0.1:8000", api_key="...")
record = client.run("react-demo", "hello") # start + wait
print(record["status"])sdk-ts 是零运行时依赖的独立客户端包 @windagent/sdk,使用标准 fetch,适合 Node.js 服务、脚本和第三方 TypeScript 应用。它不是 Web 控制台内部 API client;控制台使用同源 HttpOnly Session Cookie,而 SDK 使用可选 Bearer API Key。
import { WindAgentClient } from "@windagent/sdk";
const client = new WindAgentClient({
baseUrl: "http://127.0.0.1:8000",
apiKey: process.env.FORGE_API_KEY,
});
const { run_id } = await client.startRun("react-demo", "Hello");
for await (const event of client.streamRun(run_id)) {
if (event.type === "token") process.stdout.write(event.content ?? "");
}streamRun(runId, { afterSequence }) 支持通过事件序号断点续传;也可以传入 AbortSignal 主动停止订阅。
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/health |
健康检查(含 checkpointer/tracing/auth 状态) |
POST |
/agents |
注册 agent(YAML 编译时校验) |
GET |
/agents |
列出所有 agent |
GET |
/agents/{name} |
agent 详情(spec + yaml) |
DELETE |
/agents/{name} |
删除 agent |
GET |
/agents/{name}/versions |
查询 Agent 不可变版本历史 |
POST |
/agents/{name}/runs |
启动运行 → run_id |
POST |
/agents/{name}/sessions |
创建多轮会话 |
GET |
/sessions |
查询会话(可按 Agent 过滤) |
POST |
/sessions/{id}/runs |
在已有会话中启动运行 |
GET |
/runs |
运行列表(可按 agent 过滤) |
GET |
/runs/{id} |
运行详情(含 output + trace) |
GET |
/runs/{id}/events |
可回放的 SSE 事件流,包含 LLM token 文本增量 |
GET |
/runs/{id}/trajectory |
查询结构化 Agent 调用轨迹 |
POST |
/runs/{id}/resume |
恢复 HITL 暂停的运行 |
POST |
/runs/{id}/cancel |
取消正在执行的 Run |
GET |
/resources |
查询 Tool、MCP、Skill 和 Knowledge catalog |
GET |
/a2a/{name}/.well-known/agent.json |
A2A AgentCard 发现 |
POST |
/a2a/{name} |
A2A JSON-RPC message/send |
from windagent_core.tools import ToolRegistry, make_a2a_tool
registry = ToolRegistry()
await registry.load_mcp_server(url="http://localhost:9000/mcp") # FastMCP(extra: [mcp])
registry.register(make_a2a_tool("http://remote-agent:8000", "remote_expert")) # A2A(extra: [a2a])docker compose up # → http://localhost:8000通过 docker-compose.yml 的 environment 段或 docker run -e 传入,详见上方配置章节。
docker build -t windagent .
docker run -p 8000:8000 -v windagent-data:/data \
-e FORGE_API_KEY=my-secret \
-e OPENAI_API_KEY=sk-... \
windagentwindagent/
├── core/src/windagent_core/
│ ├── prompts/ # Prompt Engineering:版本化注册表
│ ├── context/ # Context Engineering:memory / compaction / rag
│ ├── loops/ # Loop Engineering:retry / timeout
│ ├── graphs/ # Graph Engineering:DSL + 沙箱表达式 + 编译器
│ ├── paradigms/ # ReAct / PlanExecute / Reflection / Debate / ToT / Supervisor
│ ├── llm.py # 多 provider LLM 工厂 + scripted 离线模式
│ ├── tools.py # 内置工具 + MCP(FastMCP) / A2A 接入
│ ├── tracing.py # Trace 采集 + LangSmith 集成
│ └── engine.py # ForgeEngine:compile / run / stream
├── server/ # FastAPI harness:REST + SSE + 持久化 + 鉴权 + A2A
├── sdk/ # 全异步 Python SDK(httpx)
├── sdk-ts/ # 零运行时依赖 TypeScript SDK(fetch + SSE)
├── cli/ # Typer CLI:run / validate / serve / agents / runs
├── web/ # React + TypeScript + Tailwind + React Flow 可视化控制台
├── examples/ # 离线、DeepSeek、并行 Agent 与多范式组合示例
├── tests/ # 内核、服务端、SDK、A2A、HITL 与并行编排测试
├── Dockerfile # 三阶段构建
├── docker-compose.yml
└── pyproject.toml # uv workspace 根配置
- fake LLM 模式:
provider: fake+fake_script(支持tool_calls)让所有范式离线可测可演示;接真实模型只需改provider/model并配 API key。 - 组合性的根基:所有范式共享同一个
ForgeStateschema(TypedDict channels),循环预算按 Graph scope/node 隔离,嵌套子图通过共享状态通道交换数据。 - 并行隔离与等待:Agent 分支只发布各自的
branch_outputs增量;多入边 waiting edge 保证 aggregate 在全部分支完成后执行,避免共享状态覆盖。 - 依赖精简:核心仅 8 个直接依赖;向量库 / LLM provider / MCP / A2A / PostgreSQL 全部为可选 extras。
- 安全沙箱:
when条件表达式经 AST 白名单编译,阻断__import__、属性访问等注入向量。
- 0.1 单机 MVP:Core、FastAPI、Python SDK、CLI、Web 与六种范式原型
- 0.2 / P0(进行中):正确性、现代框架接口、安全与当前产品面闭环
- 0.3 / P1:版本化 Graph/State/Event IR 与不可变资源版本
- 0.4 / P2:PostgreSQL durable RunService 与可回放 Event Log
- 0.5 / P3:Capability、Skill、MCP、Tool、Knowledge 与执行授权
- 0.6+ / P4–P5:多租户产品面、观测、评测与规模化运行
详细状态、差距和阶段验收见 docs/architecture-audit-and-evolution-plan.md。


