- 门控:用户提供 existing_system 路径 → 进入影响调查;未提供 → 原流程不变
- CodeParser 解析 Java(@RestController/@Service/@Entity/@TableName)+ ExistingSystemExplorer 组装
- ImpactAgent 变更点定位(变更区分×既存対応 确定性比对,无 LLM)→ ImpactReport(JSON 可下载)
- 影响调查结果作为 Writer 生成概要设计书的主上下文({{impact}},无专用影响章)
- source_aggregator 解除 existing_system=None 硬编码
- 既有系统样本 sunOnly/stock-trade-system(无 LICENSE,仅测试输入,保留来源标注)
- 新造股票交易域追加改修样本 要件定義_追加改修_股票.xlsx(对齐 sunOnly 真实类名)
- 全量 351 passed / 99.27% 覆盖;门禁 PASS(16 要素:新规5/変更8/削除3/未受影响50)
8.3 KiB
8.3 KiB
Impact Agent MVP 设计(2026-08-23)
背景
用户指出:写概要设计书需要「根据要件定义书 + 既有系统的设计与代码做影响调查 → 确定修改范围」。当前
source_aggregator.py 硬编码 existing_system=None,无 Impact Agent 实现。本次实现 MVP 变更点定位 + 影响书。
关键用户决策(brainstorming 确认):
- 场景 = 追加改修(需影响调查)
- 既有系统输入形态 = Java 项目源码
- 既有系统样本 =
samples/existing-system/(sunOnly/stock-trade-system,股票量化交易系统,无 LICENSE, 仅作测试输入,保留来源标注) - 里程碑范围 = MVP:解析既有系统 → 变更点定位 → 影响书(JSON);不做 LLM 要素抽取/关联推理
- 样本同域化:新造
samples/要件定義_追加改修_股票.xlsx(股票交易域,对齐 sunOnly 真实模块) - 门控:是否提供
existing_system路径决定是否进入影响调查阶段(非章节级) - 范围确认:进入影响调查前与用户确认调查范围(模块/深度)
- 消费模型:
ImpactReport是生成概要设计书的主上下文——整本概要设计书基于影响调查结果生成, 无专用影响章、无{{section:impact}}锚点门控;ImpactReport同时作为可下载独立产物
架构与数据流
要件定義_追加改修_股票.xlsx(新造) samples/existing-system/(sunOnly 源码)
│ 现有 ExcelParser │ 新增 CodeParser(Java 解析)
▼ ▼
StructuredSource.tables CodeStructure → ExistingSystemInfo
│ │
└──────────────┬───────────────────────────┘
▼
ImpactAgent(变更点定位,确定性比对)
- 取 変更区分 + 既存対応 列
- 与 ExistingSystemInfo 连接比对(存在性校验)
▼
ImpactReport(JSON 中间产物,可下载)
▼
WriteOrchestrator.generate(impact_report)
- ImpactReport 作为主上下文喂给 WriterAgent
- 整本概要设计书基于影响结果生成
门控与范围确认
- 门控(流水线级):
SourceParser.parse(existing_system_path=...)提供路径 ⇒StructuredSource.existing_system非 None ⇒ 进入影响调查;WriteOrchestrator.generate检测到existing_system非 None 且未显式传impact_report时,自动运行ImpactAgent生成影响书。 - 范围确认(human-in-loop):MVP 默认范围 = 提供的整个目录树(全模块、Controller/Service/Entity/Endpoint 全层);
可按参数收窄(
modules/depth)。完整 UI 确认留后续。 - 门控降级:CodeParser 失败(非 Java/无源码)⇒ 跳过影响调查并告警,生成照常(无 ImpactReport)。
变更点定位规则(确定性,无 LLM)
| 要件情况 | 判定 |
|---|---|
| 新規 + 既存対応空 | new(确认新增) |
| 新規 + 既存対応指定 | conflict 告警(自相矛盾) |
| 変更 + 既存対応命中且类存在 | modified(受影响既有类 = 映射清单) |
| 変更 + 既存対応缺失/类不存在 | warning(无法定位修改对象) |
| 削除 + 既存対応命中 | deleted(确认删除) |
| 削除 + 既存対応缺失/类不存在 | warning |
| 既有类未被任何要件引用 | unchanged(summary 计数) |
既存対応 列值 = Controller/Service/Entity 类名(逗号分隔);命中判定为类名出现在
ExistingSystemInfo 三层清单中(不区分大小写,后缀 Controller/Service/Entity 可选)。
数据模型(data_models.py 新增)
class ChangeType(Enum):
NEW = "新規"; MODIFIED = "変更"; DELETED = "削除"; UNCHANGED = "不变"
@dataclass
class ChangeElement:
element_id: str; element_type: str; name: str
change_type: ChangeType
existing_mapping: list[str] # 既存対応 声明值
impacted_existing: list[str] # 确认命中的既有类
evidence: str # 既有类 source_uri / 空
status: str # "ok" | "conflict" | "warning"
@dataclass
class ImpactWarning:
element_id: str; issue: str
@dataclass
class ChangeAnalysis:
project_type: str # "enhancement"
new_elements: list[ChangeElement]
modified_elements: list[ChangeElement]
deleted_elements: list[ChangeElement]
unchanged_elements: list[ChangeElement]
warnings: list[ImpactWarning]
@dataclass
class ImpactReport:
metadata: dict
change_analysis: ChangeAnalysis
summary: dict
组件
src/genesis/impact/code_parser.py(新)
CodeParser.parse(root_path) -> CodeStructure:扫描**/*.java,按注解识别:@RestController|@Controller→ ControllerInfo(base_path 取@RequestMapping,endpoints 取方法级映射)@Service→ ServiceInfo(methods)@Entity|@Table(name=...)→ EntityInfo(table_name、fields)- 方法映射 → EndpointInfo
- 顶层目录 → modules;失败(无 Java/路径无效)→ 抛
CodeParseError
src/genesis/impact/existing_system_explorer.py(新)
ExistingSystemExplorer.explore(code: CodeStructure) -> ExistingSystemInfo
src/genesis/impact/impact_agent.py(新)
ImpactAgent.run(structured_source, scope=None) -> ImpactReport- 从
tables提取带変更区分/既存対応列的表行 → 按上表规则分类 → summary
src/genesis/parsers/source_aggregator.py(改)
parse(..., existing_system_path=None):提供路径时解析并填充existing_system
src/genesis/writer/(改)
GenerationContext新增impact_report: object | None = None;to_vars()增加"impact"变量WRITER_PROMPT_TEMPLATE增加影响调查上下文:\n{{impact}}\n(在参考资料前)context_builder.build_contexts从structured_source.impact_report透传WriteOrchestrator.generate(..., impact_report=None):门控自动跑ImpactAgent;上下文携带影响书StructuredSource新增impact_report: ImpactReport | None = None(生成后回填,便于 QA/日志)
错误处理
CodeParseError(非 Java/无源码/路径无效)→ 门控降级跳过 + 告警既存対応引用不存在 →warning,不阻断新規却映射既有 →conflictwarning
测试策略(TDD,全量 ≥99%)
tests/test_data_models.py:新增 ImpactReport 模型默认值/构造tests/test_code_parser.py:用samples/existing-system真实文件断言提取(类名/数量/路径)tests/test_existing_system_explorer.py:组装 ExistingSystemInfo 分层tests/test_impact_agent.py:给定 要件定義(新造样本)+ ExistingSystemInfo → 断言分类tests/test_source_aggregator.py:existing_system_path加载;无效路径降级/报错tests/test_phase5_models.py:更新test_generation_context_no_impact_field→ 断言impact变量存在且为空tests/test_phase5_writer_agent.py:断言模板含影响上下文变量tests/test_phase5_writer_orchestrator.py:传 impact_report → 断言variables["impact"]含影响信息- 门禁(fake 模式):sunOnly + 新造样本端到端产出 ImpactReport + 概要设计书
新造样本规格
samples/要件定義_追加改修_股票.xlsx(股票交易域,对齐 sunOnly 真实模块):
- 機能一覧:F001 止损风控机能(新規,无既存対応) / F002 订单状态查询扩展(変更→OrderController,OrderQueryService) / F003 实时行情显示扩展(変更→RealtimeMarketDataController) / F004 旧回测机能(削除→StrategyBacktestController)
- 画面一覧(对应画面 + 変更区分)/DB定義(新規 止损设定表/変更 订单表/削除 旧回测表)/IF定義(新規 风控告警连携IF)
- 各表新增
既存対応列(类名或留空)+変更区分列 改修ポイント自由文本(改修概要)
里程碑外(后续)
- LLM 要素抽取 / 关联推理 / 影响矩阵
- v1→用户逐条修正→v2 生命周期 UI
- 范围确认 UI / API 化