| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- from __future__ import annotations
- """Trip Reviewer节点:调用TripReviewerAgent从风险角度独立评审行程,生成阻塞问题与优化建议。"""
- from typing import Any, Literal
- from app.agents.reviewer_agent import (
- TripReviewerAgent,
- )
- from app.graph.state import TravelState
- from app.schemas.review import TripReviewResult
- def route_after_validation(
- state: TravelState,
- ) -> Literal[
- "review_plan",
- "end",
- ]:
- """确定性校验执行后进入Reviewer。
- 即使方案校验失败,也允许Reviewer读取错误,
- 生成更完整的修改意见。
- """
- if state.get("errors"):
- return "end"
- if not state.get(
- "plan_validation_result"
- ):
- return "end"
- if not state.get("itinerary_plan"):
- return "end"
- return "review_plan"
- def _unique_feedback(
- values: list[str],
- ) -> list[str]:
- """对修改意见列表去重并去除空字符串,保持原有顺序。"""
- result: list[str] = []
- for value in values:
- normalized = value.strip()
- if (
- normalized
- and normalized not in result
- ):
- result.append(normalized)
- return result
- def make_trip_reviewer_node(
- agent: TripReviewerAgent,
- ):
- """创建Trip Reviewer节点。"""
- async def trip_reviewer_node(
- state: TravelState,
- ) -> dict[str, Any]:
- """评审节点:调用ReviewerAgent独立审查行程方案,将评审结论与修改意见写入state。"""
- attempts = (
- state.get("review_attempts", 0)
- + 1
- )
- validation = state[
- "plan_validation_result"
- ]
- try:
- result = await agent.review(
- request=state["travel_request"],
- plan=state["itinerary_plan"],
- validation=validation,
- map_result=state[
- "map_research_result"
- ],
- route_result=state[
- "route_evaluation_result"
- ],
- )
- structured_response = result.get(
- "structured_response"
- )
- if structured_response is None:
- message = (
- "Trip Reviewer没有返回"
- "结构化结果。"
- )
- existing_errors = list(
- state.get("errors", [])
- )
- existing_errors.append(message)
- return {
- "review_attempts": attempts,
- "reviewer_messages": (
- result.get("messages", [])
- ),
- "review_passed": False,
- "errors": existing_errors,
- "final_answer": message,
- }
- if not isinstance(
- structured_response,
- TripReviewResult,
- ):
- structured_response = (
- TripReviewResult.model_validate(
- structured_response
- )
- )
- # Reviewer不能覆盖Validator结果。
- review_passed = (
- validation.is_valid
- and structured_response.approved
- )
- combined_feedback = (
- validation.revision_feedback
- + structured_response
- .revision_feedback
- )
- combined_feedback = _unique_feedback(
- combined_feedback
- )
- if review_passed:
- combined_feedback = []
- message = (
- "Trip Reviewer审查通过:"
- f"发现"
- f"{len(structured_response.issues)}"
- "项非阻塞问题,"
- "方案可以进入最终输出阶段。"
- )
- else:
- message = (
- "Trip Reviewer审查未通过:"
- f"Validator错误"
- f"{validation.error_count}项,"
- "Reviewer发现"
- f"{len(structured_response.issues)}"
- "项问题;"
- "方案需要重新规划。"
- )
- return {
- "trip_review_result": (
- structured_response
- ),
- "reviewer_messages": result.get(
- "messages",
- [],
- ),
- "review_passed": review_passed,
- "review_attempts": attempts,
- "revision_feedback": (
- combined_feedback
- ),
- "final_answer": message,
- }
- except Exception as exc:
- message = (
- "Trip Reviewer执行失败:"
- f"{type(exc).__name__}: {exc}"
- )
- existing_errors = list(
- state.get("errors", [])
- )
- existing_errors.append(message)
- return {
- "review_attempts": attempts,
- "review_passed": False,
- "errors": existing_errors,
- "final_answer": message,
- }
- return trip_reviewer_node
|