☰
【Agent】7. 使用Anthropic函数调用构建智能代理
2026/10/26 7:02:17 网站建设 项目流程

本案例展示了如何使用LlamaIndex构建一个基于Anthropic函数调用能力的智能代理。该代理能够使用预定义的工具执行特定任务,并通过函数调用机制与外部系统交互。

1. 案例目标

本案例的主要目标是演示如何使用LlamaIndex和Anthropic API构建一个具有函数调用能力的智能代理。具体来说,我们将:

  • 创建一个基于Anthropic的FunctionAgent
  • 定义简单的计算工具(加法和乘法)
  • 演示代理如何使用工具执行数学计算
  • 展示如何管理代理的上下文和记忆
  • 构建一个基于RAG的代理,用于查询文档内容

2. 技术栈与核心依赖

  • LlamaIndex- 用于构建智能代理和工作流
  • Anthropic API- 提供Claude语言模型和函数调用功能
  • OpenAI API- 提供文本嵌入模型
  • FunctionAgent- 用于构建具有函数调用能力的代理
  • VectorStoreIndex- 用于构建RAG系统
  • QueryEngineTool- 用于将查询引擎封装为工具

核心依赖包

%pip install llama-index %pip install llama-index-llms-anthropic %pip install llama-index-embeddings-openai

3. 环境配置

首先需要设置Anthropic API密钥:

from llama_index.llms.anthropic import Anthropic llm = Anthropic(model="claude-3-opus-20240229", api_key="sk-...")

对于RAG部分,还需要设置OpenAI API密钥:

from llama_index.embeddings.openai import OpenAIEmbedding embed_model = OpenAIEmbedding( model_name="text-embedding-3-large", api_key="sk-proj-..." ) query_llm = Anthropic(model="claude-3-haiku-20240307", api_key="sk-...")

4. 案例实现

4.1 工具定义

定义简单的计算工具:

def multiply(a: int, b: int) -> int: """Multiple two integers and returns the result integer""" return a * b def add(a: int, b: int) -> int: """Add two integers and returns the result integer""" return a + b

4.2 初始化Anthropic代理

使用定义好的工具创建FunctionAgent:

from llama_index.core.agent.workflow import FunctionAgent agent = FunctionAgent( tools=[multiply, add], llm=llm, )

4.3 代理交互

创建一个函数来运行代理并显示详细的工具调用信息:

from llama_index.core.agent.workflow import ToolCallResult async def run_agent_verbose(query: str): handler = agent.run(query) async for event in handler.stream_events(): if isinstance(event, ToolCallResult): print( f"Called tool {event.tool_name} with args {event.tool_kwargs}\nGot result: {event.tool_output}" ) return await handler

4.4 执行数学计算

使用代理执行数学计算:

response = await run_agent_verbose("What is (121 + 2) * 5?") print(str(response))

输出示例:

Called tool add with args {'a': 121, 'b': 2} Got result: 123 Called tool multiply with args {'a': 123, 'b': 5} Got result: 615 Therefore, (121 + 2) * 5 = 615

4.5 管理上下文/记忆

默认情况下,`.run()`是无状态的。如果要维护状态,可以传入一个`context`对象:

from llama_index.core.workflow import Context ctx = Context(agent) response = await agent.run("My name is John Doe", ctx=ctx) response = await agent.run("What is my name?", ctx=ctx) print(str(response))

4.6 构建基于RAG的代理

4.6.1 准备数据
!mkdir -p 'data/10k/' !wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/10k/uber_2021.pdf' -O 'data/10k/uber_2021.pdf'
4.6.2 构建查询引擎
from llama_index.core.tools import QueryEngineTool from llama_index.core import SimpleDirectoryReader, VectorStoreIndex # 加载数据 uber_docs = SimpleDirectoryReader( input_files=["./data/10k/uber_2021.pdf"] ).load_data() # 构建索引 uber_index = VectorStoreIndex.from_documents( uber_docs, embed_model=embed_model ) uber_engine = uber_index.as_query_engine(similarity_top_k=3, llm=query_llm) query_engine_tool = QueryEngineTool.from_defaults( query_engine=uber_engine, name="uber_10k", description=( "Provides information about Uber financials for year 2021. " "Use a detailed plain text question as input to the tool." ), )
4.6.3 创建基于RAG的代理
from llama_index.core.agent.workflow import FunctionAgent agent = FunctionAgent(tools=[query_engine_tool], llm=llm, verbose=True)
4.6.4 查询文档内容
response = await agent.run( "Tell me both the risk factors and tailwinds for Uber?" ) print(str(response))

