AstroResearch/docs/architecture/agent/overview.md
Asfmq cec4b8cf7b feat: Docker 容器化、Cookie 鉴权、Coordinator 编排、FTS5 搜索与 P1-P3 全面收尾
Docker 容器化部署
  - 提供 Mode A (Alpine musl, ~23MB) 和 Mode B (Distroless glibc, ~87MB)
    两种镜像,Docker Compose 一键启动
  - build.rs 支持 SKIP_DASHBOARD_BUILD 跳过前端构建
  - 国内镜像加速 (npm/apt/apk) 通过 USE_MIRRORS build-arg 控制

  安全:Cookie-Based 鉴权系统
  - HttpOnly/SameSite=Strict Cookie 会话管理(24h 过期自动清理)
  - 登录/登出/验证接口 + 中间件注入
  - 前端登录页面 + 退出按钮
  - 三层 CORS:localhost 鉴权 / 全放通 bookmarklet / 受保护路由
  - 书签脚本 fetch 添加 credentials:'include'

  Coordinator 模式 (P2)
  - 4 个 meta-tool (delegate_task/check_task/task_stop/synthesize)
  - WorkerPool + Semaphore 并发控制 + 超时保护
  - 前端协调者模式开关

  Hook 系统:UserPromptSubmit 事件 (P2)
  - 第 13 个生命周期事件,fire-and-forget 审计

  FTS5 全文搜索 (P3)
  - agent_sessions_fts + agent_messages_fts 虚拟表
  - search_history Agent 工具 + /api/search/history HTTP 接口
  - 前端防抖搜索框 + 仅当前会话筛选

  工具加载优化 (P3)
  - defer_loading 延迟加载 (7 个重型工具)
  - is_readonly 只读标记 (9 个查询工具)
  - classifier_summary 工具目录供 LLM 按需判断

  模型回退策略 (P3)
  - LLM_FALLBACK_MODEL 优先回退 + LLM_FALLBACK_CHAIN 链式轮换
  - LlmClient model 改为 Arc<RwLock> 支持运行时切换
  - 连续 3 次过载后自动切换

  压缩记忆桥接 (P3)
  - 压缩丢弃消息 → 子代理提取持久记忆 (extract_memories_from_compaction)

  git2 依赖修复
  - 切换到 vendored-libgit2,消除 OpenSSL 系统依赖
2026-06-23 20:22:06 +08:00

