agent 模式补充文件功能已经实现
This commit is contained in:
@@ -27,7 +27,6 @@ from typing import Any
|
||||
|
||||
from .. import get_logger
|
||||
from ..doc.llm_extractor import (
|
||||
CACHE_DIR_NAME,
|
||||
build_extraction_user_message,
|
||||
llm_query_text,
|
||||
load_cache,
|
||||
@@ -39,6 +38,7 @@ from ..doc.prompt import (
|
||||
build_travel_info_system_prompt,
|
||||
)
|
||||
from ..doc.validator import validate_extracted_info
|
||||
from ..pipeline_core import save_cache_info
|
||||
|
||||
log = get_logger("agent")
|
||||
|
||||
@@ -126,9 +126,26 @@ def load_agent_state(session_dir: Path) -> AgentSession | None:
|
||||
|
||||
AGENT_EVENT_LOG = "agent_events.log"
|
||||
|
||||
# 去重守卫:记录每个 session 上一次发射的事件类型,防止连续重复发射
|
||||
# key: str(session_dir), value: 上一次的 event_type
|
||||
_last_event_type: dict[str, str] = {}
|
||||
|
||||
|
||||
def _emit_agent_event(session_dir: Path, event_type: str, **kwargs: Any) -> None:
|
||||
"""向 agent_events.log 追加一行 JSON 事件。"""
|
||||
"""向 agent_events.log 追加一行 JSON 事件。
|
||||
|
||||
同一 session 连续发射相同 event_type 时直接抛出 RuntimeError,
|
||||
强制调用方修复重复发射的代码,而非静默掩盖。
|
||||
"""
|
||||
session_key = str(session_dir)
|
||||
prev = _last_event_type.get(session_key)
|
||||
if prev == event_type:
|
||||
raise RuntimeError(
|
||||
f"事件重复发射: session={session_dir.name!r}, event_type={event_type!r}。"
|
||||
f"请检查调用链,确保每个事件类型只发射一次。"
|
||||
)
|
||||
_last_event_type[session_key] = event_type
|
||||
|
||||
event = {"type": event_type, **kwargs}
|
||||
try:
|
||||
event_path = session_dir / AGENT_EVENT_LOG
|
||||
@@ -345,32 +362,16 @@ def run_agent_round(
|
||||
log.info("检测到补充文件,加载上一轮分析结果作为历史上下文")
|
||||
|
||||
try:
|
||||
if session.invoice_type == "travel":
|
||||
should_reanalyze = not cache_map.get("travel_info") or is_supplement
|
||||
if should_reanalyze:
|
||||
session.extracted_info = _do_extraction_with_validation(
|
||||
session_dir, session, previous_analysis=previous_analysis
|
||||
)
|
||||
# 提取后立即写入缓存,后续步骤依赖此数据
|
||||
cache_dir = session_dir / CACHE_DIR_NAME
|
||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
with open(cache_dir / "travel_info.json", "w", encoding="utf-8") as f:
|
||||
json.dump(session.extracted_info, f, ensure_ascii=False, indent=2)
|
||||
else:
|
||||
session.extracted_info = cache_map["travel_info"]
|
||||
info_key = "travel_info" if session.invoice_type == "travel" else "normal_info"
|
||||
should_reanalyze = not cache_map.get(info_key) or is_supplement
|
||||
if should_reanalyze:
|
||||
session.extracted_info = _do_extraction_with_validation(
|
||||
session_dir, session, previous_analysis=previous_analysis
|
||||
)
|
||||
# 提取后立即写入缓存,后续步骤依赖此数据
|
||||
save_cache_info(session_dir, info_key, session.extracted_info)
|
||||
else:
|
||||
should_reanalyze = not cache_map.get("normal_info") or is_supplement
|
||||
if should_reanalyze:
|
||||
session.extracted_info = _do_extraction_with_validation(
|
||||
session_dir, session, previous_analysis=previous_analysis
|
||||
)
|
||||
# 提取后立即写入缓存,后续步骤依赖此数据
|
||||
cache_dir = session_dir / CACHE_DIR_NAME
|
||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
with open(cache_dir / "normal_info.json", "w", encoding="utf-8") as f:
|
||||
json.dump(session.extracted_info, f, ensure_ascii=False, indent=2)
|
||||
else:
|
||||
session.extracted_info = cache_map["normal_info"]
|
||||
session.extracted_info = cache_map[info_key]
|
||||
|
||||
except Exception as e:
|
||||
session.state = AgentState.ERROR
|
||||
@@ -501,13 +502,9 @@ def process_user_text_supplement(
|
||||
)
|
||||
|
||||
# Step 3: 保存到缓存
|
||||
cache_dir = session_dir / CACHE_DIR_NAME
|
||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
info_file = "travel_info.json" if session.invoice_type == "travel" else "normal_info.json"
|
||||
info_path = cache_dir / info_file
|
||||
with open(info_path, "w", encoding="utf-8") as f:
|
||||
json.dump(session.extracted_info, f, ensure_ascii=False, indent=2)
|
||||
log.info("已更新 %s", info_file)
|
||||
info_key = "travel_info" if session.invoice_type == "travel" else "normal_info"
|
||||
save_cache_info(session_dir, info_key, session.extracted_info)
|
||||
log.info("已更新 %s", info_key)
|
||||
|
||||
# Step 4: 重新执行 Agent 校验
|
||||
session.state = AgentState.EXTRACTING
|
||||
|
||||
Reference in New Issue
Block a user