Langroid项目中的聊天代理与工具调用机制详解
langroid Harness LLMs with Multi-Agent Programming 项目地址: https://gitcode.com/gh_mirrors/la/langroid
引言
在现代语言模型应用中,我们经常需要让大语言模型(LLM)不仅能生成自然语言文本,还能与外部系统进行结构化交互。Langroid项目提供了一套优雅的解决方案,让开发者能够轻松地为聊天代理(ChatAgent)配备工具调用(Tool/Function-call)能力。本文将深入解析这一机制的工作原理和实现方式。
工具调用的基本概念
工具调用(或称函数调用)是一种让LLM生成结构化输出而非纯文本的机制。这种结构化输出可以被外部函数处理,从而实现更复杂的交互。常见的应用场景包括:
- 从文档中提取结构化信息
- 执行特殊计算(如单位转换)
- 代码执行(在沙箱环境中)
- 发起API调用
Langroid提供了两种实现方式:
- 原生工具机制(适用于非OpenAI模型)
- OpenAI函数调用API(专为OpenAI模型优化)
开发者可以通过配置ChatAgentConfig
中的use_tools
和use_functions_api
标志来选择使用哪种方式。
实战示例:寻找列表中的最小数字
为了更好地理解这一机制,我们通过一个简单的数字游戏示例来演示。在这个游戏中,代理(Agent)持有一个数字列表,LLM需要通过"探测"工具来找出列表中的最小数字。
第一步:定义工具消息
我们首先定义一个ProbeTool
类,继承自ToolMessage
:
class ProbeTool(lr.agent.ToolMessage):
request: str = "probe" # 指定处理此消息的代理方法名
purpose: str = """
找出列表中接近你指定<number>的数字
""" # 工具的目的说明
number: int # 必需的参数
@classmethod
def examples(cls):
# 提供给LLM的示例
return [
cls(number=10),
(
"要找出接近20的数字",
cls(number=20),
)
]
这个定义清晰地说明了:
- 工具将由代理的
probe
方法处理 - 工具的目的是找出接近指定数字的值
- 必须提供
number
参数 - 提供了使用示例帮助LLM理解工具用法
第二步:创建聊天代理
接下来我们创建自定义的聊天代理类:
class SpyGameAgent(lr.ChatAgent):
def __init__(self, config: lr.ChatAgentConfig):
super().__init__(config)
self.numbers = [3, 4, 8, 11, 15, 25, 40, 80, 90] # 代理持有的数字列表
def probe(self, msg: ProbeTool) -> str:
# 返回小于等于指定数字的元素数量
return str(len([n for n in self.numbers if n <= msg.number]))
关键点:
- 代理持有私有的数字列表
probe
方法名必须与工具定义中的request
字段匹配- 方法接收
ProbeTool
消息并返回处理结果
第三步:配置并启用工具
配置代理并启用工具:
config = lr.ChatAgentConfig(
name="Spy",
llm = lr.language_models.OpenAIGPTConfig(
chat_model=lr.language_models.OpenAIChatModel.GPT4o,
),
use_tools=True, # 启用原生工具机制
use_functions_api=False, # 禁用OpenAI函数调用
vecdb=None,
)
spy_game_agent = SpyGameAgent(config)
spy_game_agent.enable_message(ProbeTool) # 启用ProbeTool处理
第四步:创建任务并运行
最后设置任务指令并运行:
task = lr.Task(
spy_game_agent,
system_message="""
我有一个1到100之间的数字列表。
你的任务是找出其中最小的数字。
为此,你可以给我一个数字,我会告诉你
有多少个数字小于等于你提供的数字。
当你找到最小数字后,可以说DONE并报告答案。
"""
)
task.run()
工具调用的高级特性
无状态工具处理
除了上述需要访问代理状态的有状态工具外,Langroid还支持无状态工具。这类工具可以直接在ToolMessage
类中定义handle
方法,无需子类化ChatAgent
。
异步工具处理
对于异步任务(task.run_async()
),可以实现异步工具处理方法(如probe_async
)。
实际应用场景
工具调用机制在实际中有广泛应用:
- 文档信息提取:从合同或技术文档中提取结构化数据
- 计算任务:执行模型无法直接完成的复杂计算
- 数据查询:从大型数据集中检索特定信息
- 工作流自动化:协调多个系统完成复杂任务
总结
Langroid的工具调用机制为LLM应用开发提供了强大而灵活的交互能力。通过本文的示例,我们了解了如何:
- 定义工具消息
- 创建具备工具处理能力的代理
- 配置和启用工具
- 设置任务并运行交互
这种机制极大地扩展了LLM的应用范围,使其能够与外部系统和数据进行更丰富的交互。开发者可以根据具体需求选择原生工具机制或OpenAI函数调用API,实现各种复杂的应用场景。
langroid Harness LLMs with Multi-Agent Programming 项目地址: https://gitcode.com/gh_mirrors/la/langroid
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考