AI代理的架构、工具与实现

APPLICATION Jan 13, 2025

人工智能继续重塑我们的生活和工作方式。近年来,大型语言模型(LLMs),如ChatGPT,以其理解和生成类人文本的能力吸引了全世界的关注。它们是语言大师,能够进行对话、回答复杂问题,甚至编写代码。但在其语言能力的背后,存在一个根本性的限制——它们缺乏真正的自主性,并且受限于其训练数据。这就是 代理(Agent)概念的用武之地。代理是扩展LLM能力的程序,使其能够观察、推理并自主行动,使用各种工具完成任务。

在本文中,我们将探讨AI代理的世界,涵盖其架构、核心组件以及在实际应用中的实现。

1、什么是AI代理?

在最基本的形式中,生成式AI代理是一种通过观察世界并使用可用工具来采取行动以实现目标的应用程序。这些代理是自主的,意味着它们可以在没有人类干预的情况下独立运行,尤其是在提供了明确目标的情况下。

与LLMs相比,LLMs是被动的,需要用户不断输入提示才能响应。尽管LLMs的能力令人印象深刻,但它们仍然是被动的,无法在没有明确指令的情况下采取行动。

这就是AI代理的不同之处。与LLMs不同,AI代理不仅仅是理解——它们会采取行动。它们不仅能够做出决策,还能自主执行任务。例如,虽然LLM可以帮助你制定旅行计划,但AI代理会更进一步:预订航班、比较酒店价格并安排交通,而无需为每个步骤提供明确的指令。

2、AI代理的核心组件

代理的认知架构由三个核心组件组成:

  • 模型(Model):这是作为代理核心决策者的语言模型(LM)。但它不能是任何LM,它必须能够基于指令进行推理和逻辑框架,如ReAct、Chain-of-Thought或Tree-of-Thoughts。为了获得最佳结果,所选模型应与所需应用相匹配,并且最好在代理将使用的工具相关数据上进行训练。换句话说,模型应熟悉它将使用工具处理的数据的格式、结构或上下文。
  • 工具(Tools):这些工具弥合了模型内部能力与外部世界之间的差距。工具使代理能够与外部数据和服务交互,扩展其行动范围。工具可以采取多种形式,如扩展、函数和数据存储。例如,更新数据库、获取天气数据或发送电子邮件。
  • 编排层(Orchestration Layer):该层控制代理如何处理信息、执行推理并决定下一步行动。这是一个循环过程,直到代理达到其目标或达到停止点。该层的复杂性可以有很大差异,从简单的计算到链式逻辑和机器学习算法。它还包括提示工程和相关框架,以指导推理和规划。

3、认知架构:代理如何运作

认知架构是代理的大脑。它们是底层结构,使代理不仅能够处理信息,还能够进行推理、做出决策,并迭代优化其行动以实现特定目标。

以下是这些架构的工作原理:

  • 循环过程:代理以循环方式运作,不断接收信息、执行内部推理,并使用该推理决定下一步行动。这个循环持续进行,直到代理实现其目标或达到定义的停止点。
  • 编排层为核心:任何认知架构的核心都是编排层。该层负责维护代理的记忆、当前状态、推理过程和整体规划。
  • 推理框架:编排层使用提示工程和特定框架来指导推理和规划。这些框架帮助代理更有效地与环境交互并完成任务。

目前最流行的推理框架包括:

  • ReAct(推理与行动)
  • Chain-of-Thought(思维链)
  • Tree-of-Thoughts(思维树)

代理可以使用上述任何一种推理技术。基本上,这些框架将强制LM逐步思考,仔细考虑可用信息,并根据该推理采取最合适的行动。

4、工具:代理与外部世界的连接

正如我们所看到的,LMs擅长处理信息,但它们本质上受限于无法与真实世界交互。工具弥合了这一关键差距,使代理能够与外部数据和服务交互,从而扩展了模型本身能力之外的行动范围。

代理主要有三种工具类型:扩展、函数和数据存储。

4.1 扩展:标准化的API交互

扩展充当API与代理之间的标准化桥梁,允许代理执行API,而无需考虑其底层实现。将扩展视为预构建的连接器,使代理能够轻松地与不同的API交互。

扩展的工作原理

  • 它们通过示例教会代理如何使用API端点。
  • 它们教会代理调用API端点所需的参数。
  • 代理使用所学知识决定哪个扩展(如果有)适合解决用户的查询。

4.2 函数:客户端控制

函数是自包含的代码模块,用于完成特定任务,并且可以根据需要重复使用,类似于软件开发人员使用函数的方式。在代理的上下文中,模型决定何时使用每个函数以及需要哪些参数。函数与扩展的关键区别在于,函数在客户端执行,而扩展在代理端执行。

函数的工作原理

  • AI代理处理用户的请求并确定应调用特定函数。
  • 模型生成要调用的函数名称和所需的参数。例如,如果用户问:“纽约的天气如何?”,代理可能会输出:
Function: get_weather
Arguments: {"location": "New York"}
  • AI代理不直接进行API调用或执行函数本身。它只是“推荐”操作(函数和参数)给周围的系统。
  • 客户端应用程序(代理运行的环境)负责解释模型的输出并实际调用函数或API。

使用函数的原因

  • 简单性:代理不需要理解API调用的技术细节,如处理身份验证令牌、错误响应或网络连接。
  • 安全性:将API调用卸载到客户端减少了暴露敏感API密钥或管理安全连接的风险。
  • 性能:通过不进行实时API调用,AI模型专注于推理和决策,而客户端处理现实世界的交互。

