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:
+36
-1
@@ -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=[],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user