|
|
@@ -40,9 +40,10 @@ from llmops.workflow_state import (
|
|
|
update_state_with_planning_decision,
|
|
|
update_state_with_data_classified,
|
|
|
convert_numpy_types,
|
|
|
- update_state_with_data_standardize
|
|
|
+ update_state_with_data_standardize,
|
|
|
+ update_state_with_report
|
|
|
)
|
|
|
-from llmops.agents.outline_agent import generate_report_outline
|
|
|
+from llmops.agents.outline_agent import generate_report_outline
|
|
|
from llmops.agents.planning_agent import plan_next_action
|
|
|
from llmops.agents.rules_engine_metric_calculation_agent import RulesEngineMetricCalculationAgent
|
|
|
from llmops.agents.data_manager import DataManager
|
|
|
@@ -83,6 +84,7 @@ class CompleteAgentFlow:
|
|
|
workflow.add_node("metric_calculator", self._metric_calculator_node)
|
|
|
workflow.add_node("data_classify", self._data_classify_node)
|
|
|
workflow.add_node("data_standardize", self._data_standardize_node)
|
|
|
+ workflow.add_node("report_generator", self._report_generator_node)
|
|
|
|
|
|
# 设置入口点
|
|
|
workflow.set_entry_point("planning_node")
|
|
|
@@ -96,6 +98,7 @@ class CompleteAgentFlow:
|
|
|
"metric_calculator": "metric_calculator",
|
|
|
"data_classify": "data_classify",
|
|
|
"data_standardize": "data_standardize",
|
|
|
+ "report_generator": "report_generator",
|
|
|
END: END
|
|
|
}
|
|
|
)
|
|
|
@@ -105,6 +108,7 @@ class CompleteAgentFlow:
|
|
|
workflow.add_edge("data_classify", "planning_node")
|
|
|
workflow.add_edge("outline_generator", "planning_node")
|
|
|
workflow.add_edge("metric_calculator", "planning_node")
|
|
|
+ workflow.add_edge("report_generator", END)
|
|
|
|
|
|
return workflow
|
|
|
|
|
|
@@ -170,11 +174,11 @@ class CompleteAgentFlow:
|
|
|
if failed_attempts.get(mid, 0) < max_retries
|
|
|
]
|
|
|
|
|
|
- # 如果覆盖率 >= 80%,或者没有可重试的指标 → 结束流程
|
|
|
+ # 如果覆盖率 >= 80%,或者没有可重试的指标 → 生成报告
|
|
|
if coverage >= 0.8 or not retryable_metrics:
|
|
|
reason = "覆盖率达到80%" if coverage >= 0.8 else "没有可重试指标"
|
|
|
- print(f"→ 结束流程(覆盖率={coverage:.2%},原因:{reason})")
|
|
|
- return END
|
|
|
+ print(f"→ 指标计算完成,进入生成报告(覆盖率={coverage:.2%},原因:{reason})")
|
|
|
+ return "report_generator"
|
|
|
|
|
|
# 默认返回规划节点
|
|
|
return "planning_node"
|
|
|
@@ -319,7 +323,90 @@ class CompleteAgentFlow:
|
|
|
new_state["errors"].append(f"数据标准化错误: {str(e)}")
|
|
|
return convert_numpy_types(new_state)
|
|
|
|
|
|
+ async def _report_generator_node(self, state: IntegratedWorkflowState) -> IntegratedWorkflowState:
|
|
|
+ """报告完成节点:生成最终报告"""
|
|
|
+ try:
|
|
|
+ print("📋 正在生成最终报告...")
|
|
|
+
|
|
|
+ # 获取大纲和计算结果
|
|
|
+ outline = state.get("outline_draft")
|
|
|
+ computed_metrics = state.get("computed_metrics", {})
|
|
|
+ print(f"已经完成的计算指标:{computed_metrics}")
|
|
|
+
|
|
|
+ if not outline:
|
|
|
+ raise ValueError("没有可用的报告大纲")
|
|
|
+
|
|
|
+ # 生成最终报告
|
|
|
+ final_report = {
|
|
|
+ "title": outline.report_title,
|
|
|
+ "generated_at": datetime.now().isoformat(),
|
|
|
+ "summary": {
|
|
|
+ "total_sections": len(outline.sections),
|
|
|
+ "total_metrics_required": len(outline.global_metrics),
|
|
|
+ "total_metrics_computed": len(computed_metrics),
|
|
|
+ "planning_steps": state.get("planning_step", 0),
|
|
|
+ "completion_rate": len(computed_metrics) / len(
|
|
|
+ outline.global_metrics) if outline.global_metrics else 0
|
|
|
+ },
|
|
|
+ "sections": [],
|
|
|
+ "metrics_detail": {}
|
|
|
+ }
|
|
|
+
|
|
|
+ # 构建章节内容
|
|
|
+ for section in outline.sections:
|
|
|
+ section_content = {
|
|
|
+ "section_id": section.section_id,
|
|
|
+ "title": section.title,
|
|
|
+ "description": section.description,
|
|
|
+ "metrics": {}
|
|
|
+ }
|
|
|
+
|
|
|
+ # 添加该章节的指标数据
|
|
|
+ for metric_id in section.metrics_needed:
|
|
|
+ if metric_id in computed_metrics:
|
|
|
+ section_content["metrics"][metric_id] = computed_metrics[metric_id]
|
|
|
+ else:
|
|
|
+ if not metric_id.startswith("metric-"):
|
|
|
+ # 指标缺少metric前缀,进行补充
|
|
|
+ section_content["metrics"][metric_id] = computed_metrics["metric-"+metric_id]
|
|
|
+ else:
|
|
|
+ section_content["metrics"][metric_id] = "数据缺失"
|
|
|
+
|
|
|
+ final_report["sections"].append(section_content)
|
|
|
+
|
|
|
+ # 添加详细的指标信息
|
|
|
+ for metric_req in outline.global_metrics:
|
|
|
+ metric_id = metric_req.metric_id
|
|
|
+ final_report["metrics_detail"][metric_id] = {
|
|
|
+ "name": metric_req.metric_name,
|
|
|
+ "logic": metric_req.calculation_logic,
|
|
|
+ "required_fields": metric_req.required_fields,
|
|
|
+ "computed": metric_id in computed_metrics,
|
|
|
+ "value": computed_metrics.get(metric_id, {}).get("value", "N/A")
|
|
|
+ }
|
|
|
+
|
|
|
+ # 更新状态
|
|
|
+ new_state = update_state_with_report(state, final_report)
|
|
|
+
|
|
|
+ # 添加完成消息
|
|
|
+ new_state["messages"].append({
|
|
|
+ "role": "assistant",
|
|
|
+ "content": f"🎉 完整报告生成流程完成:{outline.report_title}",
|
|
|
+ "timestamp": datetime.now().isoformat()
|
|
|
+ })
|
|
|
+
|
|
|
+ print(f"✅ 最终报告生成完成:{outline.report_title}")
|
|
|
+ print(f" 章节数:{len(final_report['sections'])}")
|
|
|
+ print(f" 计算指标:{len(computed_metrics)}/{len(outline.global_metrics)}")
|
|
|
+ print(".2%")
|
|
|
|
|
|
+ return convert_numpy_types(new_state)
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ print(f"❌ 报告完成失败: {e}")
|
|
|
+ new_state = state.copy()
|
|
|
+ new_state["errors"].append(f"报告完成错误: {str(e)}")
|
|
|
+ return convert_numpy_types(new_state)
|
|
|
|
|
|
def _print_ai_selection_analysis(self, outline):
|
|
|
"""打印AI指标选择的推理过程分析 - 完全通用版本"""
|
|
|
@@ -740,6 +827,7 @@ async def main():
|
|
|
)
|
|
|
|
|
|
print(f"📋 结果: {'✅ 成功' if result.get('success') else '❌ 失败'}")
|
|
|
+ print(f"{result}")
|
|
|
|
|
|
if result.get('success'):
|
|
|
summary = result.get('execution_summary', {})
|