feat(orchestration): Agent 架构升级 —— Prompt 分层 + Schema + 并行研究扇出#128
Conversation
D-13 · P0:按 OpenHands/LangGraph 验证过的稳定性分层模式重构系统 prompt。 **改前**:878 行平铺 INSTRUCTIONS 字符串,全部塞在 orchestrator.ts 里。 **改后**:8 个指令模块按稳定性排序注入,STABLE 前缀最大化 cache 命中。 模块结构: - instructions/language.ts STABLE · 输出语言规则(最高优先级) - instructions/tool-catalog.ts STABLE · 工具目录 + 描述 - instructions/pipeline.ts STABLE · 研究决策链路 + 质量门 + 迭代纪律 - instructions/strategy.ts STABLE · 下单流 + 策略协议 + 审批门 - instructions/market.ts MARKET · venue 路由 + 多空 + 时效性 + 归因 - instructions/style.ts STABLE · 页面上下文 + 语言风格 + 术语翻译 - instructions/divination.ts COND · 狐神签规则 - instructions/index.ts · buildInstructions() 组合引擎 prompt 功能等价(全部 16 个 section 校验通过),typecheck 零错误。 orchestrator.ts: 878 → 93 行。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
P1 基础:用 Zod 替代手写 type predicate(shape guard)。工具返回值格式有单一事实来源。 - Bar / BarsResult / Ticker - BacktestResult / BacktestMetrics - FactorScore / FactorScoreResult - Fundamentals - validateShape<T>() 校验工具函数 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
commit `467c988`(第四轮,第三轮 review 之后的两条 medium 修复)
第三轮 review 提的两条 medium 已核实修复,均正确、无新增回归:
其余:前三轮验证过的内容(prompt 分层排序 / STABLE 前缀化、 整体:无 must-fix,无新增 medium。LGTM,可以合并。 |
三项收益最大的优化: **P0 · 数据预取去重(延迟 -30%,服务端负载 -60%)** - 新增 AnalystContext:runner 前置拉取 K 线/基本面/因子快照 - 6 个 analyst 不再各自调 DataClient——共享一份预拉数据 - technical analyst 优先从 self._shared 读 bars + factor_snapshot - 预取失败 → shared=None → analyst 回退到自己拉(向后兼容) **P1 · 结构化输出:静默降级变可见** - _parse() 新增 stance_normalized / confidence_clamped / factors_dropped 警告日志 - LLM 返了非标准 stance(如 'bull' 被降级到 'neutral')→ 打 warning - confidence 超出 [0,1] 被 clamp → 打 warning - factor 校验被丢弃 → 打 warning + 记录 raw_count vs parsed_count **P2 · Manager 上下文压缩** - briefs 送 manager 前去掉 raw_excerpt(json.dumps(raw)[:500] × 6 = ~3000 字噪音) - key_points 限制到 3 条 - manager 有更多 token 预算用于真实推理 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
D-13 · P0:将研究从单体 deep_dive 调用升级为可选并行扇出。 核心变更: - 新增 research.parallel_dive tool:N 个视角并行跑深度研究 - 每个视角独立 LLM session,零交叉污染 - 默认最多 4 个视角(bull/bear/technical/macro) - 修复 shared/schemas.ts Zod record 类型定义 - 指令:tool-catalog 新增描述,pipeline step 1 改为二选一 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9efa851 to
2044c26
Compare
Deploying inalpha-web with
|
| Latest commit: |
467c988
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://c81087b9.inalpha-web.pages.dev |
| Branch Preview URL: | https://feat-agent-architecture-upgr.inalpha-web.pages.dev |
回应 PR #128 auto-review 的 major: **问题**:runtime_facts(含秒级 isoFull 时间戳)拼在 prompt 最前面, 位于全部 8 个 STABLE 模块之前。前缀缓存要求从第 0 字节起完全一致才命中, 每秒变化的时间戳让后面所有 STABLE 层 0% 命中——重构核心目的没兑现。 **修复**: - runtime_facts 从最前面挪到**最末尾**(STABLE 段成为稳定缓存前缀) - 去掉秒级 isoFull,只用 day 粒度 dateStr——一天内 prompt 完全不变, 跨天才失效一次 - 日期注入在末尾不影响 LLM 理解"今天几号"(system prompt 全文都在 context 里) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…allel_dive 测试 回应 PR #128 auto-review 的三条 medium: 1. **parallel_dive 复用 research.ts 的 SymbolSchema/TimeframeSchema** —— 导出两个 schema,删掉 parallel 里去掉正则的弱副本,避免两处漂移 2. **BacktestResultSchema 补 sharpe_ci 字段** —— pipeline.ts 用 sharpe_ci.includes_zero 作 promote 硬闸, 之前 schema 没声明会被 z.object strip 静默丢弃 → 闸失效 3. **补 research.parallel_dive 测试**(3 个) —— schema 2-4 视角边界 / 复用正则拒空格 / 部分 lane 失败时 succeeded/failed/errors 聚合正确性 全套 424 测试通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
修复 PR #128 CI 的 research mypy FAILURE(我引入的 8 个类型错误): - get_bars 用 from_ts/to_ts 关键字(原错传 as_of/lookback_days/positional) - 预取逻辑抽成 _prefetch_shared helper,每项独立 async 包装(gather 不再传 None) - AnalystContext.fundamentals/factor_snapshot 类型 list→dict (get_fundamentals / get_snapshot 返回单个 dict 非列表) - technical.py 因子快照统一按 dict 解析(预取路径 + 自拉路径同逻辑) - AnalystContext 补进 analysts/__init__ __all__ mypy 从 28 降回 20(= main baseline,我引入的错误清零)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…kback 统一 回应 PR #128 二轮 auto-review: **[major] parallel_dive 能力夸大修正** - 描述从"独立 LLM session/零交叉污染"改为如实说明:每条 lane 都是完整 deep_dive(同一套 analyst + 辩论),只是 userQuestion 措辞不同,本质是 同一证据链的 N 次带侧重采样,非独立视角推理 - tool description + tool-catalog + pipeline 三处同步改,明确要求 orchestrator 呈现时措辞"从不同提问角度看",别当客观独立结论 **[medium] 预取去重真正兑现 + 消费方对齐** - risk analyst 也接 shared.bars(与 technical 同一批 K 线,去重往返) - 去掉 fundamentals 预取:fundamental/valuation 用路由后 fund_venue, 与研究 venue 可能不同,预取版本对不上——AnalystContext 移除该字段 - macro 拉 FRED 序列是独立必需请求,不共享 **[medium] 因子 lookback 窗口统一** - 抽 factor_lookback_bars() helper,预取路径与 technical 自拉回退用同一表达式 - 消除"同一请求因基础设施是否可靠算出不同因子窗口"的漂移 **[medium] 补预取回归测试** - test_deep_dive_prefetch_dedups_shared_bars:断言预取命中后主标的 /bars 只打 1 次(technical+risk 读 shared 不自拉),锁住静默降级 research 141 测试全过,ruff 通过,mypy = main baseline(无新增)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
P2 送前压缩把 raw_excerpt 置 None 换 token 收益,但 manager._format_user_prompt 从未把 raw_excerpt 拼进 prompt——收益为零,却让每次 deep_dive 返回的 ResearchPlan.briefs[].raw_excerpt 恒为 None,排查 LLM 原始 JSON 解析异常时 这份 debug 数据被无条件丢弃。 改为:runner 直接传完整 briefs(保留 raw_excerpt + 完整 key_points 给调用方), 真正省 token 的 key_points 截断挪进 manager._format_user_prompt——只影响 prompt 字符串,不污染返回值。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
schemas.ts(173 行)此前零消费方零测试,shape 是否与真实 tool 输出匹配 无从验证。补 8 个用例覆盖 6 个 schema + validateShape 的 ok/error 分支, fixtures 对齐真实 tool 输出形状(bar 取自 data.get_bars mock),锁死意外改坏。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
回应 PR #128 auto-review 的 major: **问题**:runtime_facts(含秒级 isoFull 时间戳)拼在 prompt 最前面, 位于全部 8 个 STABLE 模块之前。前缀缓存要求从第 0 字节起完全一致才命中, 每秒变化的时间戳让后面所有 STABLE 层 0% 命中——重构核心目的没兑现。 **修复**: - runtime_facts 从最前面挪到**最末尾**(STABLE 段成为稳定缓存前缀) - 去掉秒级 isoFull,只用 day 粒度 dateStr——一天内 prompt 完全不变, 跨天才失效一次 - 日期注入在末尾不影响 LLM 理解"今天几号"(system prompt 全文都在 context 里) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…allel_dive 测试 回应 PR #128 auto-review 的三条 medium: 1. **parallel_dive 复用 research.ts 的 SymbolSchema/TimeframeSchema** —— 导出两个 schema,删掉 parallel 里去掉正则的弱副本,避免两处漂移 2. **BacktestResultSchema 补 sharpe_ci 字段** —— pipeline.ts 用 sharpe_ci.includes_zero 作 promote 硬闸, 之前 schema 没声明会被 z.object strip 静默丢弃 → 闸失效 3. **补 research.parallel_dive 测试**(3 个) —— schema 2-4 视角边界 / 复用正则拒空格 / 部分 lane 失败时 succeeded/failed/errors 聚合正确性 全套 424 测试通过。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
修复 PR #128 CI 的 research mypy FAILURE(我引入的 8 个类型错误): - get_bars 用 from_ts/to_ts 关键字(原错传 as_of/lookback_days/positional) - 预取逻辑抽成 _prefetch_shared helper,每项独立 async 包装(gather 不再传 None) - AnalystContext.fundamentals/factor_snapshot 类型 list→dict (get_fundamentals / get_snapshot 返回单个 dict 非列表) - technical.py 因子快照统一按 dict 解析(预取路径 + 自拉路径同逻辑) - AnalystContext 补进 analysts/__init__ __all__ mypy 从 28 降回 20(= main baseline,我引入的错误清零)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…kback 统一 回应 PR #128 二轮 auto-review: **[major] parallel_dive 能力夸大修正** - 描述从"独立 LLM session/零交叉污染"改为如实说明:每条 lane 都是完整 deep_dive(同一套 analyst + 辩论),只是 userQuestion 措辞不同,本质是 同一证据链的 N 次带侧重采样,非独立视角推理 - tool description + tool-catalog + pipeline 三处同步改,明确要求 orchestrator 呈现时措辞"从不同提问角度看",别当客观独立结论 **[medium] 预取去重真正兑现 + 消费方对齐** - risk analyst 也接 shared.bars(与 technical 同一批 K 线,去重往返) - 去掉 fundamentals 预取:fundamental/valuation 用路由后 fund_venue, 与研究 venue 可能不同,预取版本对不上——AnalystContext 移除该字段 - macro 拉 FRED 序列是独立必需请求,不共享 **[medium] 因子 lookback 窗口统一** - 抽 factor_lookback_bars() helper,预取路径与 technical 自拉回退用同一表达式 - 消除"同一请求因基础设施是否可靠算出不同因子窗口"的漂移 **[medium] 补预取回归测试** - test_deep_dive_prefetch_dedups_shared_bars:断言预取命中后主标的 /bars 只打 1 次(technical+risk 读 shared 不自拉),锁住静默降级 research 141 测试全过,ruff 通过,mypy = main baseline(无新增)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
概述
基于 Omnigent / OpenHands / Ruflo / Claude Code Workflows 等 8 个业界顶级 agent 产品的架构调研,对 Inalpha 编排层做三方面升级。
调研报告:
docs/research/claude-code-gui-ecosystem-2026.html改动
1. Prompt 分层注入
2. 共享领域 Schema
shared/schemas.ts:Zod 类型定义 Bar/Ticker/回测/因子/基本面validateShape<T>()替代手写 type predicate3. 并行多视角研究扇出
research.parallel_divetool不做的事
验证
pnpm typecheck零错误🤖 Generated with Claude Code