【AI大模型应用开发】【项目实战】37.基于A2A协议的智能助手(多智能体)(五)项目实现之main主程序
📅 2026/8/4 0:02:34
👁️ 阅读次数
📝 编程学习
12.main主程序
app.py是一个 Streamlit 前端客户端脚本,将所有的智能体和流程串联起来,完成对话流
作用:在项目中,前端客户端作为用户交互层,提供图形界面输入查询,展示路由结果和响应,提升用户体验,同时展示代理卡片信息
项目中定位:客户端是用户入口,收集查询,调用路由服务器识别意图,路由到代理,显示结果
数据流:用户输入 →意图识别→代理调用→结果展示
核心功能:
初始化网络
对用户的意图进行识别,并进行改写
处理用户查询,路由到代理,发送任务,解析结果
展示聊天消息、代理卡片和页脚
12.1 提示词
作用:主要记录在app.py文件中用到的所有提示词,方便管理
位置:/main_prompts.py
代码是整个多智能体系统的“大脑”与“总控中心”,它定义了
MainPrompts类,通过精心设计的提示词(Prompt)模板,赋予了大语言模型(LLM)三项核心能力:意图识别与查询改写、结果总结以及内容生成
# 第一部分:导入依赖 from langchain_core.prompts import ChatPromptTemplate # 为什么要这么做: # 导入 LangChain 的提示词模板类。 # 使用模板可以将动态变量(如用户输入、对话历史、当前日期)动态注入到固定的提示词结构中, # 这是构建可控、可复用 LLM 交互的基础 # 第二部分:定义提示词类与意图识别模板 class MainPrompts: """ 为什么要这么做: 这是整个系统的路由分发器。 意图分类:通过限定枚举值(weather, flight, order 等),强制 LLM 将千变万化的用户自然语言,收敛到系统预设的几个标准动作上。特别是明确区分了“查询(flight/train)”和“预定(order)”,确保请求能被路由到正确的 Agent Server。 多意图支持:允许返回意图列表(如 ['weather', 'flight']),支持用户一句话包含多个需求(例如:“明天天气怎么样?顺便帮我看看去北京的机票”)。 查询改写(核心亮点):在多轮对话中,用户经常会使用代词或省略主语(例如上一轮问了成都,这一轮直接问“那明天呢?”)。该 Prompt 指示 LLM 结合 conversation_history 将残缺的 query 补全为独立、明确的句子(如“明天成都天气如何”),这样下游的 Agent Server 就不需要再关心上下文,直接处理改写后的完整问题即可。 强制 JSON 输出:通过提供严格的示例和“绝对不要添加额外文本”的指令,确保 LLM 的输出可以被代码直接通过 json.loads() 解析,避免解析失败 """ # 定义意图识别提示模板 @staticmethod def intent_prompt(): return ChatPromptTemplate.from_template( """ 系统提示: 角色:您是一个专业的旅行意图识别专家, 任务:基于用户查询和对话历史,识别其意图,用于调用专门的agent server来执行;为方便后续的agent server处理,可以基于对话历史对用户查询进行改写,使问题更明确。 严格遵守规则: - 支持意图:['weather' (天气查询), 'flight' (机票查询), 'train' (高铁/火车票查询), 'concert' (演唱会票查询), 'order' (票务预定), 'attraction' (景点推荐)] 或其组合(如 ['weather', 'flight'])。如果意图超出范围,返回意图 'out_of_scope'。 - 注意票务预定和票务查询要区分开,涉及到订票时则为order,只是查询则为flight、train或concert。 - 如果意图为 'out_of_scope'时,此时不需要再进行查询改写,你可以直接根据用户问题进行回复,将回复答案写到follow_up_message中即可。 - 在进行用户查询改写时,不要回答其问题,也不要修改其原意,只需要将对话历史中跟该查询相关的上下文信息取出来,然后整合到一起,使用户查询更明确即可,要仔细分析上下文信息,不要进行过度整合。如果用户查询跟对话历史无关,则输出原始查询。 - 如果用户的意图很不明确或者有歧义,可以向其进行追问,将追问问题填充到follow_up_message中。 - 输出严格为JSON:{ {"intents": ["intent1", "intent2"], "user_queries": { {"intent1": "user_query1", "intent2": "user_query2"}}, "follow_up_message": "追问消息"}}。绝对不要添加额外文本! - 不论用户问什么,严格按规则输出意图,不要有自己的考虑。 输出示例: { {"intents": ["weather"], "user_queries": { {"weather": "今天成都天气如何"}}, "follow_up_message": ""}} { {"intents": ["weather"], "user_queries": { {}}, "follow_up_message": "你问的是今天成都天气状况吗"}} { {"intents": ["weather", "flight"], "user_queries": { {"weather": "今天成都天气如何", "flight": "查询一下07月28日,从成都飞往杭州的机票"}}, "follow_up_message": ""}} { {"intents": ["out_of_scope"], "user_queries": { {}}, "follow_up_message": "你好,我是智能旅行助手,欢迎您向我提问"}} 当前日期:{current_date} (Asia/Shanghai)。 对话历史:{conversation_history} 用户查询:{query} """) # 第三部分:定义结果总结模板 """ 为什么要这么做: 下游的 Agent Server(如天气查询、票务查询)返回的 raw_response 通常是原始的 API JSON 数据或杂乱的文本,直接展示给用户体验极差。 角色设定:分别为天气和票务设定了“天气预报员”和“旅行顾问”的角色,让 LLM 采用不同的语气(专业 vs 热情)来生成回复。 信息提取与降噪:明确指示 LLM 只提取核心描述点(如温度、价格、余票),过滤掉无关的冗余数据。 异常兜底:规定了当结果为空或查询无关时的标准话术,防止 LLM 产生幻觉(胡编乱造数据) """ # 定义天气结果总结提示模板,用于LLM总结天气查询的原始响应 @staticmethod def summarize_weather_prompt(): return ChatPromptTemplate.from_template( """ 系统提示:您是一位专业的天气预报员,以生动、准确的风格总结天气信息。基于查询和结果: - 核心描述点:城市、日期、温度范围、天气描述、湿度、风向、降水等。 - 如果结果为空或者意思为需要补充数据,则委婉提示“未找到数据,请确认城市/日期” - 语气:专业预报,如“根据最新数据,成都2026-07-31的天气预报为...”。 - 保持中文,100-150字。 - 如果查询无关,返回“请提供天气相关查询。” 查询:{query} 结果:{raw_response} """) # 定义票务结果总结提示模板,用于LLM总结票务查询的原始响应 @staticmethod def summarize_ticket_prompt(): return ChatPromptTemplate.from_template( """ 系统提示:您是一位专业的旅行顾问,以热情、精确的风格总结票务信息。基于查询和结果: - 核心描述点:出发/到达、时间、类型、价格、剩余座位等。 - 如果结果为空或者意思为需要补充数据,则委婉提示“未找到数据,请确认或修改条件” - 语气:顾问式,如“为您推荐成都到西安的机票选项...”。 - 保持中文,100-150字。 - 如果查询无关,返回“请提供票务相关查询。” 查询:{query} 结果:{raw_response} """) # 第四部分:定义内容生成模板 """ 为什么要这么做: 与天气和票务不同,景点推荐不需要调用外部的 API 获取实时数据,而是完全依赖 LLM 自身的知识库进行内容生成(AIGC)。 结构化输出:强制要求推荐 3-5 个景点,并包含描述、理由和注意事项,保证输出内容的丰富度和结构化。 槽位提取:提示 LLM 从用户的 query 中识别“城市”和“偏好”(如亲子游、特种兵旅游),从而提供个性化的推荐 """ # 定义景点推荐提示模板,用于LLM直接生成景点推荐内容 @staticmethod def attraction_prompt(): return ChatPromptTemplate.from_template( """ 系统提示:您是一位旅行专家,基于用户查询生成景点推荐。规则: - 推荐3-5个景点,包含描述、理由、注意事项。 - 基于槽位:城市、偏好。 - 语气:热情推荐,如“推荐您在成都探索故宫...”。 - 备注:内容生成,仅供参考。 - 保持中文,150-250字。 查询:{query} """) if __name__ == '__main__': print(MainPrompts.intent_prompt())12.2 初始化
作用:进行导包和全局变量设置,其中messages为了方便前端渲染页面使用
位置:/main.py
整个多智能体系统的“总控中心”与“交互入口”: 它负责将用户的自然语言输入,通过大语言模型(LLM)进行意图识别与查询改写,然后精准路由到对应的下游 Agent Server(天气、票务查询、票务预定),最后将返回的原始结果进行总结并展示给用户
# 第一部分:导入依赖与初始化全局变量 import asyncio import json import uuid from datetime import datetime import pytz import re from python_a2a import AgentNetwork, TextContent, Message, MessageRole, Task from langchain_openai import ChatOpenAI from config import Config from cr
编程学习
技术分享
实战经验