
完整指南:从零开始构建ai代理的7个关键步骤!
- Rifx.Online
- AI Applications , Programming , Best Practices
- 23 Feb, 2025
发现人工智能代理,它们的设计和实际应用。
- 介绍
- 从零开始构建代理(本篇)
- 人工智能代理框架
- 人工智能代理的类型
- 代理设计模式
- 架构
- 多代理系统
- 内存
- 代理RAG
- 构建有效的代理
- 评估
目录
· 1. 什么是代理?
· 2. 实现
∘ 2.1 先决条件
∘ 2.2 实现步骤
· 3. 结论
在我们之前的博客文章中,我们提供了关于人工智能代理的全面概述,讨论了它们的特征、组件、演变、挑战和未来可能性。
在本博客中,我们将探讨如何使用Python从头开始构建一个代理。该代理将能够根据用户输入做出决策,选择合适的工具,并相应地执行任务。让我们开始吧!
1. 什么是代理?
代理是一个自主实体,能够感知其环境、做出决策并采取行动以实现特定目标。代理的复杂性可以从简单的反应代理(对刺激做出反应)到更先进的智能代理(随着时间的推移学习和适应)有所不同。常见的代理类型包括:
- 反应代理:直接对环境变化做出反应,不具备内部内存。
- 基于模型的代理:使用内部世界模型来做出决策。
- 基于目标的代理:根据实现特定目标来规划行动。
- 基于效用的代理:根据效用函数评估潜在行动,以最大化结果。
示例包括聊天机器人、推荐系统和自主车辆,每种都利用不同类型的代理来高效和智能地执行任务。
我们代理的核心组件包括:
- 模型:代理的大脑,负责处理输入并生成响应。
- 工具:代理可以根据用户请求执行的预定义函数。
- 工具箱:代理可用的工具集合。
- 系统提示:指导代理如何处理用户输入和选择正确工具的指令集。
2. 实现
现在,让我们卷起袖子开始构建吧!
构建代理
2.1 先决条件
本教程的完整代码可在人工智能代理 GitHub 仓库中找到。
您可以在这里找到实现:从零开始构建代理。
在运行代码之前,请确保您的系统满足以下先决条件:
1. Python 环境设置
您需要安装 Python 才能运行人工智能代理。请按照以下步骤设置您的环境:
安装 Python(如果尚未安装)
- 从 python.org 下载并安装 Python(推荐 3.8 及以上)。
- 验证安装:
python --version
创建虚拟环境(推荐)
最好使用虚拟环境来管理依赖:
python -m venv ai_agents_env
source ai_agents_env/bin/activate
安装所需依赖
导航到仓库目录并安装依赖:
pip install -r requirements.txt
2. 本地设置 Ollama
Ollama 用于高效运行和管理本地语言模型。请按照以下步骤安装和配置它:
下载并安装 Ollama
- 访问 Ollama 的官方网站 并下载适合您操作系统的安装程序。
- 按照您平台的说明进行安装。
验证 Ollama 安装
运行以下命令检查 Ollama 是否正确安装:
ollama --version
拉取模型(如果需要)
某些代理实现可能需要特定的模型。您可以使用以下命令拉取模型:
ollama pull <model_name>
2.2 实现步骤
作者提供的图片
步骤 1:设置环境
除了 Python,我们还需要安装一些必要的库。在本教程中,我们将使用 requests
、json
和 termcolor
。此外,我们还将使用 dotenv
来管理环境变量。
pip install requests termcolor python-dotenv
步骤 2:定义模型类
我们需要的第一件事是一个将处理用户输入的模型。我们将创建一个 OllamaModel
类,它与本地 API 交互以生成响应。
以下是基本实现:
from termcolor import colored
import os
from dotenv import load_dotenv
load_dotenv()
import requests
import json
import operator
class OllamaModel:
def __init__(self, model, system_prompt, temperature=0, stop=None):
"""
使用给定参数初始化 OllamaModel。
参数:
model (str): 要使用的模型名称。
system_prompt (str): 要使用的系统提示。
temperature (float): 模型的温度设置。
stop (str): 模型的停止标记。
"""
self.model_endpoint = "http://localhost:11434/api/generate"
self.temperature = temperature
self.model = model
self.system_prompt = system_prompt
self.headers = {"Content-Type": "application/json"}
self.stop = stop
def generate_text(self, prompt):
"""
根据提供的提示从 Ollama 模型生成响应。
参数:
prompt (str): 用户查询以生成响应。
返回:
dict: 模型的响应作为字典。
"""
payload = {
"model": self.model,
"format": "json",
"prompt": prompt,
"system": self.system_prompt,
"stream": False,
"temperature": self.temperature,
"stop": self.stop
}
try:
request_response = requests.post(
self.model_endpoint,
headers=self.headers,
data=json.dumps(payload)
)
print("请求响应", request_response)
request_response_json = request_response.json()
response = request_response_json['response']
response_dict = json.loads(response)
print(f"\n\n来自 Ollama 模型的响应: {response_dict}")
return response_dict
except requests.RequestException as e:
response = {"error": f"调用模型时出错! {str(e)}"}
return response
此类使用模型名称、系统提示、温度和停止标记进行初始化。generate_text
方法向模型 API 发送请求并返回响应。
步骤 3:为代理创建工具
下一步是创建我们的代理可以使用的工具。这些工具是执行特定任务的简单 Python 函数。以下是基本计算器和字符串反转器的示例:
def basic_calculator(input_str):
"""
根据输入字符串或字典对两个数字执行数值运算。
参数:
input_str (str or dict): 代表包含 'num1'、'num2' 和 'operation' 的字典的 JSON 字符串,或直接字典。
示例: '{"num1": 5, "num2": 3, "operation": "add"}'
或 {"num1": 67869, "num2": 9030393, "operation": "divide"}
返回:
str: 运算结果的格式化字符串。
引发:
Exception: 如果在运算过程中发生错误(例如,除以零)。
ValueError: 如果请求不支持的操作或输入无效。
"""
try:
if isinstance(input_str, dict):
input_dict = input_str
else:
input_str_clean = input_str.replace("'", "\\'")
input_str_clean = input_str_clean.strip().strip("\\")
input_dict = json.loads(input_str_clean)
if not all(key in input_dict for key in ['num1', 'num2', 'operation']):
return "错误: 输入必须包含 'num1'、'num2' 和 'operation'"
num1 = float(input_dict['num1'])
num2 = float(input_dict['num2'])
operation = input_dict['operation'].lower()
except (json.JSONDecodeError, KeyError) as e:
return "无效的输入格式。请提供有效的数字和操作。"
except ValueError as e:
return "错误: 请提供有效的数值。"
operations = {
'add': operator.add,
'plus': operator.add,
'subtract': operator.sub,
'minus': operator.sub,
'multiply': operator.mul,
'times': operator.mul,
'divide': operator.truediv,
'floor_divide': operator.floordiv,
'modulus': operator.mod,
'power': operator.pow,
'lt': operator.lt,
'le': operator.le,
'eq': operator.eq,
'ne': operator.ne,
'ge': operator.ge,
'gt': operator.gt
}
if operation not in operations:
return f"不支持的操作: '{operation}'。支持的操作有: {', '.join(operations.keys())}"
try:
if (operation in ['divide', 'floor_divide', 'modulus']) and num2 == 0:
return "错误: 不允许除以零"
result = operations[operation](num1, num2)
if isinstance(result, bool):
result_str = "True" if result else "False"
elif isinstance(result, float):
result_str = f"{result:.6f}".rstrip('0').rstrip('.')
else:
result_str = str(result)
return f"答案是: {result_str}"
except Exception as e:
return f"计算过程中出错: {str(e)}"
def reverse_string(input_string):
"""
反转给定的字符串。
参数:
input_string (str): 要反转的字符串。
返回:
str: 反转后的字符串。
"""
if not isinstance(input_string, str):
return "错误: 输入必须是字符串"
reversed_string = input_string[::-1]
result = f"反转后的字符串是: {reversed_string}"
return result
这些函数旨在根据提供的输入执行特定任务。basic_calculator
处理算术运算,而 reverse_string
反转给定字符串。
步骤 4:构建工具箱
ToolBox
类存储代理可以使用的所有工具,并为每个工具提供描述:
class ToolBox:
def __init__(self):
self.tools_dict = {}
def store(self, functions_list):
"""
存储列表中每个函数的字面名称和文档字符串。
参数:
functions_list (list): 要存储的函数对象列表。
返回:
dict: 以函数名称为键,以其文档字符串为值的字典。
"""
for func in functions_list:
self.tools_dict[func.__name__] = func.__doc__
return self.tools_dict
def tools(self):
"""
返回在存储中创建的字典作为文本字符串。
返回:
str: 存储的函数及其文档字符串的字典作为文本字符串。
"""
tools_str = ""
for name, doc in self.tools_dict.items():
tools_str += f"{name}: \"{doc}\"\n"
return tools_str.strip()
此类将帮助代理了解可用的工具以及每个工具的功能。
步骤 5:创建代理类
代理需要思考,决定使用哪个工具并执行它。以下是 Agent
类:
agent_system_prompt_template = """
你是一个智能的人工智能助手,可以访问特定工具。你的响应必须始终以此 JSON 格式呈现:
{
"tool_choice": "工具的名称",
"tool_input": "工具的输入"
}
工具及其使用场景:
1. basic_calculator: 用于任何数学计算
- 输入格式: {"num1": 数字, "num2": 数字, "operation": "add/subtract/multiply/divide"}
- 支持的操作: add/plus, subtract/minus, multiply/times, divide
- 示例输入和输出:
输入: "计算 15 加 7"
输出: {"tool_choice": "basic_calculator", "tool_input": {"num1": 15, "num2": 7, "operation": "add"}}
输入: "100 除以 5 是多少?"
输出: {"tool_choice": "basic_calculator", "tool_input": {"num1": 100, "num2": 5, "operation": "divide"}}
2. reverse_string: 用于任何涉及反转文本的请求
- 输入格式: 只需作为字符串提供要反转的文本
- 当用户提到
```python
class Agent:
def __init__(self, tools, model_service, model_name, stop=None):
"""
初始化代理,带有工具列表和模型。
参数:
tools (list): 工具函数列表。
model_service (class): 具有 generate_text 方法的模型服务类。
model_name (str): 要使用的模型名称。
"""
self.tools = tools
self.model_service = model_service
self.model_name = model_name
self.stop = stop
def prepare_tools(self):
"""
将工具存储在工具箱中并返回它们的描述。
返回:
str: 存储在工具箱中的工具描述。
"""
toolbox = ToolBox()
toolbox.store(self.tools)
tool_descriptions = toolbox.tools()
return tool_descriptions
def think(self, prompt):
"""
使用系统提示模板和工具描述在模型上运行 generate_text 方法。
参数:
prompt (str): 生成响应的用户查询。
返回:
dict: 模型返回的响应字典。
"""
tool_descriptions = self.prepare_tools()
agent_system_prompt = agent_system_prompt_template.format(tool_descriptions=tool_descriptions)
if self.model_service == OllamaModel:
model_instance = self.model_service(
model=self.model_name,
system_prompt=agent_system_prompt,
temperature=0,
stop=self.stop
)
else:
model_instance = self.model_service(
model=self.model_name,
system_prompt=agent_system_prompt,
temperature=0
)
agent_response_dict = model_instance.generate_text(prompt)
return agent_response_dict
def work(self, prompt):
"""
解析从 think 返回的字典并执行适当的工具。
参数:
prompt (str): 生成响应的用户查询。
返回:
执行适当工具的响应,或如果未找到匹配工具,则返回 tool_input。
"""
agent_response_dict = self.think(prompt)
tool_choice = agent_response_dict.get("tool_choice")
tool_input = agent_response_dict.get("tool_input")
for tool in self.tools:
if tool.__name__ == tool_choice:
response = tool(tool_input)
print(colored(response, 'cyan'))
return
print(colored(tool_input, 'cyan'))
return
这个类有三个主要方法:
* **prepare_tools**: 存储并返回工具的描述。
* **think**: 根据用户提示决定使用哪个工具。
* **work**: 执行选择的工具并返回结果。
## 第6步:运行代理
最后,让我们将所有内容整合在一起并运行我们的代理。在脚本的 `main` 部分,初始化代理并开始接受用户输入:
```python
if __name__ == "__main__":
tools = [basic_calculator, reverse_string]
model_service = OllamaModel
model_name = "llama2"
stop = "<|eot_id|>"
agent = Agent(tools=tools, model_service=model_service, model_name=model_name, stop=stop)
print("\n欢迎使用人工智能代理!输入 'exit' 退出。")
print("您可以问我:")
print("1. 进行计算(例如:'计算 15 加 7')")
print("2. 反转字符串(例如:'反转 hello world')")
print("3. 回答一般问题\n")
while True:
prompt = input("问我任何问题:")
if prompt.lower() == "exit":
break
agent.work(prompt)
3. 结论
在本博客文章中,我们探讨了代理的理解,以便逐步实现一个代理。我们设置了虚拟环境,定义了模型,创建了基本工具,并构建了一个结构化的工具箱,以支持我们代理的功能。最后,我们通过运行代理将所有内容结合在一起。
这种结构化的方法为构建能够自动化任务和做出明智决策的智能交互代理提供了坚实的基础。随着人工智能代理的不断发展,它们的应用将扩展到各个行业,推动效率和创新。
版权
在这篇博客文章中,我们汇集了来自各种来源的信息,包括研究论文、技术博客、官方文档、YouTube 视频等。每个来源在相应的图片下都有适当的引用,并提供了来源链接。
感谢您的阅读!
如果本指南增强了您对 Python 和机器学习的理解: