Skip to content

Latest commit

 

History

History
240 lines (185 loc) · 15.6 KB

File metadata and controls

240 lines (185 loc) · 15.6 KB

WindAgent 当前实现与运行机制

更新日期:2026-08-09

适用版本:0.1.x

Python:>=3.11,开发与容器推荐 3.12

1. 当前结论

WindAgent 已从单机演示原型演进为具备稳定领域边界的自托管 Agent 编排基础平台。当前完成的主能力包括:

  • 六种内置范式:ReAct、Plan-and-Execute、Reflection、Debate、Tree-of-Thought、Supervisor;
  • LLM、Tool、RAG、Human、Subgraph、Memory Recall、Memory Save、Context Compact 原语;
  • namespaced extension、嵌套 Graph scope、节点私有循环计数和受控并发;
  • 不可变 AgentVersion、CapabilitySnapshot、ResourceVersion 与 Run 固定版本恢复;
  • 多 Session 对话、Session 内 LangGraph 短期 Context、跨 Session 隔离与完整删除;
  • append-only RunEvent、SSE cursor 回放、多订阅者、HITL、真实 cancel;
  • Web、CLI、Python SDK 与零运行时依赖 TypeScript SDK;
  • FastMCP 3.x Client 复用、参数 Schema 与结构化结果;
  • A2A 1.x SDK 的 Agent Card、JSON-RPC、Task/HITL/cancel 适配;
  • Skill progressive disclosure、依赖能力门控、两阶段 ZIP 安装;
  • 稳定 AgentTrajectory/Eval IR、确定性门禁和可选 OTLP 导出。

内置 Run worker 仍明确是单副本模式。它支持持久 HITL 恢复,但不宣称多副本领取任务,也不宣称运行中的任意协程可在崩溃后原地继续。需要跨天/月的 durable workflow、多副本调度和 Signal/Update 语义时,目标后端是可选 Temporal adapter。

2. 领域对象

Agent ── current ──> AgentVersion ── pins ──> GraphSpec
                           │
                           └── pins ──> CapabilitySnapshot
                                           ├── Tool ResourceVersion
                                           ├── MCP ResourceVersion
                                           ├── Skill ResourceVersion
                                           └── Knowledge ResourceVersion

Session ── pins ──> AgentVersion + CapabilitySnapshot
   │
   ├── owns ──> stable LangGraph thread/checkpoint
   └── contains ──> Run ──> append-only RunEvent
                         └── AgentTrajectory ──> Evaluator ──> EvalScore ──> GateDecision

Memory ── explicit read/write policy ──> selected facts across Sessions

关键语义:

  • Agent 是稳定身份,更新配置会发布新的 AgentVersion,不会改写旧版本;
  • CapabilityBinding 只声明希望使用的能力,CapabilitySnapshot 才是固定版本结果;
  • None binding 表示从 Graph 的真实引用推导最小集合,显式空列表表示拒绝全部;
  • Session 创建时固定 AgentVersion/CapabilitySnapshot;同一 Session 的后续 Run 与 HITL 恢复都不跟随 latest;
  • 一个 Run 表示 Session 中的一轮执行;同一 Session 复用稳定 thread_id,不同 Session 使用不同 thread;
  • Context 是 Session 内的 LangGraph checkpoint state;Memory 是显式选择后跨 Session 保存的事实,两者都不是 UI 聊天记录的别名;
  • 删除 Session 会先删除 LangGraph thread checkpoint,再事务删除所属 Run 与 RunEvent;活动中的 Session 必须先 cancel;
  • Skill 的 requires 只是需求声明,不会自动扩大 Agent grant;
  • RunEvent 是事实源,SSE 只是它的一种投影。

3. 编译与运行链

flowchart LR
    YAML[YAML / JSON] --> LOAD[load_spec]
    LOAD --> DSL[GraphSpec validation]
    DSL --> SNAP[Capability resolver]
    SNAP --> VER[immutable AgentVersion]
    VER --> COMP[ForgeEngine.compile]
    COMP --> SCOPE[BuildContext / local Graph scope]
    SCOPE --> LG[LangGraph CompiledStateGraph]
    LG --> CP[(LangGraph checkpointer)]

    API[FastAPI / A2A / SDK] --> SESSION[SessionManager]
    SESSION --> RUN[RunManager]
    SESSION --> CP
    RUN --> DB[(Run + append-only Event Log)]
    RUN --> LG
    DB --> SSE[SSE replay by sequence]
    DB --> TRAJ[AgentTrajectory]
    TRAJ --> OTLP[optional OTLP]
    TRAJ --> EVAL[Evaluator / Gate]
