你还在一步步教AI做事?现在流行的是:告诉Agent目标,然后放手让它自己完成。

过去一年,AI给我们的震撼已经足够多。但现在,一个更重要的转变正在发生:AI不再只是等着回答问题,而是开始主动为我们做事了。

这就是智能体的崛起。

我们正从“向AI提问”的时代,快步走向“让AI行动”的时代。让我们来一起学习了解习智能体吧,让你不仅仅是一个AI的使用者,更成为指挥AI行动的构建者。

什么是智能体(Agent)?

简单来说,智能体就是一个能够感知环境、进行决策并采取行动,以达成特定目标的系统。

你可以把它想象成一个数字化的“助手”或“代表”,它被赋予了一个任务,然后它会自主地去思考并执行,而不需要你每一步都下达详细的指令。

一个智能体通常包含三个核心部分:

  1. 感知: 它能通过传感器、数据接口或用户输入来“观察”和获取周围环境的信息。
  2. 决策: 它有一个“大脑”(通常是算法或模型),能够分析感知到的信息,思考该做什么,并制定行动计划。
  3. 行动: 它通过执行器、输出接口或具体操作来影响环境,从而向目标迈进。

举一个生动的例子:智能家居管家

想象一下你家里有一个高级的智能家居系统,它就是一个智能体。

  • 它的目标: 维持室内舒适的环境,并尽可能节省能源。
  • 它的“身体”: 遍布家中的温度、湿度、光线传感器,以及可以控制的空调、加湿器、电动窗帘。

现在,我们来看它在一个下午的工作流程:

  1. 感知
    • 温度传感器感知到室内温度升高到了28°C。
    • 光线传感器感知到西晒的阳光非常强烈。
    • 湿度传感器感知到空气干燥。
    • 它的“大脑”也从互联网上获取了当前时间(下午3点)和天气预报(今晚有雨)。
  1. 决策
    • “大脑”开始分析:“温度28°C,太热了,用户设定的舒适温度是24°C。阳光太强是主要原因,而且空气也很干燥。”
    • 它制定了一个行动计划:
      • 第一步: 先关闭电动窗帘,阻挡阳光,这是最节能的降温方式。
      • 第二步: 如果15分钟后温度还是高于25°C,就打开空调,设定为24°C。
      • 第三步: 同时,因为空气干燥,启动加湿器。
  1. 行动
    • 它向电动窗帘发出指令,窗帘自动关闭。
    • 15分钟后,温度传感器显示26°C,它向空调发出指令,空调开始制冷。
    • 它同时向加湿器发出指令,加湿器开始工作。
  1. 持续循环
    • 空调运行一段时间后,温度传感器显示已达到24°C。
    • 智能体再次感知到这个变化,于是决策行动:调高空调风速或暂时关闭,以防止过度制冷,节约电能。

在这个例子中:

  • 你没有给出任何即时指令(比如“太热了,开空调”)。
  • 这个智能家居系统作为一个智能体,自主地、有目标地完成了整个任务。

智能体并非一次性完成任务,而是通过一个持续的循环与环境进行交互,这个核心机制被称为 智能体循环 (Agent Loop)。如下图所示,该循环描述了智能体与环境之间的动态交互过程,构成了其自主行为的基础。

相信你看到这里,也会觉得前面内容很枯燥吧,其实前面内容了解即可,重要的是会应用。

下面让我们来花五分钟动手从零构建第一个智能体吧。我要讲解的是构建智能旅行助手。

目标是要解决的用户任务定义为:"你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。"

它厉害在哪?你只需要说一句:
“帮我查下北京今天天气,然后推荐个合适景点”

接下来,就是见证奇迹的时刻:

第一秒,它独立思考:“得先查天气”
下一秒,它自动调用天气API
第三秒,它根据“晴天26度”的结果,自动搜索匹配景点
最后,它把完整的旅行方案呈现在你面前

全程自动,无需你插手!这就是正在爆发的智能体(Agent) 技术。

和我一起创造你的第一个“数字员工”

其实吧智能体也没大家想的那么神秘,他的核心就是让AI学会“三步走”:

  1. 思考(Thought):分析该做什么
  2. 行动(Action):调用工具执行
  3. 观察(Observation):根据结果调整

