过去一年,AI给我们的震撼已经足够多。但现在,一个更重要的转变正在发生:AI不再只是等着回答问题,而是开始主动为我们做事了。
这就是智能体的崛起。
我们正从“向AI提问”的时代,快步走向“让AI行动”的时代。让我们来一起学习了解习智能体吧,让你不仅仅是一个AI的使用者,更成为指挥AI行动的构建者。
什么是智能体(Agent)?
简单来说,智能体就是一个能够感知环境、进行决策并采取行动,以达成特定目标的系统。
你可以把它想象成一个数字化的“助手”或“代表”,它被赋予了一个任务,然后它会自主地去思考并执行,而不需要你每一步都下达详细的指令。
一个智能体通常包含三个核心部分:
- 感知: 它能通过传感器、数据接口或用户输入来“观察”和获取周围环境的信息。
- 决策: 它有一个“大脑”(通常是算法或模型),能够分析感知到的信息,思考该做什么,并制定行动计划。
- 行动: 它通过执行器、输出接口或具体操作来影响环境,从而向目标迈进。
举一个生动的例子:智能家居管家
想象一下你家里有一个高级的智能家居系统,它就是一个智能体。
- 它的目标: 维持室内舒适的环境,并尽可能节省能源。
- 它的“身体”: 遍布家中的温度、湿度、光线传感器,以及可以控制的空调、加湿器、电动窗帘。
现在,我们来看它在一个下午的工作流程:
- 感知
-
- 温度传感器感知到室内温度升高到了28°C。
- 光线传感器感知到西晒的阳光非常强烈。
- 湿度传感器感知到空气干燥。
- 它的“大脑”也从互联网上获取了当前时间(下午3点)和天气预报(今晚有雨)。
- 决策
-
- “大脑”开始分析:“温度28°C,太热了,用户设定的舒适温度是24°C。阳光太强是主要原因,而且空气也很干燥。”
- 它制定了一个行动计划:
-
-
- 第一步: 先关闭电动窗帘,阻挡阳光,这是最节能的降温方式。
- 第二步: 如果15分钟后温度还是高于25°C,就打开空调,设定为24°C。
- 第三步: 同时,因为空气干燥,启动加湿器。
-
- 行动
-
- 它向电动窗帘发出指令,窗帘自动关闭。
- 15分钟后,温度传感器显示26°C,它向空调发出指令,空调开始制冷。
- 它同时向加湿器发出指令,加湿器开始工作。
- 持续循环
-
- 空调运行一段时间后,温度传感器显示已达到24°C。
- 智能体再次感知到这个变化,于是决策并行动:调高空调风速或暂时关闭,以防止过度制冷,节约电能。
在这个例子中:
- 你没有给出任何即时指令(比如“太热了,开空调”)。
- 这个智能家居系统作为一个智能体,自主地、有目标地完成了整个任务。
智能体并非一次性完成任务,而是通过一个持续的循环与环境进行交互,这个核心机制被称为 智能体循环 (Agent Loop)。如下图所示,该循环描述了智能体与环境之间的动态交互过程,构成了其自主行为的基础。

相信你看到这里,也会觉得前面内容很枯燥吧,其实前面内容了解即可,重要的是会应用。
下面让我们来花五分钟动手从零构建第一个智能体吧。我要讲解的是构建智能旅行助手。
目标是要解决的用户任务定义为:"你好,请帮我查询一下今天北京的天气,然后根据天气推荐一个合适的旅游景点。"
它厉害在哪?你只需要说一句:
“帮我查下北京今天天气,然后推荐个合适景点”
接下来,就是见证奇迹的时刻:
第一秒,它独立思考:“得先查天气”
下一秒,它自动调用天气API
第三秒,它根据“晴天26度”的结果,自动搜索匹配景点
最后,它把完整的旅行方案呈现在你面前
全程自动,无需你插手!这就是正在爆发的智能体(Agent) 技术。
和我一起创造你的第一个“数字员工”
其实吧智能体也没大家想的那么神秘,他的核心就是让AI学会“三步走”:
- 思考(Thought):分析该做什么
- 行动(Action):调用工具执行
- 观察(Observation):根据结果调整
就像训练一个实习生:
- 你给他工具箱(查天气、搜攻略)
- 教他工作流程(先查天气再推荐)
- 然后就能放手让他独立完成任务!
我用短短50行Python代码就实现了这个智能旅行管家。最关键的是,这个思路能无限扩展:
- 想做个自动报税助手?加上财税工具就行
- 想要智能客服?接入产品数据库就好
- 甚至可以做私人投资顾问...
Step1:前期准备
1.1 安装必要的Python库
使用代码
pip install requests tavily-python openai
或者直接添加


1.2 获取API密钥
- Tavily API密钥:
-
- 访问 https://www.tavily.com/
- 注册账户并获取免费API密钥
- 每月有1,000次免费搜索

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密钥
- 打开
travel_agent.py文件 - 找到文件开头的配置区域
- 将
YOUR_TAVILY_API_KEY替换为您从Tavily获取的实际API密钥 - 将
YOUR_OPENAI_API_KEY替换为您的OpenAI API密钥
安装Ollama:

访问不了的话关注公众号,回复【Olla】获取安装包
3.2 运行程序
cmd中运行ollama模型:
ollama pull llama2
set OLLAMA_CPU=1 && ollama serve

再运行py文件
python travel_agent.py
3.3 使用示例
当程序运行时,您可以询问类似以下的问题:
- "查询北京天气并推荐景点"
- "上海今天天气怎么样?有什么适合的旅游景点?"
- "帮我看看杭州的天气,然后推荐一个景点"

被折叠的 条评论
为什么被折叠?



