什么是人工智能代理?
如果我们问一个人工智能,比如 ChatGPT: learnwithhasan.com 的响应时间是多少?
你认为它能回答吗?
如果你回答“否”,那么你是对的。
如果你回答“是”,那么你也是对的!
有趣的是,这两个答案都可以被认为是正确的。原因就在这里:
下面是 ChatGPT 对问题的回答:
它无法回答!
正如我们在 "提示工程 "中学到的,LLM 的主要局限之一是它无法访问实时数据,只能完全根据已有的训练数据生成回复。
然而,现在看看这个:
答案:自主 AI 代理
自主人工智能代理集成了大型语言模型(LLM)、外部功能和增强的提示机制。
为了理解这个概念,让我们看看法律硕士是如何回答我们的问题的。
1- 查询输入: 首先,我们向 LLM 发送问题。
2- 使用 ReAct 系统提示进行处理: LLM 由 ReAct 系统提示提供动力,允许它思考问题以及如何回答问题。我们称其为 "思考"(Thought),我们将在接下来的章节中详细讨论。
3- 外部功能执行: 然后,LLM 选择并执行外部函数,本例中为 "get_website_response_time(url)"。
4- 生成响应: 获得实时数据后,人工智能会根据结果制作并提供响应。
入门指南
在本指南中,我们将使用 Python 从头开始构建人工智能代理。首先,让我们建立一个新的 Python 项目。
你可以选择任何集成开发环境,但在本指南中,我将使用 Visual Studio Code。
创建并激活虚拟环境
安装 OpenAI 软件包
在本例中,我们将使用 OpenAI API 作为我们的大型语言模型,当然你也可以使用 Anthropic、Gemini 或其他开源模型。
确保 API 密钥已准备就绪。在你的项目中创建一个 .env 文件,然后像这样添加你的密钥,如下所示:
OPENAI_API_KEY = "sk-XX"
启动虚拟环境后,安装 OpenAI Python 软件包:
pip install openai
设置项目文件
创建三个 Python 文件:actions.py、prompts.py 和 main.py。
你现在应该有类似这样的文件:
使用 OpenAI API 生成文本
打开 main.py 文件,创建一个使用 OpenAI API 生成文本的简单函数。该函数将为我们的人工智能代理提供动力:
代码如下
from openai import OpenAI
import os
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Create an instance of the OpenAI class
openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def generate_text_with_conversation(messages, model = "gpt-3.5-turbo"):
response = openai_client.chat.completions.create(
model=model,
messages=messages
)
return response.choices[0].message.content
该脚本从 .env 文件中加载你的 API 密钥,并创建 OpenAI 实例来处理请求。
generate_text_with_conversation 函数简单明了,只需两个参数--模型和消息--即可生成响应。
测试函数
在继续之前,让我们确保一切工作符合预期。通过模拟对话来测试函数:
# 定义一个消息列表以模拟对话
# Define a list of messages to simulate a conversation
test_messages = [
{"role": "user", "content": "Hello, how are you?"},
{"role": "system", "content": "You are a helpful AI assistant"}
]
# Call the function with the test messages
response = generate_text_with_conversation(test_messages)
print("AI Response:", response)
基本设置完成后,我们就可以开始构建代理的核心部分了。
定义功能
这一部分,我们将指定人工智能代理可以访问的操作或功能。这将使代理在响应用户查询时能够利用外部功能。
创建基本功能
打开 actions.py 文件。在这里,我们将定义一个简单的函数来模拟不同网站的响应时间:
def get_response_time(url):
if url == "learnwithhasan.com":
return 0.5
if url == "google.com":
return 0.3
if url == "openai.com":
return 0.4
这个虚拟函数根据所提供的 URL 返回固定的响应时间。它是一个基本示例,帮助我们了解代理如何利用外部函数。
ReAct 提示
ReAct 提示使我们的人工智能代理能够模仿人类行为。
该系统提示引导模型完成 "思考"、"行动 "和 "响应 "的循环,使其能够有效处理用户询问。
简单地说,ReAct 提示指示模型思考用户询问、理解用户询问、决定如何回答、在需要时选择一个行动,然后利用这个行动以最佳方式回答问题。
定义 ReAct 提示
在 prompts.py 文件中,添加以下系统提示配置:
system_prompt = """
You run in a loop of Thought, Action, PAUSE, Action_Response.
At the end of the loop you output an Answer.
Use Thought to understand the question you have been asked.
Use Action to run one of the actions available to you - then return PAUSE.
Action_Response will be the result of running those actions.
Your available actions are:
get_response_time:
e.g. get_response_time: learnwithhasan.com
Returns the response time of a website
Example session:
Question: what is the response time for learnwithhasan.com?
Thought: I should check the response time for the web page first.
Action:
{
"function_name": "get_response_time",
"function_parms": {
"url": "learnwithhasan.com"
}
}
PAUSE
You will be called again with this:
Action_Response: 0.5
You then output:
Answer: The response time for learnwithhasan.com is 0.5 seconds.
"""
该系统提示指示 LLM 在 "思考"、"行动 "和 "行动响应 "的循环中运行。
循环结构(Thought、Action、PAUSE、Action_Response)为 LLM 提供指导:
可用操作
然后,我们告诉 LLM 哪些操作是可用的,并展示一个带有参数和简单描述的简单示例,以便模型了解函数的内容。
Your available actions are:are:
get_response_time:
e.g. get_response_time: learnwithhasan.com
Returns the response time of a website
确保函数名称与你在 python 中定义的函数名称一致。
示例会话
然后,我们向 LLM 演示一个示例,说明它将如何回答一个示例查询。
这里最重要的部分是如何返回 Action:
Action:
{
"function_name": "get_response_time","get_response_time",
"function_parms": {
"url": "learnwithhasan.com"
}
}
你可以看到,我在这里指示 LLM 以 JSON 格式返回操作。
为什么要循环?
这种循环机制模仿了 LLM 所采取的步骤:理解问题,根据理解采取行动,并使用行动结果做出响应。
对于简单的任务,这个过程只需几个循环,而对于更复杂的情况,则可能需要数百个循环。
把所有放在一起
在建立了 ReAct 系统提示并定义了必要的功能后,我们现在就可以整合这些元素来构建我们的人工智能代理。
让我们回到 main.py 脚本,完成设置。
定义可用函数
首先,列出代理可以使用的功能。在本例中,我们只有一个:
available_actions = {
"get_response_time": get_response_time
}
设置用户和系统提示
定义用户提示和将传递给我们之前创建的 generate_text_with_conversation 函数的信息:
user_prompt = "What is the response time for learnwithhasan.com?"
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
]
创建代理循环
执行处理用户输入和人工智能响应的循环:
turn_count = 1
max_turns = 5
while turn_count < max_turns:
print (f"Loop: {turn_count}")
print("----------------------")
turn_count += 1
response = generate_text_with_conversation(messages, model="gpt-4")
print(response)
json_function = extract_json(response)
if json_function:
function_name = json_function[0]['function_name']
function_parms = json_function[0]['function_parms']
if function_name not in available_actions:
raise Exception(f"Unknown action: {function_name}: {function_parms}")
print(f" -- running {function_name} {function_parms}")
action_function = available_actions[function_name]
#call the function
result = action_function(**function_parms)
function_result_message = f"Action_Response: {result}"
messages.append({"role": "user", "content": function_result_message})
print(function_result_message)
else:
break
这个循环反映了 ReAct 循环,即生成响应、提取 JSON 格式的函数调用并执行相应的操作。
因此,我们先生成响应,然后检查 LLM 是否返回了函数。
我创建了 extract_json 方法,以便于从 LLM 响应中提取任何函数。
在下面一行中
json_function = extract_json(response)
我们将检查 LLM 是否返回了要执行的函数,如果是,它将执行并将结果附加到消息中,这样在下一轮中,LLM 就可以使用 Action_response 来回答用户的询问。