5. 案例效果

5.1 数学计算能力

代理成功使用定义的加法和乘法工具执行了复杂的数学计算。具体来说:

  • 代理正确解析了数学表达式"(121 + 2) * 5"
  • 代理首先调用加法工具计算121 + 2 = 123
  • 然后调用乘法工具计算123 * 5 = 615
  • 最后给出了完整的计算过程和结果

5.2 上下文记忆能力

通过Context对象,代理能够记住之前的对话内容。当用户询问"我的名字是什么?"时,代理能够正确回答之前提到的"John Doe"。这展示了代理的状态管理能力。

5.3 文档查询能力

基于RAG的代理成功查询了Uber 2021年的10-K文档,并提取了关于风险因素和增长机会的信息。具体来说:

  • 代理正确识别了需要使用查询工具来回答问题
  • 代理将自然语言问题转换为适合查询引擎的格式
  • 代理从查询结果中提取了关键信息,并进行了总结
  • 代理提供了关于Uber风险因素和增长机会的详细回答

5.4 工具调用透明度

通过流式事件处理,用户可以清楚地看到代理调用了哪些工具、传递了什么参数以及获得了什么结果。这种透明度使得代理的行为更加可理解和可调试。

6. 案例实现思路

6.1 函数调用机制

本案例基于Anthropic的函数调用机制,允许语言模型调用预定义的函数。这种机制使得代理能够与外部系统交互,执行超出语言模型本身能力的任务,如数学计算、数据查询等。

6.2 工具定义与封装

通过定义Python函数并将其作为工具传递给FunctionAgent,我们实现了工具的封装。每个工具都有明确的参数类型和返回类型,以及描述其功能的文档字符串。这种设计使得代理能够理解工具的用途并正确调用它们。

6.3 代理与工具的交互

代理通过函数调用机制与工具交互。当用户提出请求时,代理会分析请求并决定是否需要调用工具。如果需要,代理会生成适当的函数调用,包括函数名和参数。工具执行后,代理会处理结果并生成最终回答。

6.4 状态管理

通过Context对象,我们实现了代理的状态管理。Context对象允许在多次调用之间共享状态,使代理能够记住之前的对话内容。这种状态管理对于构建有记忆的对话系统至关重要。

6.5 RAG集成

通过将RAG查询引擎封装为QueryEngineTool,我们实现了代理与RAG系统的集成。代理可以使用查询工具从文档中检索信息,从而回答基于特定文档的问题。这种扩展使得代理能够访问和利用外部知识库。

7. 扩展建议

7.1 增强工具能力

  • 添加更多类型的工具,如数据库查询、API调用、文件操作等
  • 实现工具的异步执行,提高并发性能
  • 添加工具权限管理,确保代理只能调用授权的工具

7.2 改进代理能力

  • 实现多轮对话中的工具链式调用,使代理能够解决更复杂的问题
  • 添加工具调用失败时的重试机制和错误处理
  • 实现工具调用的并行执行,提高效率

7.3 增强RAG功能

  • 集成多模态RAG,支持图像、音频等多种数据类型
  • 实现实时文档更新机制,保持RAG系统的知识新鲜度
  • 添加文档来源引用,提高回答的可信度和可验证性

7.4 优化用户体验

  • 实现更丰富的流式输出,包括中间步骤和思考过程
  • 添加可视化工具调用流程的界面
  • 实现用户反馈机制,允许用户纠正代理的错误

7.5 部署与扩展

  • 设计分布式代理架构,支持大规模并发请求
  • 实现代理的容器化部署,提高可移植性和可扩展性
  • 添加监控和日志系统,跟踪代理性能和使用情况

8. 总结

本案例展示了如何使用LlamaIndex和Anthropic API构建一个具有函数调用能力的智能代理。通过这个案例,我们了解了:

  • 如何定义工具并将其集成到代理中
  • 如何使用FunctionAgent创建具有函数调用能力的代理
  • 如何管理代理的上下文和记忆
  • 如何将RAG系统与代理集成,实现基于文档的问答
  • 如何通过流式事件处理监控代理的行为

函数调用机制是构建智能代理的关键技术之一,它使得代理能够与外部系统交互,执行超出语言模型本身能力的任务。通过将各种工具(如计算工具、查询工具、API工具等)集成到代理中,我们可以构建出功能强大的智能系统,解决各种复杂问题。

本案例中的代理虽然简单,但展示了构建智能代理的核心概念和技术。通过扩展工具集、改进代理能力和优化用户体验,我们可以构建出更加智能、更加实用的代理系统,为各行各业的数字化转型提供支持。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询