4.3 数据存储:访问动态信息

数据存储解决了语言模型知识静态的限制,通过提供对更动态和最新信息的访问,确保模型的响应保持相关性。将数据存储视为代理可以访问的外部、可更新的信息源。

数据存储的工作原理

  • 开发人员以原始格式(电子表格、PDF等)向代理提供数据。
  • 数据被转换为一组向量嵌入。
  • 嵌入存储在向量数据库中。
  • 用户查询被发送到相同的嵌入模型以生成查询的嵌入。
  • 查询嵌入与向量数据库内容进行匹配。
  • 匹配的内容被检索并发送给代理。
  • 代理根据用户查询和检索到的内容制定响应或行动。

5、目标学习方法以增强模型性能

目标学习方法专注于训练或指导AI代理在各种情况下更好地决定使用哪些工具或资源。有几种方法可以实现这一目标:

  • 上下文学习(In-context Learning):模型在推理时通过提示、工具和少量示例进行学习。通过向模型展示精心设计的提示,包括何时以及如何使用工具的示例,模型可以理解上下文并决定如何继续。
  • 基于检索的上下文学习(Retrieval-based In-context Learning):该方法通过从外部内存或数据库中动态检索相关信息、示例或工具来增强上下文学习。检索到的内容随后包含在推理时的提示中。
  • 基于微调的学习(Fine-tuning based Learning):这涉及在特定数据集上训练模型,该数据集包括工具使用、决策过程或推理步骤的标记示例。这会更新模型的权重,将知识嵌入到模型本身中。与依赖提示的上下文学习不同,微调创建了模型的永久适应。

6、案例:使用LangChain构建代理

为了提供一个实际运行的代理示例,我们将使用LangChain框架构建一个快速原型。

LangChain是一个开源框架,通过提供用于链接逻辑、管理内存和集成外部工具(如API或数据库)的模块化组件,简化了AI代理的构建。LangChain的一个好处是它消除了对冗长提示的需求。该框架固有地向模型提供推理指令,并有效地与外部工具集成,减少了引导行为的详细提示的需求。

在提供的示例中,我们将使用gemini-1.5-flash-001模型和两个工具:SerpAPI(用于Google搜索)和Google Places API(用于位置数据)。

import os
from langgraph.prebuilt import create_react_agent
from langchain_core.tools import tool
from langchain_community.utilities import SerpAPIWrapper
from langchain_community.tools import GooglePlacesTool

# 设置API密钥
os.environ["SERPAPI_API_KEY"] = "XXXXX"
os.environ["GPLACES_API_KEY"] = "XXXXX"

# 使用SerpAPI定义搜索工具
@tool
def search(query: str):
    """使用SerpAPI运行Google搜索。"""
    search = SerpAPIWrapper()
    return search.run(query)

# 使用Google Places API定义地点工具
@tool
def places(query: str):
    """使用Google Places API运行Google Places查询。"""
    places = GooglePlacesTool()
    return places.run(query)

# 初始化模型
model = ChatVertexAI(model="gemini-1.5-flash-001")

# 代理可用的工具列表
tools = [search, places]

# 向代理提出的查询
query = "上周德克萨斯长角牛队与谁进行了足球比赛?另一支球队的体育场地址是什么?"

# 使用模型和工具创建代理
agent = create_react_agent(model, tools)

# 输入消息结构
input = {"messages": [("human", query)]}

# 以流模式处理代理的响应
for s in agent.stream(input, stream_mode="values"):
    message = s["messages"][-1]
    if isinstance(message, tuple):
        print(message)
    else:
        message.pretty_print()

这是代理的输出:

=============================== Human Message ==============================
上周德克萨斯长角牛队与谁进行了足球比赛?另一支球队的体育场地址是什么?
================================= Ai Message ===============================
工具调用: search 
参数: 
   query: 德克萨斯长角牛队足球赛程
================================= Tool Message =============================
名称: search
{...结果: "NCAA Division I Football, Georgia, 日期..."}
================================= Ai Message ===============================
德克萨斯长角牛队上周与乔治亚斗牛犬队比赛。
工具调用: places 
参数: 
  query: 乔治亚斗牛犬队体育场 
================================ Tool Message ==============================
名称: places
{...Sanford Stadium 地址: 100 Sanford...} 
================================= Ai Message ===============================
乔治亚斗牛犬队体育场的地址是100 Sanford Dr, Athens, GA 30602, USA。

7、结束语

生成式AI代理是语言模型的强大扩展,使它们能够通过工具、推理和编排与现实世界交互。在我看来,代理非常令人兴奋,因为它们代表了向更具交互性和智能系统的转变,能够自主执行任务。

关键要点包括:

  • 代理通过利用工具访问实时信息并执行特定任务,扩展了语言模型的能力。
  • 代理的大脑在于编排层。该层负责维护代理的记忆、当前状态、推理过程和整体规划。
  • 工具(如扩展、函数和数据存储)为代理提供了与外部系统交互并访问超出其训练数据的知识的能力。
  • 目标学习方法专注于训练或指导AI代理在各种情况下更好地决定使用哪些工具或资源。
  • 像LangChain这样的框架使构建代理变得更加简单。

原文链接:Introduction to AI Agents

汇智网翻译整理,转载请标明出处

Tags