208 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Agent 架构概览
AstroResearch 内置了一个基于 **ReAct** (Thought → Action → Observation) 范式的科研智能体引擎 (`src/agent/`),参考 Claude Code 的分层设计。以下对各子系统的架构、数据流和内部逻辑进行完整说明。
### 整体架构
```mermaid
graph TD
subgraph API["API 层"]
SSE["SSE /api/chat/agent"]
Sessions["Session CRUD"]
Metrics["GET /api/chat/metrics"]
Audit["GET /api/chat/sessions/:id/audit"]
AskUser["问答 /api/chat/questions + /api/chat/answer"]
end
subgraph Runtime["AgentRuntime — ReAct 引擎"]
RunTurn["run_turn() 主入口"]
SP["SystemPrompt 组装器"]
CtxBuild["Context Builder 上下文构建"]
ReAct["ReAct 主循环"]
Streaming["streaming.rs 流式处理"]
Executor["executor.rs 并行执行"]
Finalize["finalize.rs 会话收尾"]
TokenBudget["token_budget.rs"]
CircuitBreaker["circuit_breaker.rs"]
end
subgraph Tools["工具系统 (tools/)"]
AgentTool["AgentTool trait"]
Registry["ToolRegistry"]
FS["filesystem/ (6 工具)"]
Astro["astro/ (7 工具)"]
AskUserT["ask_user"]
SubAgentT["subagent/delegate_research"]
TeamT["team/ (4 工具)"]
BG["background (2 工具)"]
end
subgraph CrossCutting["横切关注点"]
Hooks["HookRegistry (13 事件)"]
Skills["SkillRegistry (两层加载)"]
Memory["MemoryManager (项目记忆)"]
Permission["PermissionChecker"]
FileCache["FileStateCache (Read 去重)"]
Coordinator["Coordinator Mode (协调者编排)"]
end
subgraph DB["持久化"]
AgentSessions["agent_sessions"]
AgentMessages["agent_messages"]
AgentTasks["agent_tasks"]
AgentAudit["agent_audit_log"]
end
SSE --> RunTurn
RunTurn --> SP
RunTurn --> CtxBuild --> DB
RunTurn --> ReAct
ReAct --> Streaming --> Tools
ReAct --> Executor --> Tools
ReAct --> TokenBudget
ReAct --> CircuitBreaker
ReAct --> Finalize
Hooks -.-> ReAct
Hooks -.-> Tools
Skills -.-> Tools
Memory -.-> SP
Permission -.-> Tools
FileCache -.-> Tools
```
---
### ReAct 运行循环 (`runtime/`)
主循环由 `AgentRuntime::run_turn()` 驱动,分为 4 个阶段:
#### 完整生命周期
```mermaid
sequenceDiagram
participant FE as 前端 SSE
participant RT as AgentRuntime
participant DB as SQLite
participant LLM as LLM API
participant Tools as ToolRegistry
FE->>RT: POST /api/chat/agent { question, session_id? }
Note over RT: Phase 1 — 会话管理
RT->>DB: create_or_resume_session()
alt 新会话
DB-->>RT: session_id = uuid, turn_index = 0
else 恢复会话
DB-->>RT: 验证存在 + 计算 turn_index
end
RT->>RT: 触发 OnSessionStart hook
RT->>RT: 触发 UserPromptSubmit hook (用户输入审计)
RT-->>FE: SSE session { session_id, title }
opt 协调者模式 (coordinator_mode: true)
RT->>RT: run_coordinator_turn() → CoordinatorAgent
Note over RT: Coordinator 委托 Worker → 合成结果
end
Note over RT: Phase 2 — 上下文构建
RT->>RT: build_initial_context()
RT->>RT: ① 组装 SystemPrompt (静态 section + 记忆注入)
RT->>DB: ② 加载历史消息 load_history_for_llm()
RT->>DB: ③ 恢复未完成任务 (agent_tasks)
RT->>RT: ④ 检查压缩/清理上下文
RT->>DB: ⑤ 保存用户消息
RT->>RT: ⑥ 运行 PreToolUse hooks 过滤
Note over RT: Phase 3 — ReAct 循环
loop 每步迭代 (step ≤ max_steps)
RT->>LLM: chat_stream(messages + tool_defs)
LLM-->>RT: ReasoningDelta / TextDelta / ToolCallsComplete
RT-->>FE: SSE thought / text_delta / tool_call
alt 无工具调用 → 最终答案
RT->>DB: 保存 assistant 消息
RT-->>FE: SSE text_delta → usage → done
Note over RT: break 循环
else 有工具调用
RT->>RT: 检查 token 预算 + 熔断器
RT->>RT: validate_and_prepare() — 去重 + 过滤
RT->>Tools: execute_parallel() — 并行执行
Tools-->>RT: (tool_call_id, name, output)
RT-->>FE: SSE tool_result { tool_call_id, name, output }
RT->>DB: 保存 tool 消息 + 审计日志
RT->>RT: 运行 PostToolUse hooks
RT->>RT: 检测压缩需求 (auto_compact)
end
RT->>RT: 检测循环终止条件
end
Note over RT: Phase 4 — 会话收尾
RT->>DB: 更新 turn_count + updated_at
RT->>DB: calculate_and_persist_metrics()
RT->>RT: 运行 OnSessionStop hook
RT-->>FE: SSE done
```
#### 并行工具执行模型
```mermaid
sequenceDiagram
participant ReAct as ReAct 循环
participant Val as validate_and_prepare
participant Exec as execute_parallel
participant T1 as Tool A
participant T2 as Tool B
participant FE as 前端 SSE
ReAct->>Val: LLM 返回 [tool_call_a, tool_call_b]
Val->>Val: 去重检测 + 权限验证
Val-->>ReAct: prepared_calls[] + has_duplicate 标志
ReAct->>FE: 发送 tool_call SSE (逐一)
ReAct->>Exec: 启动 execute_parallel()
par 并行执行
Exec->>T1: tool_a.execute(args_a)
Exec->>T2: tool_b.execute(args_b)
end
T1-->>Exec: ToolOutput { content, is_error }
Exec-->>FE: SSE tool_result (立即推送)
T2-->>Exec: ToolOutput { content, is_error }
Exec-->>FE: SSE tool_result (立即推送)
Exec-->>ReAct: Vec<(tool_call_id, name, args, output, cancelled)>
ReAct->>ReAct: PostToolUse hooks + 审计日志 + 持久化
```
- **并发上限**:由 `max_concurrent_tools` 环境变量控制,默认不限制
- **Sibling Abort**:仅 `causes_sibling_abort() = true` 的工具(如 `download_paper`)能在出错时中断兄弟任务
- **InterruptBehavior**`Block` 工具(如 `ask_user`)不可被用户取消;`Cancel` 工具可在取消信号时中断
- **超时控制**:每个工具有独立超时,默认 120s`AGENT_TOOL_TIMEOUT_SECS`
---
### Coordinator Mode协调者模式, P2
```mermaid
graph TD
User["用户请求"] --> API["POST /api/chat/agent\n{ coordinator_mode: true }"]
API --> RT["AgentRuntime::run_coordinator_turn()"]
RT --> CA["CoordinatorAgent (仅元工具)"]
CA --> Tool["delegate_task / check_task / task_stop / synthesize"]
Tool --> WP["WorkerPool (Semaphore 并发控制)"]
WP --> W1["Worker 1 (SubAgentRunner)"]
WP --> W2["Worker 2 (SubAgentRunner)"]
WP --> W3["Worker N (SubAgentRunner)"]
W1 --> Synth["synthesize 收集结果"]
W2 --> Synth
W3 --> Synth
Synth --> Answer["最终答案"]
```
Coordinator 仅拥有 4 个元工具,将实际研究工作委托给拥有完整工具访问权限的 Worker 子代理。Worker 通过 `SubAgentRunner` + `Semaphore` 实现并发控制(默认最大 4 并发)。
- **委托 → 检查 → 合成** 三步工作流
- 前端通过 `coordinator_mode: true` 字段启用
- 源码: `src/agent/coordinator/{agent,tools,worker,mod}.rs`
---