【大模型】-LangChain--Agent

文章目录

多种工具组合

python 复制代码
import os
from typing import Dict, List, Any, TypedDict
from langchain.agents import create_agent, AgentState
from langchain.tools import tool
from langchain.messages import HumanMessage
from langchain_community.chat_models import ChatTongyi
from datetime import datetime
from dotenv import load_dotenv

load_dotenv()

# ============ 自定义状态定义 ============
class TravelAgentState(AgentState):
    """旅游助手 Agent 的自定义状态"""
    user_preferences: Dict[str, Any]
    conversation_history: List[Dict[str, str]]
    current_city: str

# ============ 使用 @tool 装饰器定义工具 ============

@tool
def weather_query(city: str) -> str:
    """查询城市天气信息。输入应该是城市名称,如'北京'或'上海'。
    返回该城市当前天气情况、温度、湿度等信息。"""
    try:
        # 模拟天气数据
        weather_data = {
            "北京": {"city": "北京", "weather": "晴", "temperature": "25°C",
                   "humidity": "45%", "wind": "东南风3级"},
            "上海": {"city": "上海", "weather": "多云", "temperature": "28°C",
                   "humidity": "65%", "wind": "东风2级"},
            "广州": {"city": "广州", "weather": "阵雨", "temperature": "30°C",
                   "humidity": "80%", "wind": "南风2级"},
            "杭州": {"city": "杭州", "weather": "晴转多云", "temperature": "26°C",
                   "humidity": "60%", "wind": "微风"},
        }

        if city in weather_data:
            data = weather_data[city]
            return f"""
{city}天气情况:
- 天气:{data['weather']}
- 温度:{data['temperature']}
- 湿度:{data['humidity']}
- 风速:{data['wind']}
- 更新时间:{datetime.now().strftime('%Y-%m-%d %H:%M')}
            """
        else:
            return f"未找到{city}的天气信息,请确认城市名称是否正确。"

    except Exception as e:
        return f"查询天气时出错:{str(e)}"

@tool
def attraction_recommendation(query: str) -> str:
    """推荐旅游景点。输入应该是城市名称和可选的主题或偏好,
    如'北京 历史'或'上海 美食'。
    返回该城市的推荐景点、评分和简介。"""
    try:
        # 解析查询参数
        parts = query.split()
        city = parts[0] if parts else ""
        preference = parts[1] if len(parts) > 1 else ""

        # 模拟景点数据
        attractions_db = {
            "北京": {
                "历史": [
                    {"name": "故宫", "rating": 4.8, "description": "明清两代的皇家宫殿", "type": "历史文化"},
                    {"name": "长城", "rating": 4.9, "description": "世界文化遗产,古代军事防御工程", "type": "历史遗迹"},
                    {"name": "天坛", "rating": 4.7, "description": "明清皇帝祭天祈谷的场所", "type": "历史建筑"}
                ],
                "公园": [
                    {"name": "颐和园", "rating": 4.8, "description": "皇家园林,风景秀丽", "type": "园林景观"},
                    {"name": "北海公园", "rating": 4.6, "description": "古典皇家园林", "type": "城市公园"}
                ]
            },
            "上海": {
                "现代": [
                    {"name": "外滩", "rating": 4.7, "description": "上海标志性景观,万国建筑博览", "type": "城市景观"},
                    {"name": "东方明珠", "rating": 4.6, "description": "上海地标性建筑", "type": "现代建筑"}
                ],
                "美食": [
                    {"name": "城隍庙", "rating": 4.5, "description": "上海小吃聚集地", "type": "美食文化"},
                    {"name": "田子坊", "rating": 4.4, "description": "文艺小资聚集地,特色小吃", "type": "文艺美食"}
                ]
            },
            "杭州": {
                "自然": [
                    {"name": "西湖", "rating": 4.9, "description": "人间天堂,风景如画", "type": "湖泊风光"},
                    {"name": "西溪湿地", "rating": 4.7, "description": "城市湿地公园", "type": "自然生态"}
                ]
            }
        }

        if city in attractions_db:
            recommendations = []
            if preference and preference in attractions_db[city]:
                recommendations = attractions_db[city][preference]
            else:
                # 如果没有指定偏好,返回所有景点
                for pref, attrs in attractions_db[city].items():
                    recommendations.extend(attrs)

            if recommendations:
                result = f"{city}推荐景点:\n"
                for i, attr in enumerate(recommendations[:5], 1):
                    result += f"{i}. {attr['name']}(评分:{attr['rating']})\n"
                    result += f"   类型:{attr['type']}\n"
                    result += f"   简介:{attr['description']}\n\n"
                return result
            else:
                return f"未找到{city}的{preference}相关景点推荐。"
        else:
            return f"暂无{city}的景点数据。"

    except Exception as e:
        return f"查询景点时出错:{str(e)}"

