Files
AstroResearch/docs/architecture/agent/dsh-alignment.md
T
fmq d6b064a490 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 科研功能路线图及实现状态
2026-09-07 21:50:32 +08:00

133 lines
7.5 KiB
Markdown
Raw 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 架构硬化 — deepseek-harness 对齐改造
本文档记录 2026-08 的 agent 系统架构改造:以 deepseek-harnessDeepSeek
开源的 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` 注册进会话 runtimeTeamManager 按
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 热重载:模型链固定。