Loading

3.1 编译

  1. load_spec() 使用 Pydantic 校验 Graph、节点、边和 extension kind。
  2. Server 解析 Tool/MCP/Skill/Knowledge binding,并固定每项 ResourceVersion。
  3. ForgeEngine.compile() 以 Graph JSON、CapabilitySnapshot 和 checkpointer identity 缓存编译结果。
  4. 每层 Graph 创建独立 BuildContext scope;共享 Prompt、Tool、Skill、Knowledge 和 LLM cache,但不共享 sibling node index。
  5. LangGraph streaming 固定使用 v2,同时消费 messages 与 updates;内部 adapter 将其转换为 WindAgent GraphToken / GraphUpdate,第三方事件形状不会泄漏为 SDK 契约。

3.2 执行、HITL 与恢复

  1. SessionManager 创建 Session 时固定 AgentVersion、CapabilitySnapshot、thread_id 与 Memory namespace。
  2. RunManager.start() 使用 Session 的稳定 thread,先落 Run 和 started 事件,再启动本地 async task。
  3. 每个文本增量 token 和状态 update 都按递增 sequence 写入 run_events, 订阅者按 cursor 独立回放;嵌套 subgraph 的模型输出同样可实时传递。
  4. Human 节点使用 LangGraph interrupt();暂停状态、interrupt payload 和 checkpoint 均持久化。
  5. 服务重启时,awaiting_human Run 会重建句柄;resume 使用固定 AgentVersion 和同一 thread checkpoint。
  6. 失去协程的 running Run 会明确标为 failed,不伪装成可恢复。
  7. cancel 会取消本 worker 中的 task、持久化终态,并广播 cancelled。

3.3 Context 与 Memory

  • 短期 Context:LangGraph checkpointer 按 Session 的 thread_id 保存完整 Graph state。后续 Run 只提交新的 HumanMessage,LangGraph 会恢复旧 state 并通过 reducer 追加本轮消息。
  • Context 压缩:compact 节点可按 YAML 显式加入 Graph,使用 truncate 或 summarize 控制长对话 Token;平台不会在未知 Graph 上偷偷改写 state。
  • 长期 Memory:Server 使用数据目录中的 memories.db,memory_recall 与 memory_save 节点通过稳定 Memory port 异步访问。默认 namespace 为当前 Agent,因而可以跨其 Session 召回。
  • 写入策略:长期写入默认不会自动发生。只有 Graph 显式编排 memory_save 才保存事实;删除会话也不会隐式删除已经明确写入的长期 Memory。
  • 当前安全边界:0.1 是单用户/单服务身份模型,Memory namespace 暂按 Agent 隔离。接入 OIDC/RBAC 后必须升级为 principal/tenant + Agent namespace,防止不同用户共享记忆。

3.4 YAML source 自动同步

AgentSourceSynchronizer 把配置目录中的 *.yaml / *.yml 作为 current AgentVersion 的权威来源:

  1. Server 启动时先完成 Tool、MCP、Knowledge 与 Skill catalog 加载,再扫描 YAML;
  2. YAML 必须依次通过 GraphSpec 校验、CapabilitySnapshot 解析与 Graph 编译;
  3. YAML 文本或 CapabilitySnapshot 变化时,创建新的不可变 AgentVersion,并原子切换 Agent 的 current pointer;
  4. 运行期按 WINDAGENT_AGENT_SYNC_INTERVAL 轮询,无需重启即可发现变化;
  5. 其他写入口临时移动 current pointer 后,下一轮同步会重新指向 YAML 对应版本;
  6. 无效、部分写入或同名冲突只会进入 degraded report,不会覆盖最后一个有效版本;
  7. 删除 YAML 不会自动删除 Agent、历史版本或 Run,避免隐式破坏数据。

从仓库根目录执行 windagent serve 且未显式配置目录时,CLI 默认监控 examples/deepseek。生产部署应显式设置 WINDAGENT_AGENT_DIRS;多个目录使用 操作系统的 path separator 分隔。状态可通过 GET /meta/agent-sources 查看。

4. 五层工程映射