@tool
def trip_planner(query: str) -> str:
    """规划旅游行程。输入应该包含城市、天数、偏好等信息,
    如'北京 3天 历史'或'上海 2天 美食购物'。
    返回详细的行程安排。"""
    try:
        parts = query.split()
        if len(parts) < 2:
            return "请输入城市和天数,如'北京 3天'"

        city = parts[0]
        days = parts[1].replace("天", "")
        preference = parts[2] if len(parts) > 2 else "general"

        # 模拟行程数据
        sample_itineraries = {
            "北京": {
                "1": "第一天:上午参观故宫,下午游览天安门广场和王府井",
                "2": "第一天:上午参观故宫,下午游览天坛\n第二天:全天游览八达岭长城,晚上品尝北京烤鸭",
                "3": "第一天:上午参观故宫,下午游览天安门广场\n第二天:全天游览八达岭长城\n第三天:上午参观颐和园,下午逛什刹海胡同,晚上体验老北京文化"
            },
            "上海": {
                "1": "第一天:上午游览外滩,下午参观东方明珠,晚上逛南京路步行街",
                "2": "第一天:上午游览外滩和豫园,下午参观城隍庙\n第二天:上午参观上海博物馆,下午逛田子坊,晚上品尝本帮菜",
                "3": "第一天:外滩、南京路步行街\n第二天:豫园、城隍庙、上海博物馆\n第三天:迪士尼乐园或朱家角古镇"
            }
        }

        if city in sample_itineraries and days in sample_itineraries[city]:
            itinerary = sample_itineraries[city][days]
            return f"{city}{days}天{preference}主题行程建议:\n{itinerary}\n\n温馨提示:请根据实际情况调整,注意景区开放时间。"
        else:
            return f"暂无{city}{days}天的标准行程,建议结合天气和景点推荐自行规划。"

    except Exception as e:
        return f"规划行程时出错:{str(e)}"

# ============ 使用第三方包的工具示例 ============

@tool
def currency_converter(amount: float, from_currency: str, to_currency: str) -> str:
    """货币转换工具。输入:金额, 原货币, 目标货币,如'100, USD, CNY'"""
    try:
        # 模拟汇率数据
        rates = {
            "USD": {"CNY": 7.2, "EUR": 0.92, "JPY": 150},
            "CNY": {"USD": 0.14, "EUR": 0.13, "JPY": 21},
            "EUR": {"USD": 1.09, "CNY": 7.8, "JPY": 163}
        }

        if from_currency in rates and to_currency in rates[from_currency]:
            rate = rates[from_currency][to_currency]
            converted = amount * rate
            return f"{amount} {from_currency} = {converted:.2f} {to_currency} (汇率: 1 {from_currency} = {rate} {to_currency})"
        else:
            return f"不支持{from_currency}到{to_currency}的货币转换"

    except Exception as e:
        return f"货币转换失败:{str(e)}"

@tool
def get_local_food(city: str) -> str:
    """获取当地美食推荐。输入:城市名称"""
    try:
        food_db = {
            "北京": ["北京烤鸭", "炸酱面", "豆汁焦圈", "卤煮火烧", "炒肝", "爆肚"],
            "上海": ["小笼包", "生煎包", "本帮红烧肉", "蟹粉汤包", "油爆虾", "腌笃鲜"],
            "广州": ["早茶点心", "煲仔饭", "烧鹅", "肠粉", "云吞面", "白切鸡"],
            "成都": ["火锅", "串串香", "麻婆豆腐", "担担面", "夫妻肺片", "龙抄手"],
            "杭州": ["西湖醋鱼", "东坡肉", "龙井虾仁", "叫化鸡", "片儿川", "定胜糕"],
        }

        if city in food_db:
            return f"{city}特色美食推荐:\n" + "\n".join([f"- {food}" for food in food_db[city]])
        else:
            return f"暂无{city}的美食数据"

    except Exception as e:
        return f"查询美食时出错:{str(e)}"

# ============ 创建 Agent ============