就像训练一个实习生:

  • 你给他工具箱(查天气、搜攻略)
  • 教他工作流程(先查天气再推荐)
  • 然后就能放手让他独立完成任务!

我用短短50行Python代码就实现了这个智能旅行管家。最关键的是,这个思路能无限扩展:

  • 想做个自动报税助手?加上财税工具就行
  • 想要智能客服?接入产品数据库就好
  • 甚至可以做私人投资顾问...
Step1:前期准备

1.1 安装必要的Python库

使用代码

pip install requests tavily-python openai

或者直接添加

1.2 获取API密钥

  1. Tavily API密钥

Step2:完整代码实现

创建名为 travel_agent.py 的文件,并复制以下完整代码:

# import os
# import requests
# import re
# import json
# from tavily import TavilyClient
#
# # ==================== 配置区域 ====================
# TAVILY_API_KEY = "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"  # 你的Tavily密钥
# OLLAMA_BASE_URL = "http://localhost:11434"  # Ollama基础地址(无需加/v1或/api)
# MODEL_NAME = "llama2"  # 已下载的Ollama模型名
#
# # ==================== 系统提示 ====================
# AGENT_SYSTEM_PROMPT = """
# 你是一个智能旅行助手。你的任务是分析用户的请求,并使用可用工具一步步地解决问题。
#
# # 可用工具:
# - `get_weather(city: str)`: 查询指定城市的实时天气。
# - `get_attraction(city: str, weather: str)`: 根据城市和天气搜索推荐的旅游景点。
#
# # 行动格式:
# 你的回答必须严格遵循以下格式。首先是你的思考过程,然后是你要执行的具体行动。
# Thought: [这里是你的思考过程和下一步计划]
# Action: [这里是你要调用的工具,格式为 function_name(arg_name="arg_value")]
#
# # 任务完成:
# 当你收集到足够的信息,能够回答用户的最终问题时,你必须使用 `finish(answer="...")` 来输出最终答案。
#
# 请开始吧!
# """
#
#
# # ==================== 工具函数 ====================
# def get_weather(city: str) -> str:
#     """通过 wttr.in API 查询实时天气"""
#     url = f"https://wttr.in/{city}?format=j1"
#     try:
#         response = requests.get(url)
#         response.raise_for_status()
#         data = response.json()
#         current_condition = data['current_condition'][0]
#         weather_desc = current_condition['weatherDesc'][0]['value']
#         temp_c = current_condition['temp_C']
#         return f"{city}当前天气:{weather_desc},气温{temp_c}摄氏度"
#     except requests.exceptions.RequestException as e:
#         return f"错误:查询天气时遇到网络问题 - {e}"
#     except (KeyError, IndexError) as e:
#         return f"错误:解析天气数据失败,可能是城市名称无效 - {e}"
#
#
# def get_attraction(city: str, weather: str) -> str:
#     """通过 Tavily API 推荐景点"""
#     api_key = TAVILY_API_KEY
#     if not api_key or api_key == "YOUR_TAVILY_API_KEY":
#         return "错误:请先配置TAVILY_API_KEY。"
#     tavily = TavilyClient(api_key=api_key)
#     query = f"'{city}' 在'{weather}'天气下最值得去的旅游景点推荐及理由"
#     try:
#         response = tavily.search(query=query, search_depth="basic", include_answer=True)
#         if response.get("answer"):
#             return response["answer"]
#         formatted_results = []
#         for result in response.get("results", []):
#             formatted_results.append(f"- {result['title']}: {result['content']}")
#         return "根据搜索,为您找到以下信息:\n" + "\n".join(formatted_results) if formatted_results else "抱歉,没有找到相关的旅游景点推荐。"
#     except Exception as e:
#         return f"错误:执行Tavily搜索时出现问题 - {e}"
#
#
# # ==================== Ollama客户端(彻底强制CPU) ====================
# class OllamaClient:
#     def __init__(self, model: str, base_url: str):
#         self.model = model
#         self.base_url = base_url
#         self.headers = {"Content-Type": "application/json"}
#
#     def generate(self, prompt: str, system_prompt: str) -> str:
#         print("正在调用大语言模型(CPU推理)...")
#         try:
#             data = {
#                 "model": self.model,
#                 "messages": [
#                     {"role": "system", "content": system_prompt},
#                     {"role": "user", "content": prompt}
#                 ],
#                 "stream": False,
#                 "options": {
#                     "gpu": 0,  # 0 = 禁用GPU(必须)
#                     "num_ctx": 512,  # 进一步降低上下文长度(512足够,内存占用更少)
#                     "num_thread": 2,  # 限制CPU线程数(2-4即可,避免内存峰值过高)
#                     "batch_size": 32  # 减小批次大小,降低内存消耗
#                 }
#             }
#             # 延长超时到90秒(CPU推理慢,避免超时)
#             response = requests.post(
#                 url=f"{self.base_url}/api/chat",
#                 headers=self.headers,
#                 json=data,
#                 timeout=90
#             )
#             response.raise_for_status()
#             result = response.json()
#             return result["message"]["content"] if "message" in result else f"模型返回异常:{str(result)[:30]}"
#         except Exception as e:
#             error_msg = f"调用错误:{str(e)[:50]}"
#             print(error_msg)
#             return error_msg
# # ==================== 主程序 ====================
# def main():
#     # 检查Tavily密钥配置
#     if TAVILY_API_KEY == "YOUR_TAVILY_API_KEY":
#         print("错误:请先配置您的TAVILY_API_KEY!")
#         return
#
#     # 初始化工具和LLM客户端
#     available_tools = {"get_weather": get_weather, "get_attraction": get_attraction}
#     llm = OllamaClient(model=MODEL_NAME, base_url=OLLAMA_BASE_URL)
#
#     # 获取用户输入
#     user_prompt = input("请输入您的旅行咨询(例如:查询北京天气并推荐景点): ") or "查询北京天气并推荐景点"
#     prompt_history = [f"用户请求: {user_prompt}"]
#     print(f"\n用户输入: {user_prompt}\n" + "="*50)
#
#     # 主循环(最多5轮思考)
#     for i in range(5):
#         print(f"\n--- 第 {i + 1} 轮思考 ---")
#         full_prompt = "\n".join(prompt_history)
#
#         # 调用Ollama生成思考和行动
#         llm_output = llm.generate(full_prompt, AGENT_SYSTEM_PROMPT)
#         print(f"AI思考:\n{llm_output}")
#         prompt_history.append(llm_output)
#
#         # 解析Action
#         action_match = re.search(r"Action: (.*)", llm_output, re.DOTALL)
#         if not action_match:
#             print("解析错误:模型输出中未找到 Action。")
#             break
#
#         action_str = action_match.group(1).strip()
#         # 处理任务完成(finish)
#         if action_str.startswith("finish"):
#             finish_match = re.search(r'finish\(answer="(.*)"\)', action_str)
#             if finish_match:
#                 print(f"\n🎉 任务完成!最终答案: {finish_match.group(1)}")
#             else:
#                 print("解析错误:finish 行动格式不正确")
#             break
#
#         # 处理工具调用
#         tool_match = re.search(r"(\w+)\((.*)\)", action_str)
#         if not tool_match:
#             print("解析错误:行动格式不正确")
#             break
#
#         tool_name, args_str = tool_match.group(1), tool_match.group(2)
#         kwargs = dict(re.findall(r'(\w+)="([^"]*)"', args_str)) if args_str else {}
#
#         # 执行工具并记录结果
#         if tool_name in available_tools:
#             print(f"执行工具: {tool_name}({kwargs})")
#             observation = available_tools[tool_name](**kwargs)
#         else:
#             observation = f"错误:未定义的工具 '{tool_name}'"
#
#         print(f"工具返回: {observation}\n" + "="*50)
#         prompt_history.append(f"Observation: {observation}")
#     else:
#         print(f"\n达到最大迭代次数 5,停止执行。")
#
#
# if __name__ == "__main__":
#     main()

