项目是干嘛的
Beaver 后端是一个面向用户任务的 agent runtime。它接收来自 Web、WebSocket、CLI、Gateway、Cron 或 MCP 的请求,
用 Main Agent 判断这是不是一个需要跟踪的 Task;简单问题直接回复,复杂任务进入 Task mode。Task mode 会规划单 agent
或 team 执行,运行统一的 AgentLoop,选择技能和工具,调用模型,记录事实证据,并等待用户接受、修改或放弃。
只有用户接受后的 Task evidence 才会沉淀为可学习的 skill 候选。
最关键的架构判断
主 agent、team node、sub-agent 都不各自实现一套 runtime;它们最后都回到同一个 beaver.engine.AgentLoop。
因此后续修改时要优先确认:入口层是不是薄的,服务层是不是只编排,真正 tool loop / prompt / provider / session 逻辑是不是仍在 engine 内收口。
主执行流
这是后端最重要的一条路径,后续逐模块修改文档应该先对齐这条链路。
1. 入口接收
/api/chat、WebSocket、CLI、Gateway 或 Cron 把用户消息转给 AgentService。
2. 意图路由
MainAgentRouter 结合 active task 和近期会话,判断 simple / new_task / continue / revise / close / abandon。
3. Task 建模
TaskService 写入 tasks.json 和 events.jsonl,维护 open/running/awaiting_acceptance/closed 状态。
4. 执行规划
TaskExecutionPlanner 让辅助模型选择 single 或 team,并为 team 生成 sequence / parallel / DAG 节点。
5. 统一运行
AgentLoop 冻结 memory,选 skill,选 tool,构建 prompt,调用 provider,执行 tool loop。
6. 事实证据
EvidenceBuilder 汇总 run/team/tool 证据。Evidence 只记录事实,不判断、不打分、不 gate。
7. 验收学习
用户接受 Task 后生成 accepted task evidence 和 learning candidates;worker 可生成 draft,但不会自动 approve/publish。
模块总览
每个模块下面都写明责任、逻辑、具体怎么做,以及关键文件。
底层配置、事件和通用模型
负责加载实例级配置、定义 provider/MCP/AuthZ/backend identity schema、提供 message bus 和 cron 数据模型。
- 配置来源优先级:
BEAVER_CONFIG_PATH、BEAVER_HOME/config.json、workspace 下.beaver/config.json。 BeaverConfig.resolve_provider_target()从默认模型、显式 provider 和已配置凭据推导运行目标。MessageBus用 async queue 承接 gateway inbound/outbound。CronSchedule/CronJob/CronRunRecord是定时任务持久化模型。
- beaver/foundation/config/schema.py
- beaver/foundation/config/loader.py
- beaver/foundation/events/message_bus.py
- beaver/foundation/models/cron.py
- beaver/foundation/embedding.py
薄入口层
负责把 HTTP、WebSocket、CLI、Gateway、MCP server 的输入转换成服务层调用,不应保存核心执行逻辑。
- Web app lifespan 启动
AgentServicerunning mode、CronService和可选 skill learning worker。 /api/chat和/ws/{session_id}都委托给_run_web_direct()/AgentService。- 文件 API 分两类:聊天附件
workspace/files/<id>与 workspace 浏览/上传/预览。 - MCP interface 暴露 memory/tools server,Gateway 用
MessageBus桥接渠道。
- beaver/interfaces/web/app.py
- beaver/interfaces/web/files.py
- beaver/interfaces/cli/main.py
- beaver/interfaces/gateway/main.py
- beaver/interfaces/mcp/*.py
- beaver/interfaces/channels/*.py
应用服务编排层
负责把入口请求转成系统内部流程:agent 运行、task mode、cron、team、memory、skill hub、process projection。
AgentService是主入口,区分 direct mode 和 running mode。_process_with_main_agent()先做意图分类,再决定是否进入 Task。_run_task_mode()管理 task planning、team 执行、主 agent synthesis、evidence 记录和用户验收状态。CronService负责持久化定时任务、计算下一次运行、记录 history。SessionProcessProjector把隐藏 task/team 事件投影给前端过程视图。
- beaver/services/agent_service.py
- beaver/services/team_service.py
- beaver/services/cron_service.py
- beaver/services/process_service.py
- beaver/services/skillhub_service.py
统一 agent 运行内核
这是主 agent 和 delegated agent 共用的核心。它装配 runtime,构建上下文,选择技能和工具,驱动 provider/tool loop,并记录所有运行事件。
EngineLoader装配 session、memory、run store、skill store、tool registry、MCP manager、task/evidence 服务。AgentLoop.process_direct()是单次运行主链;running mode 下只能通过 queuesubmit_direct()。- 每个 run 独立捕获 frozen memory snapshot,避免 parallel team runs 共享快照互相污染。
- 运行时写入
run_started、skill activation、tool selection、LLM request、tool result、run completed/failed 等事件。
- beaver/engine/loader.py
- beaver/engine/loop.py
- beaver/engine/context/builder.py
- beaver/engine/providers/*.py
- beaver/engine/session/*.py
模型 provider 抽象与选路
把不同模型网关统一成 LLMProvider.chat(),返回统一 LLMResponse 和 ToolCallRequest。
ProviderRuntime描述解析后的 provider、model、api mode、凭据、headers、routing。ProviderBundle同时包含 main、fallback、auxiliary、embedding runtime。FallbackProviderChain在主 provider 返回 error 或抛异常时按单次调用切到 fallback。- 实现包含 LiteLLM、Anthropic、OpenAI Codex API、OpenAI-compatible custom。
- beaver/engine/providers/base.py
- beaver/engine/providers/runtime.py
- beaver/engine/providers/factory.py
- beaver/engine/providers/registry.py
- beaver/engine/providers/litellm.py
- beaver/engine/providers/anthropic.py
- beaver/engine/providers/codex.py
内部 Task、事实证据和用户验收
负责把“需要执行和跟踪”的用户请求变成可持久化、可重试、可验收的 Task。
MainAgentRouter使用 LLM JSON 决策区分 simple/task/continue/revise/close/abandon。TaskExecutionPlanner让辅助模型选择 single 或 team,并限制 team 节点最多 6 个。TaskSkillResolver为 team node 匹配 published skill;没有匹配时生成 one-run ephemeral guidance。EvidenceBuilder只记录事实证据;Task 是否完成只由用户验收决定。
- beaver/tasks/models.py
- beaver/tasks/service.py
- beaver/tasks/router.py
- beaver/tasks/planner.py
- beaver/tasks/skill_resolver.py
- beaver/tasks/evidence.py
- beaver/tasks/store.py
多 agent / team 编排
负责把 team execution graph 转成多个 delegated runs。v1 真正实现的是 sequence、parallel、DAG;其它 strategy 目前保留但未实现。
ExecutionGraph.validate()校验节点唯一、依赖存在、无环,以及 strategy 是否已实现。TeamGraphScheduler按策略运行节点,失败依赖会把后续节点标记 blocked。LocalAgentRunner为每个节点生成 child session,并仍调用同一个AgentLoop。- Agent registry 和 LocalSubagentStore 支持管理 specialist/subagent,但当前 Task 主链主要走 generic skill worker。
- beaver/coordinator/models.py
- beaver/coordinator/execution/scheduler.py
- beaver/coordinator/local.py
- beaver/coordinator/registry/*.py
- beaver/coordinator/subagents.py
工具契约、选择和执行
负责把内建工具和 MCP 工具统一暴露为 provider function schema,并在 tool loop 里执行模型返回的调用。
ToolSpec是工具元数据和 schema 的事实来源,可导出 MCP descriptor 和 provider schema。ToolAssembler按 always tools、skill tool hints、embedding retrieval 选择本轮工具。ToolExecutor兼容ToolCallRequest和 OpenAI 风格 dict,解析参数并调用 registry。- 内建工具覆盖 memory、session search、filesystem、web fetch/search、terminal/process/code、cron、skill admin、delegation utility。
- beaver/tools/base.py
- beaver/tools/registry/tool_registry.py
- beaver/tools/runtime/executor.py
- beaver/tools/assembler/task_assembler.py
- beaver/tools/builtins/*.py
- beaver/tools/mcp/wrapper.py
技能目录、选择、生命周期和学习
负责发现、选择、注入、版本化、审核、发布和自动学习 Beaver skills。
SkillsLoader读取 workspace published skills、plugin/extra dirs、builtin skills,解析 frontmatter 和工具提示。SkillAssembler用 embedding 召回候选,再用 LLM 做 shortlist/final 选择,并返回SkillContext。SkillSpecStore管理skill.json、current.json、versions、drafts、reviews。SkillLearningPipelineService协调 candidate -> draft -> safety/eval -> review -> approve -> publish。
- beaver/skills/catalog/*.py
- beaver/skills/assembler/*.py
- beaver/skills/specs/*.py
- beaver/skills/drafts/service.py
- beaver/skills/reviews/service.py
- beaver/skills/publisher/service.py
- beaver/skills/learning/*.py
会话、长期记忆、运行记忆和学习状态
负责保存对话事件、长期记忆、run receipt、skill effect、skill learning candidates 和安全/eval 报告。
- 会话存 SQLite,包含
sessions、messages和 FTS5messages_fts。 - 长期记忆只有
MEMORY.md和USER.md两个桶,写入前扫描 prompt injection / secret exfiltration 风险。 - run memory 用 JSONL 保存
RunRecord和SkillEffectRecord。 - skill learning store 维护候选状态、performance snapshot、safety report、eval report。
- beaver/engine/session/*.py
- beaver/memory/curated/*.py
- beaver/memory/runs/*.py
- beaver/memory/skills/*.py
- beaver/memory/search/transcript_store.py
外部系统与协议集成
负责连接 AuthZ、MCP 和 Outlook。WhatsApp、A2A、providers 目录当前主要是占位。
MCPConnectionManager支持 stdio 和 streamable HTTP MCP server,并把远端 tools 注册成mcp_{server}_{tool}。- 远端 MCP 可用 AuthZ backend token 模式,通过 backend identity 换取 bearer token。
- Outlook integration 通过 AuthZ 或直接凭据连接,维护 workspace meta,提供 status/overview/messages/events/detail。
AuthzClient负责用户/backend 注册、权限查询、token 签发。
- beaver/integrations/mcp/connection.py
- beaver/integrations/authz/client.py
- beaver/integrations/outlook/__init__.py
- beaver/integrations/a2a/__init__.py
- beaver/integrations/whatsapp/__init__.py
权限与治理层
目录已经存在,但当前基本是空骨架。实际权限约束主要散落在具体工具、workspace path 校验、memory safety 和 skill draft safety 中。
permissions/guards、policies、profiles只有 docstring。ToolsConfig.restrict_to_workspace已在配置 schema 里存在,但需要逐工具核对是否真正执行。- 后续如果要做能力治理,应把工具执行、MCP sensitive 标记、provider/terminal/file 操作统一接入这里。
- beaver/permissions/__init__.py
- beaver/permissions/guards/__init__.py
- beaver/permissions/policies/__init__.py
- beaver/permissions/profiles/__init__.py
核心数据落点
这些文件/数据库是运行后最重要的事实来源。后续核对行为是否符合预期时,优先看这里。
| 数据 | 位置 | 写入者 | 用途 |
|---|---|---|---|
| Session / transcript event stream | <workspace>/sessions/state.db |
SessionManager / AgentLoop |
保存可见对话、隐藏 system snapshots、tool calls/results、run lifecycle、usage、FTS 搜索。 |
| Task records | <workspace>/tasks/tasks.json |
TaskService |
保存 task goal/status/run_ids/skill_names/acceptance history。 |
| Task events | <workspace>/tasks/events.jsonl |
TaskService |
保存 created/run_started/run_completed/evidence_recorded/accepted/revised/closed/abandoned。 |
| Curated memory | <workspace>/memory/curated/MEMORY.md, USER.md |
MemoryTool / MemoryStore |
长期注入 prompt 的稳定事实;每个 run 冻结快照。 |
| Run receipts / skill effects | <workspace>/memory/runs/*.jsonl |
AgentLoop / AgentService 用户验收入口 |
skill learning 的原始执行证据、用户验收事件和 final accepted run 标记。 |
| Skills lifecycle | <workspace>/skills/<name>/... |
SkillSpecStore / draft/review/publisher services |
published versions、drafts、reviews、current version、supporting files。 |
| Skill learning state | <workspace>/memory/skills/... |
SkillLearningStore |
候选、performance snapshot、safety report、eval report。 |
| Cron jobs and runs | <workspace>/cron/jobs.json |
CronService |
定时任务配置、next_run、history、notification/task linkage。 |
| Agent registry / subagents | <workspace>/agents/registry.json, *_agent/AGENTS.json |
AgentRegistry / LocalSubagentStore |
管理 builtin/workspace/learned agents 和本地 sub-agent workspace。 |
关键流程拆解
这些流程是后续逐模块修改时最容易产生偏差的地方。
Simple chat
- 入口调用
AgentService._process_with_main_agent()。 MainAgentRouter返回非 task。- 关闭 skill assembly 和 tools:
include_skill_assembly=False、include_tools=False。 - 仍通过
AgentLoop写 session/run 事件,但不创建 Task。
Task mode single
- 创建或复用 open task。
- planner 返回 single,主 agent 直接运行。
- 运行后构建
TaskEvidencePacket。 - 运行后状态变
awaiting_acceptance;用户 accept/revise/abandon 决定关闭、修订或放弃。
Task mode team
- planner 生成
ExecutionGraph。 TaskSkillResolver给节点绑定 published skill 或 ephemeral guidance。TeamService运行节点,节点仍调用AgentLoop。- 主 agent synthesis 使用 team evidence,通常关闭工具调用,避免重复执行子 agent 已做的事情。
Skill learning
- 每个 run 记录 activated skill receipt 和 effect。
- 用户 accept task 后才生成候选;证据包含整个 task 的所有 runs,并标记 final_accepted_run_id。
- worker 只生成 draft、做 safety/eval,不自动 approve/publish。
- publish 必须有 approved review、passing safety、没有失败 eval;high risk 还需要显式确认。
后续核对问题清单
这些问题适合配合 brainstorming / grill-me 逐模块核对想法和现有项目是否一致。
interfaces/web/app.py 已经超过 3000 行,包含 auth、files、skills、cron、chat 等。后续是否要拆 route 模块,还是先保持单文件以降低迁移风险?代码观察与风险点
这些不是修改建议的最终结论,只是阅读代码后值得后续逐项核对的偏差点。
定时 Task 路径存在明显变量错误
AgentService.run_scheduled_task() 末尾更新 assistant event payload 时引用了 job.id、run.scheduled_run_id、job.name,
但该函数参数只有 cron_job_id、cron_job_name、scheduled_run_id。这条路径如果执行到这里会触发 NameError。
权限层还没有真正成为执行闸门
permissions 目录为空骨架,实际保护分散在工具实现和路径校验里。若后续开放 terminal、filesystem、MCP sensitive tools,需要统一执行前 policy。
Web auth 是本地单用户风格
本地 auth 文件以 username/password 字段读写,使用 token/handoff code 做前端会话。若目标是多用户或公网后端,需要重新评估密码存储、token 生命周期和权限边界。
Skill eval 目前偏轻量启发式
SkillDraftEvaluator 基于历史 accepted task evidence 和草稿长度/内容做 bounded report,不是真正 replay。它只属于 skill draft 治理,不属于 Task runtime。
接口层过大
interfaces/web/app.py 同时承载 app factory、lifespan、auth、provider config、sessions、files、agents、MCP、Outlook、skills、cron、chat、helper functions。
后续修改时容易产生跨功能回归。
已经落地的稳定点
可依赖:统一 AgentLoop、session event stream、Task evidence/acceptance 状态、team graph v1、skill lifecycle gates、MCP wrapper、workspace path containment。
测试覆盖信号
单元测试覆盖了当前后端多数关键行为,可作为后续修改文档的回归索引。
Task / acceptance
test_task_mode_feedback.py, test_task_evidence.py, test_task_execution_planner.py, test_task_skill_resolver.py
Engine / providers
test_websocket_chat.py, test_main_agent_router.py, test_litellm_thinking_mode.py, test_imports.py
Team / process
test_agent_team_v1.py, test_agent_registry_resolver.py, test_process_projection.py
Skills / tools / web
test_phase5_skills_runtime.py, test_skill_learning_*.py, test_tool_assembler.py, test_web_files_api.py