[Bug]: Tool schema marks **kwargs as a required (untyped) parameter, forcing the LLM to fill it

用户在 LlamaIndex 中使用 FunctionTool.from_defaults() 包装一个带有 **kwargs 的函数,然后通过 llm.chat_with_tools() 调用 OpenAI 驱动并启用 strict=True 模式时触发此错误。该错误同样适用于其他带有 *args

[Bug]: Tool schema marks **kwargs as a required (untyped) parameter, forcing the LLM to fill it

[Bug]: Tool schema marks **kwargs as a required (untyped) parameter, forcing the LLM to fill it

快速结论:该报错发生在 LlamaIndex 的 FunctionTool 构建工具参数 schema 时,将函数定义中的 **kwargs*args 错误地当作必需参数处理,导致 OpenAI 严格模式(strict=True)拒绝调用。优先排查你的工具函数中是否包含了 **kwargs 并改用显式参数定义。

问题场景

用户在 LlamaIndex 中使用 FunctionTool.from_defaults() 包装一个带有 **kwargs 的函数,然后通过 llm.chat_with_tools() 调用 OpenAI 驱动并启用 strict=True 模式时触发此错误。该错误同样适用于其他带有 *args 或任意可变参数的函数。

报错原文

ERROR: BadRequestError
Error code: 400 - {'error': {'message': "Invalid schema for function 'search': In context=('properties', 'kwargs'), schema must have a 'type' key.", 'type': 'invalid_request_error', 'param': 'tools[0].function.parameters', 'code': 'invalid_function_parameters'}}

原因分析

问题出在 LlamaIndex core 的 create_schema_from_function 函数(位于 tools/utils.py)。该函数在遍历 signature(func).parameters 时,没有检查参数的 param.kind,导致 VAR_KEYWORD(即 **kwargs)和 VAR_POSITIONAL(即 *args)被当作普通参数处理。由于 **kwargs 的默认值为 Parameter.empty,它被标记为必需字段,且类型为 Any——这违反了 OpenAI 严格模式的 JSON Schema 要求,因为没有 type 键的值不被允许。

环境排查

  • LlamaIndex 版本:确认是否 ≤ 0.14.23(已知受影响版本)。
  • OpenAI LLM 配置:检查 OpenAI(model="...", strict=True) 中 strict 是否设置为 True(严格模式更易触发)。
  • 工具函数签名:检查 FunctionTool 包装的函数是否包含 **kwargs*args

解决步骤

  1. 推荐临时方案:移除函数中的 **kwargs,改用显式参数定义。
    from llama_index.core.tools import FunctionTool
    
    def search(query: str) -> str:
        """Search the web."""
        return _search_impl(query)  # 如有需要,内部调用封装
    
    tool = FunctionTool.from_defaults(fn=search)
    

    这是最直接且稳妥的做法,可优先尝试。

  2. 备选方案(无需改函数):使用 FunctionTool.from_defaultstool_metadata 参数手动提供 fn_schema,排除 kwargs 字段。
    (需自行构造一个不含 kwargs 的 pydantic 模型)
  3. 永久修复(等待官方合并或自行 Patch):tools/utils.pycreate_schema_from_function 中添加 param.kind 检查:
    import inspect
    
    # 在遍历 params 时跳过可变参数
    for param_name in params:
        if param_name in ignore_fields:
            continue
        if params[param_name].kind in (
            inspect.Parameter.VAR_POSITIONAL,
            inspect.Parameter.VAR_KEYWORD,
        ):
            continue
        # ... 原有 schema 构建逻辑
    

    该补丁已经在 Issue 中得到确认,只需要检查 param.kind 来跳过 *args/**kwargs 即可。

验证方法

修改后重新运行触发报错的代码(如 Issue 中的 llm.chat_with_tools 样例),观察是否不再抛出 BadRequestError(400) 错误,且 LLM 能正常返回工具调用结果。

参考来源

run-llama/llama_index #22134

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 11451

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注