焦点 当前实现
Prompt Engineering 严格 Jinja2、StrictUndefined、版本化 registry、英文内置 Prompt
Context Engineering Session/checkpoint 短期 Context、显式长期 Memory、RAG/Knowledge、truncate/summarize compaction
Loop Engineering retry、timeout、recursion limit、节点私有 loop count、有界并发
Graph Engineering GraphSpec、嵌套 scope、条件边、subgraph、namespaced extension
Harness Engineering AgentVersion、Run/Event、HITL/cancel、API/SDK/Web、A2A、OTel/Eval

5. Skill 模型与安全边界

Skill package 由 SKILL.md、可选 skill.json、refs/、scripts/、assets/ 组成。模型只先看到卡片;progressive Skill 必须调用 activate_skill 后才注入英文正文并显示依赖 Tool。

Server 随包提供三个可直接绑定的示例 Skill:data-verification、evidence-briefing 与 incident-coordination。它们位于 windagent_server/builtin_skills,启动时先于 Agent YAML 同步发布,因此 DeepSeek ReAct 示例可以固定绑定 data-verification@1.0.0。这些示例的 SKILL.md 指令保持英文,Manifest 与依赖仍走同一套版本、授权和审计规则。

执行器会再次检查依赖 Tool 是否已激活,不能通过伪造 Tool call 绕过。Manifest 依赖在发布时检查存在性和完整 DAG 环,在 Agent 发布时再次检查它们是否被显式 grant。

ZIP 安装流程:

  1. POST /skills/imports/prepare 上传 archive;
  2. 校验压缩/解压体积、文件数、重复路径、Zip Slip、加密项、符号链接和唯一 SKILL.md;
  3. draft 一小时有效,prepare 阶段不发布资源;
  4. POST /skills/imports/{draft_id}/confirm 再检查内容 hash 与依赖;
  5. 复制到不可变目录并发布 ResourceVersion。

上传内容强制保持 untrusted 且禁止 scripts。可信 Skill 只能通过运维控制的只读 WINDAGENT_SKILL_DIRS 发布。运行期不会把宿主机全部环境变量暴露给 Skill。

6. MCP、A2A 与 Knowledge

  • MCP 默认 Streamable HTTP;只有显式 /sse URL 使用兼容 transport;Client/stdio process 在 registry 生命周期内复用。
  • 远程 MCP inputSchema 会成为 LangChain Tool schema,结果同时保留文本 content 和结构化 data/artifact。
  • A2A 使用 1.x SDK 的 protobuf AgentCard、/.well-known/agent-card.json 和官方 request handler;A2A Task 最终仍进入统一 RunManager。
  • Graph 推荐只引用 Knowledge resource id。连接配置与凭证只保存在服务端 Resource config,列表 API 永不返回 config。

7. Trajectory、Telemetry 与 Eval

AgentTrajectory 是 WindAgent 自有稳定 IR,step kind 包含:model、retrieval、tool、mcp、a2a、skill_activate、graph_node、artifact、human_intervention。

  • GET /runs/{id}/trajectory 提供统一轨迹;
  • LangChain callback 生命周期会实时写为 activity RunEvent,Tool/MCP/Model 无需等 Run 结束即可回放;终态仍保存完整 Trace,Trajectory 会自动去重;
  • Graph update 保留 subgraph namespace、Supervisor 派工、Debate transcript 和结构化产物,用于展示 Agent 协作过程;私有 reasoning/Thinking/Tree-of-Thought 状态不进入 Web 详情;
  • TelemetrySink 消费 Trajectory,内置 OTelTrajectorySink;
  • WINDAGENT_OTEL_ENABLED=true 时使用标准 OTEL_EXPORTER_OTLP_* 环境变量;
  • Langfuse 可作为推荐自托管 OTLP backend;LangSmith 保持独立可选 tracing;
  • Ragas/DeepEval 通过 Evaluator adapter 接入,不成为核心类型;
  • windagent eval SPEC --dataset DATASET 执行确定性离线门禁,失败返回非零退出码。

OpenTelemetry GenAI semantic conventions 仍在演进,因此公共 IR 使用稳定的 windagent.* 属性,实验性属性只能在 adapter 内映射。

8. 配置清单