def create_travel_agent():
    """创建旅游助手 Agent"""

    # 初始化通义千问模型
    llm = ChatTongyi(
        model="qwen-plus",
        temperature=0.1,
        max_tokens=2000
    )

    # 工具列表
    tools = [
        weather_query,
        attraction_recommendation,
        trip_planner,
        currency_converter,
        get_local_food
    ]

    # 系统提示词
    system_prompt = """你是一个专业的旅游助手,可以帮助用户:
    1. 查询城市天气信息
    2. 推荐旅游景点(可按主题筛选)
    3. 规划旅游行程
    4. 货币汇率转换
    5. 推荐当地特色美食
    
    请根据用户的需求,选择合适的工具来提供帮助。
    如果用户的问题需要多个信息,请按顺序使用相关工具。
    最后给出完整、有用的回答。"""

    # 使用 create_agent 创建 Agent(新版API)
    # 使用新版的create_agent(正确的参数)
    agent = create_agent(
        model=llm,                # 必需:模型实例或字符串标识
        tools=tools,              # 必需:工具列表
        system_prompt=system_prompt,  # 系统提示词
    )

    return agent

# ============ 测试函数 ============

def test_agent():
    """测试 Agent 的不同功能"""

    travel_agent = create_travel_agent()

    test_cases = [
        "北京今天的天气怎么样?",
        "我想去上海旅游,有什么推荐的景点吗?",
        "推荐一些杭州的自然风光景点",
        "帮我规划一个北京3天的行程",
        "我想去广州玩,先查一下天气,再推荐一些景点",
        "100美元能换多少人民币?",
        "成都有什么好吃的?"
    ]

    print("=" * 60)
    print("开始测试旅游助手Agent")
    print("=" * 60)

    for i, query in enumerate(test_cases, 1):
        print(f"\n测试 {i}: {query}")
        print("-" * 40)

        try:
            # 初始化状态
            initial_state = {
                "messages": [HumanMessage(content=query)],
                "user_preferences": {"language": "zh", "detail_level": "normal"},
                "conversation_history": [],
                "current_city": ""
            }

            # 调用 Agent
            result = travel_agent.invoke(initial_state)

            # 提取最终回答
            final_message = result["messages"][-1]
            print(f"助手回答:\n{final_message.content}")

        except Exception as e:
            print(f"执行出错:{e}")

# ============ 交互式对话 ============

def interactive_chat():
    """交互式对话模式"""

    travel_agent = create_travel_agent()

    print("=" * 60)
    print("旅游助手交互模式")
    print("输入 '退出' 结束对话")
    print("=" * 60)

    # 初始化状态
    state = {
        "messages": [],
        "user_preferences": {"language": "zh", "detail_level": "normal"},
        "conversation_history": [],
        "current_city": ""
    }

    while True:
        user_input = input("\n你:").strip()

        if user_input.lower() in ['退出', 'quit', 'exit', 'q']:
            print("感谢使用,再见!")
            break

        if not user_input:
            continue

        # 添加用户消息到状态
        state["messages"].append(HumanMessage(content=user_input))

        try:
            print("思考中...")

            # 调用 Agent
            result = travel_agent.invoke(state)

            # 更新状态
            state = result

            # 提取并显示助手的最新回复
            for msg in reversed(state["messages"]):
                if hasattr(msg, 'content') and msg.content and msg.content != user_input:
                    print(f"\n助手:{msg.content}")
                    break

        except Exception as e:
            print(f"出错:{e}")

# ============ 主程序 ============

if __name__ == "__main__":
    print("旅游助手 Agent 系统")
    print("=" * 40)
    print("1. 测试模式(运行预设测试)")
    print("2. 对话模式(交互式对话)")

    choice = input("\n请选择模式 (1/2): ").strip()

    if choice == "1":
        test_agent()
    else:
        interactive_chat()
相关推荐
世转神风-4 小时前
windows-ps1-脚本-删除文件
windows
TToolss5 小时前
新手使用frp,3端全部Windows
windows
普通网友5 小时前
24年9月最新微软copilot国内Windows11强制开启使用教程方法
windows·ai·微软·copilot
qq_420443275 小时前
AMD显卡在windows中通过WSL安装使用stable diffusion(WebUI和ComfyUI)
linux·windows·ubuntu·stable diffusion·wsl
凯子坚持 c5 小时前
本地文件深度交互新玩法:Obsidian Copilot的深度开发
microsoft·copilot·obsidian·蓝耘api
网安入门学习5 小时前
2025年AIGC人才需求报告:从招聘数据看行业趋势与技能要求
人工智能·windows·ai作画·stable diffusion·aigc
JH灰色6 小时前
【大模型】-LangChain多模态输入和自定义输出
java·前端·langchain
HLJ洛神千羽6 小时前
使用MediaCreationTool修复/升级到Windows10系统
windows
JH灰色6 小时前
【大模型】-LangChain自定义工具调用
数据库·langchain