feat: layered precise generation for A4 report images

3-phase pipeline to solve LLM prompt overflow from too many OCR elements:
Phase 1 (generate_skeleton): compressed layout schema → skeleton JRXML
Phase 2 (refine_layout): sampled coordinates → pixel-level position tuning
Phase 3 (map_fields): OCR field names → replace $F{field_N} placeholders

Only triggered when layout_schema.total_rows > 0 on initial_generation intent.
Text requests and all other intents are unaffected (zero behavior change).
This commit is contained in:
2026-05-21 08:34:32 +08:00
parent 9bb011e429
commit 43a0542a11
14 changed files with 882 additions and 81 deletions
+36 -1
View File
@@ -16,6 +16,9 @@ from agent.nodes import (
classify_intent,
retrieve,
generate,
generate_skeleton,
refine_layout,
map_fields,
modify_jrxml,
handle_consult,
handle_undo,
@@ -87,6 +90,15 @@ def route_by_intent(state: AgentState) -> Literal[
return "retrieve"
@_log_route("route_after_retrieve")
def route_after_retrieve(state: AgentState) -> Literal["generate", "generate_skeleton"]:
"""当 layout_schema 存在时走三层精确生成,否则走原有 1-shot。"""
layout_schema = state.get("layout_schema")
if layout_schema and isinstance(layout_schema, dict) and layout_schema.get("total_rows", 0) > 0:
return "generate_skeleton"
return "generate"
@_log_route("route_after_generate")
def route_after_generate(state: AgentState) -> Literal["save_session"]:
return "save_session"
@@ -158,6 +170,11 @@ def build_graph() -> StateGraph:
workflow.add_node("handle_undo", handle_undo)
workflow.add_node("handle_reset", handle_reset)
# 新增节点:分层精确生成(阶段一~三)
workflow.add_node("generate_skeleton", generate_skeleton)
workflow.add_node("refine_layout", refine_layout)
workflow.add_node("map_fields", map_fields)
# ---- 入口和前置流程 ----
workflow.set_entry_point("load_session")
workflow.add_edge("load_session", "process_input")
@@ -180,12 +197,28 @@ def build_graph() -> StateGraph:
)
# ---- 初始生成分支 ----
workflow.add_edge("retrieve", "generate")
workflow.add_conditional_edges(
"retrieve",
route_after_retrieve,
{
"generate": "generate",
"generate_skeleton": "generate_skeleton",
},
)
# 原有 1-shot 路径
workflow.add_conditional_edges(
"generate",
route_after_generate,
{"save_session": "save_session"},
)
# 分层精确生成 3 阶段路径
workflow.add_edge("generate_skeleton", "refine_layout")
workflow.add_edge("refine_layout", "map_fields")
workflow.add_conditional_edges(
"map_fields",
route_after_generate,
{"save_session": "save_session"},
)
# ---- 修改分支 ----
workflow.add_conditional_edges(
@@ -264,4 +297,6 @@ def create_initial_state() -> AgentState:
jrxml_versions=[],
last_error_case={},
pending_failure_context={},
layout_schema={},
ocr_elements=[],
)