旅行智能推荐助手

一、准备工作

获取实时搜索的api:

tavily-python, AI 搜索 API 客户端,用于获取实时的网络搜索结果,可以在官网注册后获取 API。

我们先在终端创建一个新环境命名为ai-agent:(当时设置的镜像是清华源的,注意把梯子关了)

 conda create -n ai-agent python=3.11 -y

然后再激活环境

conda activate ai-agent

用国内的镜像源安装

pip install requests openai tavily-python -i https://pypi.tuna.tsinghua.edu.cn/simple

二、编写智能体并测试

打开vscode,选择我们刚刚创建的环境。

创建travel_agent.py文件

# travel_agent.py  智能旅行助手完整代码
import os
import re
import requests
from openai import OpenAI
from tavily import TavilyClient

# ====================== 1. 系统提示词(智能体的指令) ======================
AGENT_SYSTEM_PROMPT = """
你是一个智能旅行助手。你的任务是分析用户的请求,并使用可用工具一步步地解决问题。

# 可用工具:
- `get_weather(city: str)`: 查询指定城市的实时天气。
- `get_attraction(city: str, weather: str)`: 根据城市和天气搜索推荐的旅游景点。

# 输出格式要求:
你的每次回复必须严格遵循以下格式,包含一对Thought和Action:

Thought: [你的思考过程和下一步计划]
Action: [你要执行的具体行动]

Action的格式必须是以下之一:
1. 调用工具:function_name(arg_name="arg_value")
2. 结束任务:Finish[最终答案]

# 重要提示:
- 每次只输出一对Thought-Action
- Action必须在同一行,不要换行
- 当收集到足够信息可以回答用户问题时,必须使用 Action: Finish[最终答案] 格式结束
"""

# ====================== 2. 工具1:查询天气 ======================
def get_weather(city: str) -> str:
    url = f"https://wttr.in/{city}?format=j1"
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        data = response.json()
        current = data['current_condition'][0]
        desc = current['weatherDesc'][0]['value']
        temp = current['temp_C']
        return f"{city}当前天气:{desc},气温{temp}℃"
    except Exception as e:
        return f"天气查询失败:{str(e)}"

# ====================== 3. 工具2:景点推荐(Tavily搜索) ======================
def get_attraction(city: str, weather: str) -> str:
    api_key = os.environ.get("TAVILY_API_KEY")
    if not api_key:
        return "错误:未设置Tavily API Key"
    
    tavily = TavilyClient(api_key=api_key)
    query = f"{city} {weather}天气 适合去的旅游景点推荐"
    
    try:
        res = tavily.search(query=query, search_depth="basic", include_answer=True)
        return res.get("answer", "未找到推荐信息")
    except Exception as e:
        return f"景点搜索失败:{str(e)}"

# 工具注册
available_tools = {
    "get_weather": get_weather,
    "get_attraction": get_attraction
}

# ====================== 4. LLM 客户端 ======================
class OpenAICompatibleClient:
    def __init__(self, model: str, api_key: str, base_url: str):
        self.model = model
        self.client = OpenAI(api_key=api_key, base_url=base_url)

    def generate(self, prompt: str, system_prompt: str) -> str:
        print("\n→ 正在调用大模型...")
        try:
            messages = [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": prompt}
            ]
            resp = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                temperature=0.1
            )
            return resp.choices[0].message.content
        except Exception as e:
            return f"模型调用失败:{str(e)}"

# ====================== 5. 填写你的 KEY ======================
# 1. 大模型 API 信息
API_KEY = "替换成自己的"
BASE_URL = "替换成自己的"
MODEL_ID = "替换成自己的"

# 2. Tavily API Key(搜索景点用)
TAVILY_API_KEY = "替换成自己的"

os.environ["TAVILY_API_KEY"] = TAVILY_API_KEY

# 初始化LLM
llm = OpenAICompatibleClient(
    model=MODEL_ID,
    api_key=API_KEY,
    base_url=BASE_URL
)

# ====================== 6. 智能体主循环 ======================
if __name__ == "__main__":
    user_query = "你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。"
    history = [f"用户请求:{user_query}"]

    print("=" * 50)
    print("用户输入:", user_query)
    print("=" * 50)

    # 最多循环5次
    for round_num in range(5):
        print(f"\n===== 第 {round_num+1} 轮思考 =====")
        
        # 构造完整prompt
        full_prompt = "\n".join(history)
        
        # 调用LLM
        llm_response = llm.generate(full_prompt, AGENT_SYSTEM_PROMPT)
        print("模型输出:\n", llm_response)
        
        # 截断多余内容
        match = re.search(r"(Thought:.*?Action:.*?)(?=\nThought|\Z)", llm_response, re.DOTALL)
        if match:
            llm_response = match.group(1).strip()
        
        history.append(llm_response)

        # 解析Action
        action_match = re.search(r"Action: (.*)", llm_response)
        if not action_match:
            obs = "无法解析Action"
            history.append(f"Observation: {obs}")
            continue
        
        action = action_match.group(1).strip()

        # 如果是Finish,结束任务
        if action.startswith("Finish"):
            ans = re.findall(r"Finish\[(.*?)\]", action)[0]
            print("\n任务完成!最终回答:\n", ans)
            break

        # 解析工具名和参数
        tool_name = re.findall(r"(\w+)\(", action)[0]
        args = dict(re.findall(r'(\w+)="([^"]+)"', action))

        # 执行工具
        if tool_name in available_tools:
            obs = available_tools[tool_name](**args)
        else:
            obs = f"工具{tool_name}不存在"

        print(f"\nObservation: {obs}")
        history.append(f"Observation: {obs}")

我选用的大模型是qwen-turbo

打开阿里云百炼(通义千问平台):https://bailian.console.aliyun.com/

阿里云账号登录(没有就注册一个,要实名认证)

右上角进入 API Key 管理 → 创建 API Key

设置好后执行该文件。

最后输出:

(ai-agent) PS D:\Project\ai-agent> & C:\Users\HUANG\.conda\envs\ai-agent\python.exe d:/Project/ai-agent/travel_agent.py
==================================================
用户输入: 你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。
==================================================

===== 第 1 轮思考 =====

→ 正在调用大模型...
模型输出:
 Thought: 用户需要查询北京的天气,并根据天气推荐一个旅游景点。首先,我需要调用工具获取北京的实时天气。
Action: function_name=get_weather(city="北京")

Observation: 北京当前天气:Sunny,气温26℃

===== 第 2 轮思考 =====

→ 正在调用大模型...
模型输出:
 Thought: 现在我有了北京的天气信息,接下来我需要根据天气推荐一个合适的旅游景点。
Action: function_name=get_attraction(city="北京", weather="Sunny")

Observation: 北京天坛和颐和园在晴天特别适合游览,这两个地方有丰富的历史和美丽的景色。

===== 第 3 轮思考 =====

→ 正在调用大模型...
模型输出:
 Thought: 根据天气信息,我已找到适合的旅游景点。现在可以向用户推荐这些景点。
Action: Finish[北京今天天气晴朗,气温26℃,推荐您去北京天坛和颐和园游览,这两个地方在晴天特别适合,有丰富的历史和美丽的景色。]

任务完成!最终回答:
 北京今天天气晴朗,气温26℃,推荐您去北京天坛和颐和园游览,这两个地方在晴天特别适合,有丰富的历史和美丽的景色。
(ai-agent) PS D:\Project\ai-agent> 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