import os
import requests
import re
import json
from tavily import TavilyClient

# ==================== 配置区域 ====================
TAVILY_API_KEY = "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"
OLLAMA_BASE_URL = "http://localhost:11434"
MODEL_NAME = "llama2"

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

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

# 行动格式:
你的回答必须严格遵循以下格式。首先是你的思考过程,然后是你要执行的具体行动。
Thought: [这里是你的思考过程和下一步计划]
Action: [这里是你要调用的工具,格式为 function_name(arg_name="arg_value")]

# 重要说明:
- 在Action中必须使用关键字参数格式,例如:get_weather(city="Beijing")
- 不要使用位置参数格式,例如:get_weather("Beijing") 是错误的

# 任务完成:
当你收集到足够的信息,能够回答用户的最终问题时,你必须使用 `finish(answer="...")` 来输出最终答案。

请开始吧!
"""


# ==================== 工具函数 ====================
def get_weather(city: str) -> str:
    """通过 wttr.in API 查询实时天气"""
    url = f"https://wttr.in/{city}?format=j1"
    try:
        response = requests.get(url)
        response.raise_for_status()
        data = response.json()
        current_condition = data['current_condition'][0]
        weather_desc = current_condition['weatherDesc'][0]['value']
        temp_c = current_condition['temp_C']
        return f"{city}当前天气:{weather_desc},气温{temp_c}摄氏度"
    except requests.exceptions.RequestException as e:
        return f"错误:查询天气时遇到网络问题 - {e}"
    except (KeyError, IndexError) as e:
        return f"错误:解析天气数据失败,可能是城市名称无效 - {e}"


def get_attraction(city: str, weather: str) -> str:
    """通过 Tavily API 推荐景点"""
    api_key = TAVILY_API_KEY
    if not api_key or api_key == "YOUR_TAVILY_API_KEY":
        return "错误:请先配置TAVILY_API_KEY。"
    tavily = TavilyClient(api_key=api_key)
    query = f"'{city}' 在'{weather}'天气下最值得去的旅游景点推荐及理由"
    try:
        response = tavily.search(query=query, search_depth="basic", include_answer=True)
        if response.get("answer"):
            return response["answer"]
        formatted_results = []
        for result in response.get("results", []):
            formatted_results.append(f"- {result['title']}: {result['content']}")
        return "根据搜索,为您找到以下信息:\n" + "\n".join(
            formatted_results) if formatted_results else "抱歉,没有找到相关的旅游景点推荐。"
    except Exception as e:
        return f"错误:执行Tavily搜索时出现问题 - {e}"


# ==================== Ollama客户端(彻底强制CPU) ====================
class OllamaClient:
    def __init__(self, model: str, base_url: str):
        self.model = model
        self.base_url = base_url
        self.headers = {"Content-Type": "application/json"}

    def generate(self, prompt: str, system_prompt: str) -> str:
        print("正在调用大语言模型(CPU推理)...")
        try:
            data = {
                "model": self.model,
                "messages": [
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": prompt}
                ],
                "stream": False,
                "options": {
                    "num_gpu": 0,  # 使用新的参数名
                    "num_ctx": 512,
                    "num_thread": 4,
                    "low_vram": True
                }
            }
            response = requests.post(
                url=f"{self.base_url}/api/chat",
                headers=self.headers,
                json=data,
                timeout=120
            )
            response.raise_for_status()
            result = response.json()
            return result["message"]["content"]
        except Exception as e:
            error_msg = f"调用错误:{str(e)}"
            print(error_msg)
            return error_msg


# ==================== 参数解析函数 ====================
def parse_arguments(args_str: str) -> dict:
    """解析工具调用的参数,支持多种格式"""
    kwargs = {}

    # 尝试解析关键字参数格式:get_weather(city="Beijing")
    keyword_matches = re.findall(r'(\w+)=["\']([^"\']*)["\']', args_str)
    if keyword_matches:
        for key, value in keyword_matches:
            kwargs[key] = value
        return kwargs

    # 尝试解析位置参数格式:get_weather("Beijing")
    positional_matches = re.findall(r'["\']([^"\']*)["\']', args_str)
    if positional_matches:
        # 根据工具参数顺序映射
        if len(positional_matches) == 1:
            kwargs['city'] = positional_matches[0]
        elif len(positional_matches) == 2:
            kwargs['city'] = positional_matches[0]
            kwargs['weather'] = positional_matches[1]

    return kwargs


# ==================== 主程序 ====================
def main():
    # 检查Tavily密钥配置
    if TAVILY_API_KEY == "YOUR_TAVILY_API_KEY":
        print("错误:请先配置您的TAVILY_API_KEY!")
        return

    # 初始化工具和LLM客户端
    available_tools = {"get_weather": get_weather, "get_attraction": get_attraction}
    llm = OllamaClient(model=MODEL_NAME, base_url=OLLAMA_BASE_URL)

    # 获取用户输入
    user_prompt = input("请输入您的旅行咨询(例如:查询北京天气并推荐景点): ") or "查询北京天气并推荐景点"
    prompt_history = [f"用户请求: {user_prompt}"]
    print(f"\n用户输入: {user_prompt}\n" + "=" * 50)

    # 主循环(最多5轮思考)
    for i in range(5):
        print(f"\n--- 第 {i + 1} 轮思考 ---")
        full_prompt = "\n".join(prompt_history)

        # 调用Ollama生成思考和行动
        llm_output = llm.generate(full_prompt, AGENT_SYSTEM_PROMPT)
        print(f"AI思考:\n{llm_output}")
        prompt_history.append(llm_output)

        # 解析Action
        action_match = re.search(r"Action: (.*)", llm_output, re.DOTALL)
        if not action_match:
            print("解析错误:模型输出中未找到 Action。")
            # 如果没有找到Action,尝试直接完成回答
            if "finish" in llm_output.lower() or "答案" in llm_output:
                print(f"\n🎉 任务完成!最终答案: {llm_output}")
                break
            continue

        action_str = action_match.group(1).strip()

        # 处理任务完成(finish)
        if action_str.startswith("finish"):
            finish_match = re.search(r'finish\(answer=["\'](.*)["\']\)', action_str)
            if finish_match:
                print(f"\n🎉 任务完成!最终答案: {finish_match.group(1)}")
            else:
                # 尝试其他格式的finish
                finish_match = re.search(r'finish\(["\'](.*)["\']\)', action_str)
                if finish_match:
                    print(f"\n🎉 任务完成!最终答案: {finish_match.group(1)}")
                else:
                    print("解析错误:finish 行动格式不正确")
            break

        # 处理工具调用
        tool_match = re.search(r"(\w+)\((.*)\)", action_str)
        if not tool_match:
            print("解析错误:行动格式不正确")
            continue

        tool_name, args_str = tool_match.group(1), tool_match.group(2)

        # 使用新的参数解析函数
        kwargs = parse_arguments(args_str)
        print(f"解析到的参数: {kwargs}")

        # 执行工具并记录结果
        if tool_name in available_tools:
            print(f"执行工具: {tool_name}({kwargs})")
            try:
                observation = available_tools[tool_name](**kwargs)
            except TypeError as e:
                observation = f"错误:调用工具时参数不匹配 - {e}"
        else:
            observation = f"错误:未定义的工具 '{tool_name}'"

        print(f"工具返回: {observation}\n" + "=" * 50)
        prompt_history.append(f"Observation: {observation}")
    else:
        print(f"\n达到最大迭代次数 5,停止执行。")


if __name__ == "__main__":
    main()

Step3:配置和运行

3.1 配置API密钥

  1. 打开 travel_agent.py 文件
  2. 找到文件开头的配置区域
  3. YOUR_TAVILY_API_KEY 替换为您从Tavily获取的实际API密钥
  4. YOUR_OPENAI_API_KEY 替换为您的OpenAI API密钥

安装Ollama:

https://ollama.com/download

访问不了的话关注公众号,回复【Olla】获取安装包

3.2 运行程序

cmd中运行ollama模型:

ollama pull llama2
set OLLAMA_CPU=1 && ollama serve

再运行py文件

python travel_agent.py

3.3 使用示例

当程序运行时,您可以询问类似以下的问题:

  • "查询北京天气并推荐景点"
  • "上海今天天气怎么样?有什么适合的旅游景点?"
  • "帮我看看杭州的天气,然后推荐一个景点"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了一li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值