用llamaindex搭建GAR遇到400

中转代理遇到400

这是我根据llamaindex文档写的第一版代码:

python 复制代码
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI
import asyncio
import openai
from dotenv import load_dotenv
import os
# 加载当前目录.env文件存储的环境变量
load_dotenv()
# 变量赋值,以用于中转到openai
openai.api_key = os.environ[""]
openai.base_url = os.environ[""]
# Create a RAG tool using LlamaIndex
documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()

def multiply(a: float, b: float) -> float:
    """Useful for multiplying two numbers."""
    return a * b

async def search_documents(query: str) -> str:
    """Useful for answering natural language questions about an personal essay written by Paul Graham."""
    response = await query_engine.aquery(query)
    return str(response)

# Create an enhanced workflow with both tools
agent = FunctionAgent(
    tools=[multiply, search_documents],
    llm=OpenAI(model="gpt-4o-mini"),
    system_prompt="""You are a helpful assistant that can perform calculations
    and search through documents to answer questions.""",
)

# Now we can ask questions about the documents or do calculations
async def main():
    response = await agent.run(
        "What did the author do in college? Also, what's 7 * 8?"
    )
    print(response)

# Run the agent
if __name__ == "__main__":
    asyncio.run(main())

问题描述

问题显示代理不支持 tool calling

问题分析

我把multiply保留,search_documents删掉了代码就能跑通,证明代理是可以使用的,可能是代码调用的方法存在问题。最后经过对gpt的反复拷问,得到真实原因。

*messages with role 'tool' must be a response...*报错,本质上就是因为你用的 中转代理(OpenAI 兼容 API)并没有完整实现 OpenAI 的 Tool Calling 协议。

LlamaIndex 的 FunctionAgent 默认是走 OpenAI 官方的工具调用协议,所以才会发 {"role": "tool"} 的消息。中转代理一旦不支持,就直接 400。

解决方案

方案 1(推荐,最简单):换成官方api

如果你一定要用 FunctionAgent,那么代理必须支持 tool calling。

换掉中转代理,直接用官方 https://api.openai.com/v1。

确保 OPENAI_API_KEY 可用

方案 2:换成 ReActAgent

ReActAgent 不依赖 Tool Calling 协议,它只用纯文本 ReAct 推理方式来调工具,更兼容各种代理。
成功跑通代码:

python 复制代码
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool
from llama_index.llms.openai import OpenAI as LIOpenAI
import asyncio, os
from dotenv import load_dotenv
load_dotenv()
documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()

def multiply(a: float, b: float) -> float:
    return a * b

async def search_documents(query: str) -> str:
    resp = await query_engine.aquery(query)
    return str(resp)

# 关键:把代理地址和 key 显式传给 LlamaIndex 的 OpenAI 封装
llm = LIOpenAI(
    model="gpt-4o-mini",  # 换成你的代理支持的模型名
    api_key=os.environ[""],
    api_base=os.environ[""],
)

tools = [
    FunctionTool.from_defaults(fn=multiply),
    FunctionTool.from_defaults(fn=search_documents),
]

# 0.13.2 正确用法:直接实例化
agent = ReActAgent(
    tools=tools,
    llm=llm,
    verbose=True,
    system_prompt="You can calculate and search documents."
)

async def main():
    ans = await agent.run("What did the author do in college? Also, what's 7 * 8?")
    print(ans)

if __name__ == "__main__":
    asyncio.run(main())

注意

llama-index<=0.12 → 只能 ReActAgent(...) 直接实例化

llama-index==0.13.x → 用 ReActAgent.run(...)

llama-index>=0.14 → 才有 ReActAgent.from_tools(...)

相关推荐
黄沐阳1 天前
stp,rstp,mstp的区别
服务器·网络·php
2501_915918411 天前
掌握 iOS 26 App 运行状况,多工具协作下的监控策略
android·ios·小程序·https·uni-app·iphone·webview
清静诗意1 天前
在 Ubuntu 上安装 MinIO 并使用 Python 封装类操作对象存储
服务器·minio
Wang's Blog1 天前
Linux小课堂: 文件操作警惕高危删除命令与深入文件链接机制
linux·运维·服务器
2501_915909061 天前
iOS 混淆实战,多工具组合完成 IPA 混淆与加固(源码 + 成品 + 运维一体化方案)
android·运维·ios·小程序·uni-app·iphone·webview
我科绝伦(Huanhuan Zhou)1 天前
分享一个可以一键制作在线yum源的脚本
linux·运维
爱宇阳1 天前
禅道社区版 Docker Compose 服务迁移教程
运维·docker·容器
Paper_Love1 天前
Linux-查看硬件接口软件占用
linux·运维·服务器
wydaicls1 天前
Linux 系统下 ZONE 区域的划分
linux·运维·服务器