环境变量 作用
WINDAGENT_DATA_DIR 应用 DB、checkpoint、Skill draft/安装目录
FORGE_API_KEY 服务账号 Bearer 与 Web HttpOnly Session 登录
FORGE_CHECKPOINTER sqlite 或 postgres,只控制 LangGraph checkpoint
DATABASE_URL PostgreSQL checkpointer DSN
WINDAGENT_MCP_CONFIG 服务端 MCP catalog YAML
WINDAGENT_KNOWLEDGE_CONFIG 服务端 Knowledge catalog YAML
WINDAGENT_SKILL_DIRS 运维控制的只读可信 Skill 目录列表
WINDAGENT_AGENT_DIRS 递归监控的 Agent YAML 权威目录列表
WINDAGENT_AGENT_SYNC_INTERVAL YAML watcher 轮询秒数,默认 1.0;设为 0 时仅启动同步
WINDAGENT_CORS_ORIGINS Web 开发 origin allowlist
WINDAGENT_OTEL_ENABLED true 启用 OTLP 导出
OTEL_EXPORTER_OTLP_ENDPOINT OTLP Collector/Langfuse endpoint
LANGSMITH_TRACING true 启用可选 LangSmith tracing

注意:FORGE_CHECKPOINTER=postgres 只把 LangGraph checkpoint 放入 PostgreSQL;Agent、Run、Event 和 Resource catalog 当前仍使用数据目录中的 SQLite。内置 worker 因此只能单副本部署。

多会话 API:

  • POST /agents/{name}/sessions:创建并固定 AgentVersion;
  • GET /sessions?agent={name}:列出最近会话;
  • GET /sessions/{id}:读取会话与有序 Run;
  • POST /sessions/{id}/runs:在同一 LangGraph thread 上执行下一轮;
  • DELETE /sessions/{id}:删除 checkpoint、RunEvent、Run 与 Session。
  • DELETE /sessions?agent={name}:批量清除指定 Agent 的全部 Session;省略 agent 时清除全部 Agent,会在删除前拒绝仍有活动 Run 的请求。

Web 以 Session id 管理独立后台 Run 与 SSE 订阅,而不是使用页面级 running 开关。不同 Session 可以并行启动;切换会话、切换 Agent 或暂时离开运行页只会关闭当前浏览器订阅,不会取消后端任务。再次进入运行页时会根据持久化的 running/awaiting_human 状态重放事件并恢复订阅。同一 Session 仍限制为单个非终态 Run,避免并发写同一个 LangGraph thread。

并行 Agent 与 wait-all 汇总

fork 是无模型调用的并行分发节点。它的所有无条件出边会进入同一个 LangGraph 执行阶段。agent 节点通过 A2A 调用已发布 Agent:agent 指定目标名称,input_template 只允许使用 {input},output_key 将结果写入并发安全的 branch_outputs channel。

aggregate 的多条入边会编译为 LangGraph waiting edge,只有全部来源节点完成后才执行。inputs 声明需要读取的独立产物键,编辑器会根据连入该节点的 Agent output_key 自动生成;output_key 可继续发布汇总产物。完整示例见 examples/parallel_agent_team.yaml。

生产 adapter 通过当前 a2a-sdk 调用 FORGE_A2A_BASE_URL(默认 http://localhost:8000)下的已发布 Agent。ForgeEngine(agent_invoker=...) 是同一 seam 的内存 adapter 入口,测试可以在无网络条件下验证并行、隔离与 wait-all 语义。

9. 验证命令

uv lock --check
uv run ruff check .
uv run --extra mcp --extra a2a python -m pytest -q
PYTHONWARNINGS=default uv run python -m pytest -q \
  -W error::DeprecationWarning -W error::PendingDeprecationWarning

cd web && npm run build
cd ../sdk-ts && npm run build

浏览器交互验证需要产品内置 Browser 工具。本轮环境未提供该工具,因此前端只完成 TypeScript/Vite production build,不能把构建通过描述为点击行为已验证。

10. 明确边界与后续演进

  • 当前认证是单服务 API key + HttpOnly Session,不是多租户 OIDC/RBAC;
  • 当前应用 Store 是 SQLite,内置 worker 是单副本;
  • PostgreSQL checkpointer 不等于完整生产数据库;
  • 跨天/月、多副本 workflow 通过未来 RunBackend/Temporal adapter 扩展;
  • OCI/Git commit pin 的远程 Skill 获取应放在隔离 fetch worker,不允许服务宿主机执行 npx latest;当前内置 API 只接受受限 ZIP upload;
  • PromptVersion 独立发布、Artifact store、Attempt/Lease 和多租户权限仍是下一阶段产品化对象。