RAG 是在数据层面为大模型提供更多、更新的外部知识,而 Agent (智能体),为大模型扩展了推理业务的能力。数据是静态的,数据周期可能是天、小时甚至到秒,通过 RAG 实现时,需要调用对应系统的 API 去实时获取相关数据并组合发给 LLM,如果是一系列动作完成一个需求,前一个动作的输出是下一个动作的输入,使用 RAG 处理就相当复杂,也没有利用到大模型强大的推理能力。
Agent 的推出很好的解决了模型调用工具能力(Function Call),工具能力最早始于 ChatGPT,例如,我们想了解当前北京的气温,需要实时数据,有了工具能力就可以调用 API 获取是实时数据。本文将介绍如果通过 LlamaIndex 实现 Agent。
ReActAgent
LlamaIndex 实现 Agent 需要导入 ReActAgent 和 Function Tool,
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool
ReActAgent 是什么?
ReActAgent 通过结合推理(Reasoning)和行动(Acting)来创建动态的 LLM Agent 的框架。该方法允许 LLM 模型通过在复杂环境中交替进行推理步骤和行动步骤来更有效地执行任务。ReActAgent 将推理和动作形成了闭环,Agent 可以自己完成给定的任务。
一个典型的 ReActAgent 遵循以下循环:
- 初始推理:代理首先进行推理步骤,以理解任务、收集相关信息并决定下一步行为。
- 行动:代理基于其推理采取行动——例如查询API、检索数据或执行命令。
- 观察:代理观察行动的结果并收集任何新的信息。
- 优化推理:利用新信息,代理再次进行推理,更新其理解、计划或假设。
- 重复:代理重复该循环,在推理和行动之间交替,直到达到满意的结论或完成任务。
本地模型实现 Agent
实现最简单的代码,通过外部工具做算术题,只是一个简单的例子,这个不用 Agent,大模型也可以回答。
from llm import get_local_ollama
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool
llm = get_local_ollama()
def multiply(a: float, b: float) -> float:
"""Multiply two numbers and returns the product"""
return a * b
multiply_tool = FunctionTool.from_defaults(fn=multiply)
def add(a: float, b: float) -> float:
"""Add two numbers and returns the sum"""
return a + b
add_tool = FunctionTool.from_defaults(fn=add)
agent = ReActAgent.from_tools([multiply_tool, add_tool], llm=llm, verbose=True)
response = agent.chat("What is 20+(2*4)?")
当我们问大模型一个天气的问题,当没有工具时,大模型这么回答,作为大语言模型,他不知道天气情况并给出去哪里可以查到天气情况。
现在为我们的 Agent 添加一个查询天气的方法,返回假数据做测试
def get_weather(city: str) -> int:
"""
Gets the weather temperature of a specified city.
Args:
city (str): The name or abbreviation of the city.
Returns:
int: The temperature of the city. Returns 20 for 'NY' (New York),
30 for 'BJ' (Beijing), and -1 for unknown cities.
"""
# Convert the input city to uppercase to handle case-insensitive comparisons
city = city.upper()
# Check if the city is New York ('NY')
if city == "NY":
return 20 # Return 20°C for New York
# Check if the city is Beijing ('BJ')
elif city == "BJ":
return 30 # Return 30°C for Beijing
# If the city is neither 'NY' nor 'BJ', return -1 to indicate unknown city
else:
return -1
weather_tool = FunctionTool.from_defaults(fn=get_weather)
agent = ReActAgent.from_tools([multiply_tool, add_tool, weather_tool], llm=llm, verbose=True)
response = agent.chat("纽约天气怎么样?")
可以看到模型的推理能力很强,将纽约转成了 NY。
可以在 arize_phoenix 中看到 agent 的具体提示词,工具被装换成了提示词。
总结
ReActAgent 使得业务自动向代码转换成为可能,只要有 API 模型就可以调用,很多业务场景都适用,LlamaIndex 提供了一些开源的工具实现,可以到官网查看。
虽然 Agent 可以实现业务功能, 但是一个 Agent 不能完成所有的功能,这也符合软件解耦的设计原则,不同的 Agent 可以完成不同的任务,各司其职,Agent 之间可以进行交互、通信,类似于微服务。后续的文章中,我们将继续介绍 Agent 的高级实现方式。