from .state import TravelState from .tools import get_transport_tools,get_hotel_tools,get_attraction_tools from langchain.agents import create_agent from llm import create_model from config import load_config config=load_config() llm = create_model(config) def coordinator_node(state: TravelState)->dict: return{} #路线agent节点 async def transport_agent_node(state: TravelState) -> dict: user_request= state["user_request"] tools=await get_transport_tools() agent = create_agent( model=llm, tools=tools, system_prompt="""你是旅行规划系统中的交通专家,只负责交通与市内通勤建议。 根据用户需求,必要时调用地图工具查询路线、距离或交通方式。 优先提供公共交通建议;用户明确自驾时再提供驾车建议。 若用户未提供出发地、日期等关键条件,应明确说明你的假设或待确认信息。 不得推荐酒店、景点或编造工具未返回的路线数据。 输出应包含:推荐交通方式、预计耗时、关键换乘/路线信息、出行提醒。""" ) result = await agent.ainvoke({"messages":[{"role":"user","content":user_request}]}) return {"transport_plan":result["messages"][-1].content} #酒店agent节点 async def hotel_agent_node(state:TravelState)->dict: user_request= state["user_request"] tools=await get_hotel_tools() agent = create_agent( model=llm, tools=tools, system_prompt="""你是旅行规划系统中的住宿专家,只负责查询与推荐住宿。 当用户给出了目的地时,必要时调用 hotel_search_and_recommend。 调用时: - destination 必填,从用户请求中提取城市、区域或地标; - query 传入完整用户原始需求; - scene 可映射为商务、亲子、度假、背包或通用; - 用户明确给出入住/退房日期时,才传 YYYY-MM-DD 格式的 check_in/check_out; - guests 取用户明确人数,未说明时可省略; - max_price 只在用户明确给出“每晚预算”时传入;总旅行预算不能直接当作每晚预算。 如果用户没有目的地,不调用工具,并要求补充目的地。 不得编造酒店名称、价格、位置、评分或是否有房。 推荐结果不代表已完成预订。 不得规划交通、景点或完整行程。 输出格式: 1. 推荐住宿 2. 每晚价格与位置 3. 适合原因 4. 需用户确认的信息""" ) result = await agent.ainvoke({"messages":[{"role":"user","content":user_request}]}) return {"hotel_plan":result["messages"][-1].content} #景点agent节点 async def attraction_agent_node(state:TravelState)->dict: user_request= state["user_request"] tools=await get_attraction_tools() agent = create_agent( model=llm, tools=tools, system_prompt="""你是旅行规划系统中的景点与活动专家,只负责景点推荐和游玩建议。 用户提供目的地时,必须调用地图工具查询景点或天气后再回答。 优先使用关键词搜索查找与用户偏好匹配的 POI。 需要了解特定地点时,使用详情搜索;需要查询某个地点周边内容时,先获得其坐标,再使用周边搜索。 根据天气工具结果给出合理出行提醒。 不得虚构景点地址、营业时间、门票、评分、距离或天气数据。 不得推荐酒店、规划交通路线或声称已完成预约。 输出应包含: 1. 推荐景点或区域; 2. 每个推荐的类型、位置或商圈信息; 3. 适合用户偏好的原因; 4. 天气与游玩提醒; 5. 需要用户确认的信息。""" ) result = await agent.ainvoke({"messages":[{"role":"user","content":user_request}]}) return {"attraction_plan":result["messages"][-1].content} #整合agent async def integrator_agent_node(state: TravelState) -> dict: user_request= state["user_request"] transport_plan=state.get("transport_plan") hotel_plan=state.get("hotel_plan") attraction_plan=state.get("attraction_plan") agent = create_agent( model=llm, tools=[], system_prompt="""你是旅行规划系统中的方案整合专家。 只能依据用户需求及交通、住宿、景点专家提供的结果生成方案。 不得自行调用工具、补充未经专家结果支持的酒店、路线、景点价格、天气或营业信息。 若专家结果冲突、缺失或信息不足,明确标记“待确认”,不要编造。 输出格式: 1. 旅行概览 2. 交通与市内通勤 3. 住宿建议 4. 每日行程建议 5. 注意事项与待确认事项""" ) compose_text=f"""【用户需求】{user_request} 【交通专家结果】 {transport_plan} 【住宿专家结果】 {hotel_plan} 【景点专家结果】 {attraction_plan} """ result=await agent.ainvoke({"messages":[{"role":"user","content":compose_text}]}) return {"final_plan":result["messages"][-1].content}