AI Agent 正成为连接大型语言模型(LLM)与现实世界的关键桥梁。它们不仅能理解我们的指令,还能利用各种工具完成复杂任务。本文将带你深入了解如何从零开始构建一个 AI Agent,解析其中的核心概念如 LLM、工具、函数调用以及 MCP Server,并探讨如何利用 LangChain 等框架简化开发流程,让你掌握构建智能代理的底层逻辑。
什么是工具?AI Agent 的行动之手
在 AI Agent 的世界里,“工具”并非指锤子或扳手,而是指 LLM 可以调用以执行特定任务的函数。 想象一下,你想让 AI Agent 执行 shell 命令,例如列出目录中的文件。没有工具,LLM 只能生成文本,而无法实际操作。这时,一个名为 “executeshellcommand” 的工具就能派上用场。
import subprocess
def execute_shell_command(command: str) -> str:
try:
print("Executing: " + command)
result = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT, text=True, timeout=5)
return result.strip()
except subprocess.CalledProcessError as e:
return f"Error: {e.output}"
这段代码定义了一个 工具,它接收一个 shell 命令作为输入,执行该命令,并返回结果。通过赋予 AI Agent 调用这个工具的能力,它就能与操作系统进行交互,从而完成超出纯文本生成的任务。例如,你可以让 AI Agent 自动执行文件管理、系统监控等任务。
更进一步,我们可以构建更复杂的工具,比如调用 API 获取天气信息、访问数据库查询数据等等。工具的多样性决定了 AI Agent 的能力边界。
MCP Server:工具调用的中央枢纽
MCP Server(Model Context Protocol Server) 扮演着工具调用的中央枢纽角色。当 AI Agent 需要使用某个工具时,它会向 MCP Server 发送一个请求,包含要使用的工具名称和输入参数。MCP Server 接收到请求后,会将其路由到相应的工具函数进行执行,并将结果返回给 AI Agent。
以下是一个简单的 MCP Server 示例:
def mcp_server(agent_request: dict) -> dict:
if agent_request["tool"] == "shell":
result = execute_shell_command(agent_request["input"])
return {"tool": "shell", "output": result}
else:
return {"error": "Unknown tool"}
这个 MCP Server 只有一个 工具 “shell”,当收到请求时,它会调用 execute_shell_command
函数并返回结果。你可以根据需要添加更多的工具到这个 MCP Server 中。例如,可以添加一个 “calculator” 工具,用于执行数学计算;或者添加一个 “converter” 工具,用于单位转换。
MCP Server 的存在使得 AI Agent 的工具管理更加集中化和模块化。当需要添加、修改或删除工具时,只需要修改 MCP Server 的配置,而不需要修改 AI Agent 的核心代码。
LLM 与记忆:赋予 AI Agent 思考能力
要让 AI Agent 真正“智能”,需要赋予它理解用户意图、做出决策的能力。这就是 LLM (Large Language Model) 发挥作用的地方。 LLM 能够理解自然语言,并根据上下文生成相应的回复或指令。
为了让 LLM 更好地理解用户意图,我们还需要为 AI Agent 增加记忆功能。记忆可以帮助 AI Agent 记住之前的对话内容,从而更好地理解当前用户的指令。
以下是记忆功能的实现示例:
memory_store = []
def add_to_memory(role: str, content: str):
memory_store.append({"role": role, "content": content})
if len(memory_store) > 20: # limit memory size
memory_store.pop(0)
def get_memory():
return memory_store.copy()
这个代码定义了一个简单的记忆存储 memory_store
,使用 add_to_memory
函数可以将对话内容添加到记忆中,使用 get_memory
函数可以获取记忆内容。为了防止记忆无限增长,我们限制了记忆的大小为 20 条。
在每次与用户交互时,我们将用户输入和 AI Agent 的回复都添加到记忆中。然后,将记忆内容作为 LLM 的上下文,让 LLM 能够更好地理解用户意图。
函数调用:LLM 指挥工具的桥梁
函数调用是 LLM 与 工具 之间的桥梁。当 LLM 认为需要使用某个工具时,它会生成一个包含工具名称和输入参数的 函数调用 请求。
例如,用户输入 “请列出当前目录下的文件”,LLM 可能会生成以下 函数调用 请求:
{"tool": "shell", "input": "ls -la"}
这个请求指示 MCP Server 调用名为 “shell” 的工具,并使用 “ls -la” 作为输入参数。
在 OpenAI 的 API 中,函数调用 可以通过 tools
参数来实现。你可以定义 工具 的名称、描述和参数,OpenAI 会直接返回 JSON 格式的 函数调用 请求,无需手动解析文本。这大大简化了 LLM 与 工具 的集成过程。
以下是一个使用 OpenAI 函数调用 的示例:
import openai
import json
openai.api_key = "YOUR_API_KEY"
def get_current_weather(location, unit="fahrenheit"):
"""Get the current weather in a given location"""
weather_info = {
"location": location,
"temperature": "72",
"unit": unit,
"forecast": ["sunny", "windy"],
}
return json.dumps(weather_info)
response = openai.chat.completions.create(
model="gpt-3.5-turbo-0613",
messages=[{"role": "user", "content": "What's the weather like in Boston?"}],
tools=[
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
}
}
],
tool_choice="auto", # auto is default, but be explicit
)
message = response.choices[0].message
tool_calls = message.tool_calls
if tool_calls:
for tool_call in tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
if function_name == "get_current_weather":
weather_info = get_current_weather(location=function_args.get("location"))
second_response = openai.chat.completions.create(
model="gpt-3.5-turbo-0613",
messages=[
{"role": "user", "content": "What's the weather like in Boston?"},
message,
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": weather_info,
},
],
)
print(second_response.choices[0].message.content) # Output: The weather in Boston is 72 degrees Fahrenheit and sunny and windy.
在这个例子中,我们定义了一个 get_current_weather
工具,并使用 tools
参数将其传递给 OpenAI API。 OpenAI 会根据用户的输入判断是否需要调用这个工具,如果需要,它会返回一个包含 工具 名称和参数的 JSON 对象。我们只需要解析这个 JSON 对象,并调用相应的工具函数即可。
Agent Loop:连接一切的循环
将 LLM、工具、MCP Server 和记忆连接起来的关键是 Agent Loop。 Agent Loop 是一个循环,它不断地接收用户输入,调用 LLM 进行分析,执行相应的工具,并将结果返回给用户。
以下是一个简单的 Agent Loop 示例:
import openai
import json
import re
openai.api_key = "YOUR_API_KEY"
memory_store = []
def add_to_memory(role: str, content: str):
memory_store.append({"role": role, "content": content})
if len(memory_store) > 20: # limit memory size
memory_store.pop(0)
def get_memory():
return memory_store.copy()
def execute_shell_command(command: str) -> str:
try:
print("Executing: " + command)
result = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT, text=True, timeout=5)
return result.strip()
except subprocess.CalledProcessError as e:
return f"Error: {e.output}"
def mcp_server(agent_request: dict) -> dict:
if agent_request["tool"] == "shell":
result = execute_shell_command(agent_request["input"])
return {"tool": "shell", "output": result}
else:
return {"error": "Unknown tool"}
def extract_tool_call(text):
try:
match = re.search(r'{.*}', text)
if match:
return json.loads(match.group(0))
except json.JSONDecodeError:
pass
return None
def agent(user_input: str) -> str:
add_to_memory("user", user_input)
context = get_memory()
context.append({
"role": "system",
"content": "You are an AI agent that can use a shell tool. If the user asks for a command to be run, respond with JSON: {\"tool\": \"shell\", \"input\": \"<command>\"}. Otherwise, just reply normally."
})
try:
response = openai.chat.completions.create(
model="gpt-3.5-turbo",
messages = [{"role": m["role"], "content": m["content"]} for m in context]
)
except Exception as e:
return f"Error calling LLM: {e}"
reply = response.choices[0].message.content
add_to_memory("assistant", reply)
tool_call = extract_tool_call(reply)
if tool_call:
result = mcp_server(tool_call)
return f"(Tool Result) {result['output']}"
else:
return reply
# Test Run
print(agent("hi there"))
print(agent("I want to see files in the directory"))
print(agent("yes"))
这个 Agent Loop 的工作流程如下:
- 接收用户输入。
- 将用户输入添加到记忆中。
- 从记忆中获取上下文。
- 将上下文传递给 LLM。
- LLM 根据上下文生成回复。
- 将 LLM 的回复添加到记忆中。
- 如果 LLM 的回复包含 函数调用 请求,则调用相应的工具。
- 将工具的执行结果返回给用户。
- 重复步骤 1。
通过 Agent Loop,我们可以构建一个能够持续学习、适应用户需求的 AI Agent。
LangChain:简化 AI Agent 开发的利器
LangChain 是一个强大的框架,旨在简化 LLM 应用的开发,包括 AI Agent。它封装了许多常用的功能,例如工具管理、记忆管理和 LLM 调用,让开发者可以更专注于业务逻辑的实现。
使用 LangChain 构建 AI Agent 非常简单:
from langchain.agents import initialize_agent, Tool
from langchain_openai import OpenAI
import os
os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY"
def execute_shell_command(command: str) -> str:
try:
print("Executing: " + command)
result = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT, text=True, timeout=5)
return result.strip()
except subprocess.CalledProcessError as e:
return f"Error: {e.output}"
tool = Tool(
name="Shell",
func=execute_shell_command,
description="Runs shell commands"
)
llm = OpenAI(temperature=0)
agent = initialize_agent([tool], llm, agent="zero-shot-react-description", verbose=True)
agent.run("List all files in the directory.")
这段代码使用 LangChain 创建了一个 AI Agent,它可以执行 shell 命令。LangChain 负责处理 工具 的选择、 LLM 的调用和 Agent Loop 的管理,开发者只需要定义 工具 和 LLM 即可。
LangChain 还提供了许多其他的工具和模块,例如向量数据库、文档加载器和文本分割器,可以帮助开发者构建更复杂的 AI Agent 应用。
系统提示(System Prompt):塑造 AI Agent 的个性
系统提示(System Prompt) 是一个非常重要的概念,它用于定义 AI Agent 的角色、能力和行为准则。系统提示 相当于 AI Agent 的 “人设”,它会影响 AI Agent 的所有行为。
在 Agent Loop 的例子中,我们使用了以下 系统提示:
You are an AI agent that can use a shell tool. If the user asks for a command to be run, respond with JSON: {\"tool\": \"shell\", \"input\": \"<command>\"}. Otherwise, just reply normally.
这个 系统提示 告诉 LLM,它是一个 AI Agent,可以使用 shell 工具。如果用户要求执行命令,它应该返回 JSON 格式的 函数调用 请求。否则,它应该正常回复。
通过修改 系统提示,我们可以塑造 AI Agent 的个性。例如,我们可以让 AI Agent 扮演一个客户服务代表,或者让 AI Agent 扮演一个技术支持工程师。
一个好的 系统提示 应该清晰、简洁、明确,并能够指导 LLM 做出正确的决策。
AI Agent 的未来:无限可能
AI Agent 技术正在迅速发展,未来的 AI Agent 将会更加智能、更加强大。我们可以期待以下几个方面的发展:
- 更强大的工具:AI Agent 将能够使用更多的工具,例如机器人、传感器和执行器,从而与现实世界进行更深入的交互。
- 更智能的 LLM: LLM 将会更加智能,能够更好地理解用户意图,并做出更复杂的决策。
- 更完善的 Agent Loop:Agent Loop 将会更加完善,能够更好地处理错误和异常情况,并持续学习和改进。
AI Agent 将会在各个领域发挥重要作用,例如自动化、客户服务、医疗保健和教育。例如,在自动化领域,AI Agent 可以用于管理供应链、优化生产流程和监控设备运行状况。在客户服务领域,AI Agent 可以用于回答客户问题、解决客户问题和提供个性化推荐。在医疗保健领域,AI Agent 可以用于诊断疾病、制定治疗方案和提供远程医疗服务。在教育领域,AI Agent 可以用于个性化教学、提供学习辅导和评估学生成绩。
总之,AI Agent 代表着人工智能的未来,它将改变我们的工作和生活方式。 掌握构建 AI Agent 的技能,将让你在未来的科技浪潮中占据领先地位。 通过本文的学习,相信你已经对 AI Agent 的核心概念和技术有了更深入的理解。 现在,就开始动手构建你自己的 AI Agent 吧!