feat: 科研分析层全栈落地——光谱/时域/运动学分析工具链 + JWST/X 射线数据源 + 定时文献同步
数据分析层(新增 services/{spectrum,timeseries,analysis}):
- 光谱参数提取 parameters.rs:LAMOST/SDSS/APOGEE/DESI FITS header 跨源归一化读取
Teff/logg/[Fe/H]/RV 及 ASPCAP 20+ 元素丰度,rayon 并发批量提取
- 谱线测量 lines.rs:内置真空/空气波长谱线表,窗口内极值搜索 + 梯形法积分 EW + FWHM,支持自定义谱线
- 交叉相关测速 cross_correlate.rs:对数波长重采样对齐,内置 Pickles 模板按光谱型插值,
CCF 峰值位置提取 RV 及不确定度
- 周期搜索 periodicity.rs:Lomb-Scargle 周期图(含 FAP 误报概率)+ BLS 凌星检测 + 相位折叠
- 变星分类 classification.rs:振幅/偏度/峰度/过零率/eta 等统计特征 + 规则分类(RR Lyrae/Cepheid/食双星/AGN 等)
- SED 拟合 sed.rs:多波段测光黑体模型拟合,输出 T_eff/半径/消光 A_V/光度及不确定度
- 运动学 kinematics.rs:视差+自行+RV → 银河系 UVW 空间速度,含移动星群成员概率(Banyan Σ 简化版)
- 化学丰度 chemistry.rs:[α/Fe] vs [Fe/H] 计算,厚盘/薄盘/晕星族判别
- 观测规划 observability.rs:目标升落时间/airmass/月相影响/曝光时间估算
- 赫罗图 hr_diagram.rs:Gaia TAP CMD 查询,新增 GET /api/analysis/hr-diagram 端点
数据获取层:
- JWST:clients/mast/jwst.rs 封装 MAST Portal 锥形检索 + JwstSpectrumFetcher(NIRSpec/MIRI 光谱)
- X 射线:clients/heasarc 封装 HEASARC TAP(ADQL)+ XMM-Newton/Chandra 光谱 fetcher
- 图像 cutout:SDSS SkyServer/STScI DSS/Pan-STARRS 三源 cutout + 发现图(Finding Chart)生成
- Source 枚举新增 Jwst/Xmm/Chandra 并注册 ObservationRegistry,前端 SOURCE_THEME 与筛选器同步三源
Agent 工具集(24→35):
- 新增 9 个分析工具:get_spectrum_parameters / measure_spectral_lines / measure_radial_velocity /
find_period / classify_variable_star / fit_sed / analyze_kinematics / analyze_abundance_pattern / plan_observation
- batch_process:批量样本"查询→下载→分析→报告"流水线,并发控制防数据源速率限制
- literature_monitor:按 ADS 查询式/时间窗/最低引用数检查最新文献
定时文献同步:
- sync_queries 表新增 is_scheduled 列(migration 20260713)
- 新增 POST /sync/queries/:id/schedule 端点
- 服务启动时拉起每小时调度器,对 is_scheduled=1 的检索配置静默执行 ADS(entdate 增量)/arXiv 增量同步
- search_history 工具收敛至 services/search::search_agent_history,消除 FTS 查询逻辑重复
其他:
- plotting skill 由占位填充为完整科研绘图规范:光谱/光变/折叠曲线/CMD/SED/[α/Fe]/周期图/Mollweide/发现图 9 类 matplotlib 模板
- 删除死代码 streaming_executor.rs(929 行,仅剩 mod 声明引用,无调用方)
- 新增 docs/roadmap-research-features.md 科研功能路线图及实现状态
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
# Agent 架构硬化 — deepseek-harness 对齐改造
|
||||
|
||||
本文档记录 2026-08 的 agent 系统架构改造:以 deepseek-harness(DeepSeek
|
||||
开源的 agent harness,见 `libs/deepseek-harness`)验证过的架构不变量为
|
||||
参照,对本项目 agent 子系统的四项核心改造与若干升级。所有改动以
|
||||
"取其分层思想、不取其运行时插件树"为原则——本项目是垂直应用,
|
||||
Rust 的 trait + 注册表天然等价于 dsh 的 capability seam。
|
||||
|
||||
## 1. 统一 ReAct 引擎(消除四份手写循环)
|
||||
|
||||
**不变量**:仓库中有且仅有一个具体的 ReAct 循环实现(对应 dsh 的
|
||||
"agent-loop 是 harness 中唯一包含具体循环逻辑的包")。
|
||||
|
||||
- `src/agent/engine.rs`:`ReactEngine` 承载完整循环(取消检查 → 压缩 →
|
||||
预算/nag → 步数上限 → 后台通知 → LLM 调用含恢复阶梯 → 工具执行 → 循环)。
|
||||
- 行为差异通过组合字段注入而非分叉实现:
|
||||
|
||||
| 关注点 | lead(主代理) | subagent | teammate |
|
||||
|---|---|---|---|
|
||||
| SSE 事件 | `EventTap::channel` | `EventTap::prefixed(tx, "sub")` | `EventTap::none()` |
|
||||
| 持久化 | `DbMessageSink`(agent_name=lead) | `DbMessageSink`(agent_name=sub_xxx) | None |
|
||||
| AskUser 权限 | `AskPolicy::Interactive`(120s 挂起) | `AskPolicy::AutoDeny` | `AskPolicy::AutoDeny` |
|
||||
| 取消 | `CancelSource::Session`(DashMap) | 不可取消 | `CancelSource::Flag` |
|
||||
| 恢复阶梯/熔断/重复检测 | 共享(runtime 级 Arc) | 引擎局部实例 | 引擎局部实例 |
|
||||
|
||||
- 队友因此获得了与主代理对等的能力(错误恢复、压缩熔断、多槽重复检测)。
|
||||
- `streaming_executor.rs`(936 行零调用死代码)已删除。
|
||||
|
||||
## 2. 会话级运行时生命周期
|
||||
|
||||
**不变量**:runtime 状态属于会话而非请求。
|
||||
|
||||
`src/agent/runtime/session_registry.rs` 的 `SessionRuntimeRegistry`
|
||||
(挂在 `AppState.agent_runtimes`):
|
||||
|
||||
- 同一会话的请求复用同一 `AgentRuntime`——后台任务队列、压缩折叠日志、
|
||||
文件缓存、拒绝追踪器、压缩熔断器、prompt cache 不再随 HTTP 请求销毁
|
||||
(历史上"后台任务结果跨请求丢失、每 turn 重复压缩"两个 bug 的根因)。
|
||||
- 每会话一个 turn 互斥锁:并发请求 fail-loud 返回 409。
|
||||
- 空闲 2 小时的条目由后台清扫回收;会话删除时显式移除。
|
||||
- 会话 ID 在请求入口预分配(`create_or_resume_session_preallocated`),
|
||||
新会话的首个请求也能写入取消标记(修复 SSE 超时只 abort 不落标记)。
|
||||
- 模式回放:runtime 首次创建时从 DB 读取会话模式,后续请求不再因传参
|
||||
不同而静默切换行为。
|
||||
- 压缩递归守卫从进程级 `AtomicBool` 改为按 session_id 的集合守卫
|
||||
(`try_begin_compaction`/`end_compaction`),并发会话压缩互不干扰。
|
||||
|
||||
## 3. 会话事件日志(事件溯源的生命周期侧面)
|
||||
|
||||
**不变量**:模型可见 ⟺ 已日志化;turn/compaction 以日志化锁开闭。
|
||||
|
||||
新表 `agent_events`(migration 20260819000001)+
|
||||
`src/agent/runtime/session_events.rs`:
|
||||
|
||||
- `turn_start`/`turn_end`(含结构化终止原因 `reason_label`)、
|
||||
`compaction_start`/`compaction_end` 构成日志化锁。
|
||||
- 崩溃恢复不截断:`reconcile_interrupted` 检测开口的 start 事件并合成
|
||||
`interrupted` 关闭(对应 dsh "不伪造完成、但补写中断事实"的策略)。
|
||||
- `context_snapshot`:turn 内发生过压缩时,turn 结束保存折叠后上下文 +
|
||||
消息高水位 `base_message_id`;下一 turn 回放"快照 + id > base 的增量"
|
||||
(`context.rs::load_folded_history`),不再从原始消息重建后重新压缩。
|
||||
rewind/retry/branch 后快照作废(`remove_context_snapshots`)。
|
||||
|
||||
## 4. 工具契约集中化(消除散弹式修改)
|
||||
|
||||
**不变量**:工具的全部行为元数据声明在工具自身(AgentTool),消费方查询
|
||||
trait 而非维护平行的名字名单。
|
||||
|
||||
`AgentTool` 新增声明方法:
|
||||
|
||||
- `untrusted_output()` — 输出来自外部源需 `<untrusted_tool_result>` 包裹
|
||||
(原 `untrusted.rs` 按名列表);注册表查询不到工具时回退名字启发式。
|
||||
- `hardline_check(args)` — 参数级不可绕过拒绝(原 executor 按名路由)。
|
||||
- `causes_file_changes()` — 执行前触发 checkpoint 快照(原
|
||||
`CHECKPOINT_TRIGGER_TOOLS` 名单)。
|
||||
- `loop_signals() -> ToolSignals` — 循环行为信号(todo nag 重置/todos
|
||||
持久化/手动压缩请求),替代主循环对 `todo_write`/`compress_context`
|
||||
的按名特判。
|
||||
- 输出契约:`ToolOutput.value`(canonical JSON,机器消费:重放/审计/剪枝)
|
||||
+ `content`(模型侧 render 投影),value 随消息 metadata 持久化。
|
||||
样例:`search_papers`、`todo_write`。
|
||||
- 注册表测试从硬编码数量断言(`assert_eq!(defs.len(), 35)`)改为
|
||||
inventory 不变量断言(名字唯一/元数据完整/信号与身份一致),
|
||||
新增工具不再需要改测试。
|
||||
|
||||
## 5. 权限单调性(deny > ask > allow,只收紧不放松)
|
||||
|
||||
**不变量**:多源决策合并唯一入口 `permission::tighten(base, candidate)`:
|
||||
|
||||
- Deny 粘滞——任何层不能放行另一层已 Deny 的调用;
|
||||
- Ask 不可被放松为 Allow,可升级为 Deny;
|
||||
- executor 的 hook 请求、工具级声明、会话级规则全部经 `tighten` 合并;
|
||||
- 无人值守上下文(子代理/队友)的 AskUser fail-closed 自动拒绝
|
||||
(`AskPolicy::AutoDeny` + `engine::auto_deny_ask`)。
|
||||
|
||||
历史上与此语义重复且从未接线的 `resolve_permission_precedence` 已删除。
|
||||
|
||||
## 6. 上下文管理升级
|
||||
|
||||
- **KV-cache 纪律**:system prompt 只包含字节稳定 section;技能清单/
|
||||
项目记忆以 durable 动态上下文快照(user 消息)追加在历史尾部,哈希
|
||||
未变不重注入(`context.rs::build_initial_context` +
|
||||
`AgentRuntime::build_dynamic_context`)。
|
||||
- **记忆智能选择接线**:记忆条目 > 8 时走 `select_relevant_memories`
|
||||
(LLM 结构化选择 + 指数时间衰减,此前为零调用代码)。
|
||||
- **确定性剪枝**:`micro_compact` 对长工具结果保留头/尾预览
|
||||
(`prune_tool_result`),短结果仍为纯占位符。
|
||||
- **Spill 检索指引**:溢出 stub 携带工具名 + 明确取回路径(read_file +
|
||||
max_lines 分段)。
|
||||
- **Token 估算统一**:全循环使用 `compact::estimate_message_tokens`
|
||||
(CJK 加权),消除主循环 `len/3` 与 compact 两套口径。
|
||||
|
||||
## 7. 其他接线与修复
|
||||
|
||||
- **团队协作接线**:`spawn_teammate` 等 4 个工具经
|
||||
`ToolRegistry::new_with_team` 注册进会话 runtime(TeamManager 按
|
||||
session_key 初始化邮箱目录);队友注册表真正排除 subagent/spawn_teammate
|
||||
(原注释声称排除但未过滤)。
|
||||
- **Continuable 子代理**:`subagent` 工具新增 `agent_name` + `followup`
|
||||
参数——命名子代理历史持久化,followup 回放全部历史续话(dsh
|
||||
Activation 模型的冷恢复路径)。
|
||||
- **IdlePoller 接线**:`AGENT_AUTONOMOUS_ENABLED=true` 时启动自治轮询,
|
||||
经会话注册表获取 runtime(模式从 DB 回放)。
|
||||
- **重复检测多槽**:`DuplicateDetector` 连续通道 + 滑动窗口双通道,
|
||||
可检测 A/B 交替死循环(原单槽实现检测不到)。
|
||||
|
||||
## 不采用的设计(与理由)
|
||||
|
||||
- Cordis 运行时插件树 / bundle/patch/profile 配置组合层:服务于通用
|
||||
harness 的第三方插件生态,本项目是单二进制垂直应用。
|
||||
- Typert 类型图 RPC、host/client 双聚合、Python SDK:无对应需求。
|
||||
- 适配器休眠挂载、profiles 热重载:模型链固定。
|
||||
@@ -134,3 +134,4 @@ Agent 系统的所有可配置参数,按子系统分类。
|
||||
| `src/agent/compact.rs` (extract_memories_from_compaction) | `EXTRACT_MEMORY_ENABLED` (P3 压缩记忆桥接) |
|
||||
| `src/agent/memory/extraction.rs` (ExtractionConfig) | `EXTRACT_MEMORY_ENABLED`, `EXTRACT_MEMORY_THROTTLE_TURNS`, `EXTRACT_MEMORY_MAX_STEPS` |
|
||||
| `src/services/download.rs` | `OBSCURA_ALLOW_PRIVATE_NETWORK`(程序自动设置) |
|
||||
| `src/main.rs` (IdlePoller 启动门控) | `AGENT_AUTONOMOUS_ENABLED`(默认 false;true/1 时启用自治轮询,见 dsh-alignment.md §7) |
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
AstroResearch 内置了一个基于 **ReAct** (Thought → Action → Observation) 范式的科研智能体引擎 (`src/agent/`),参考 Claude Code 的分层设计。以下对各子系统的架构、数据流和内部逻辑进行完整说明。
|
||||
|
||||
> **架构演进**:2026-08 起,ReAct 循环的唯一实现在 `src/agent/engine.rs`
|
||||
> (`ReactEngine`,主代理/子代理/队友以不同注入组合复用);
|
||||
> `AgentRuntime` 按会话缓存复用(`SessionRuntimeRegistry`);
|
||||
> turn/compaction 生命周期与上下文快照落在 `agent_events` 事件日志。
|
||||
> 详见 [dsh-alignment.md](dsh-alignment.md)。
|
||||
|
||||
### 整体架构
|
||||
|
||||
```mermaid
|
||||
@@ -14,16 +20,18 @@ graph TD
|
||||
AskUser["问答 /api/chat/questions + /api/chat/answer"]
|
||||
end
|
||||
|
||||
subgraph Runtime["AgentRuntime — ReAct 引擎"]
|
||||
subgraph Runtime["AgentRuntime — 会话级编排"]
|
||||
RunTurn["run_turn() 主入口"]
|
||||
SP["SystemPrompt 组装器"]
|
||||
CtxBuild["Context Builder 上下文构建"]
|
||||
ReAct["ReAct 主循环"]
|
||||
Engine["ReactEngine 统一循环(engine.rs)"]
|
||||
Streaming["streaming.rs 流式处理"]
|
||||
Executor["executor.rs 并行执行"]
|
||||
Finalize["finalize.rs 会话收尾"]
|
||||
TokenBudget["token_budget.rs"]
|
||||
CircuitBreaker["circuit_breaker.rs"]
|
||||
SessionReg["SessionRuntimeRegistry 会话级缓存"]
|
||||
EventLog["agent_events 事件日志"]
|
||||
end
|
||||
|
||||
subgraph Tools["工具系统 (tools/)"]
|
||||
|
||||
Reference in New Issue
Block a user