Files
claude-code/docs/openai-task-tools.md
bonerush 91ee1428fa Fix bug OpenAI tooluse,Improve error messaging for deferred-loading tools under OpenAI‑compatible models. (#199)
* fix: reorder tool and user messages for OpenAI API compatibility (#168)
Fixes #168
OpenAI requires that an assistant message with tool_calls be immediately
followed by tool messages. Previously, convertInternalUserMessage
output user content before tool results, causing 400 errors.
Now tool messages are pushed first.

* fix: 修复OpenAI兼容层中deferred tools处理问题

  提交描述:
  修复了在使用OpenAI兼容API时TaskCreate工具调用失败的问题。

  问题:
  - 当使用OpenAI兼容API模型时,调用TaskCreate工具出现"InputValidationError: The required
  parameter `subject` is missing"错误
  - OpenAI兼容层没有正确处理deferred tools的过滤逻辑,导致工具schema没有被正确发送给模型

  修复:
  1. 在OpenAI兼容层中添加了与Anthropic API路径一致的deferred tools处理逻辑
  2. 导入必要的工具搜索相关函数: isToolSearchEnabled, extractDiscoveredToolNames,
  isDeferredTool等
  3. 实现工具过滤逻辑:
     - 检查工具搜索是否启用
     - 构建deferred tools集合
     - 过滤工具列表: 只包含非deferred工具或已发现的deferred工具
     - 为deferred tools设置deferLoading标志
  4. 修正了extractDiscoveredToolNames函数的导入路径错误

  影响:
  - 解决了TaskCreate工具调用时的参数验证错误
  - 确保OpenAI兼容层与Anthropic API路径在处理deferred tools时行为一致
  - 支持工具搜索功能在OpenAI兼容模式下正常工作

  修改的文件:
  - src/services/api/openai/index.ts - 主要修复文件

  测试建议:
  1. 使用OpenAI兼容API模型时,TaskCreate工具应该可以正常调用
  2. 如果工具搜索功能启用,可能需要先使用ToolSearchTool来发现TaskCreate工具
  3. 验证工具调用时不再出现"InputValidationError"错误

  这个修复确保了当使用OpenAI兼容API(如Ollama、DeepSeek、vLLM等)时,deferred
  tools(如TaskCreate)能够被正确处理,解决了工具调用失败的问题。

* fix: 更新工具模式未发送提示,增加OpenAI兼容模型使用指南
2026-04-08 18:08:59 +08:00

6.2 KiB
Raw Blame History

OpenAI兼容模型中task工具使用指南

问题描述

当使用OpenAI兼容模型如DeepSeek、Ollama、vLLM等调用task工具TaskGet、TaskCreate、TaskUpdate、TaskList可能会出现以下错误

Error: InputValidationError: TaskGet failed due to the following issues:
   The required parameter `taskId` is missing
   An unexpected parameter `task_id` was provided
   
   This tool's schema was not sent to the API — it was not in the discovered-tool set derived from message history. Without the schema in your prompt, typed parameters (arrays, numbers, booleans) get emitted as strings and the client-side parser rejects them. Load the tool first: call ToolSearch with query "select:TaskGet", then retry this call.

问题原因

1. 延迟加载工具Deferred Tools

task工具都是延迟加载的shouldDefer: true),这意味着:

  • 工具的模式schema不会在初始API调用中发送
  • 需要先通过ToolSearch工具发现
  • 只有在被发现后工具模式才会被发送给API

2. 参数名转换问题

  • task工具使用驼峰命名taskId
  • OpenAI兼容模型可能输出蛇形命名task_id
  • 当工具模式没有被发送时,模型会猜测参数名,可能导致不匹配

解决方案

方案1先使用ToolSearch推荐

在使用task工具之前先调用ToolSearch工具:

// 第一步发现task工具
ToolSearch("select:TaskGet,TaskCreate,TaskUpdate,TaskList")

// 第二步正常使用task工具
TaskCreate({ subject: "任务标题", description: "任务描述" })
TaskGet({ taskId: "1" })
TaskUpdate({ taskId: "1", status: "completed" })
TaskList()

方案2批量发现所有task工具

// 一次性发现所有task工具
ToolSearch("select:TaskGet,TaskCreate,TaskUpdate,TaskList")

// 然后可以任意使用task工具
const task = await TaskCreate({ subject: "新任务", description: "任务描述" })
console.log(`创建的任务ID: ${task.id}`)

const taskList = await TaskList()
console.log(`当前有 ${taskList.tasks.length} 个任务`)

方案3单独发现特定工具

// 只发现需要的工具
ToolSearch("select:TaskGet")

// 然后使用该工具
TaskGet({ taskId: "1" })

参数名注意事项

在使用OpenAI兼容模型时请注意参数名格式

正确(驼峰命名)

TaskGet({ taskId: "1" })
TaskCreate({ subject: "标题", description: "描述" })
TaskUpdate({ taskId: "1", status: "completed" })

错误(蛇形命名)

TaskGet({ task_id: "1" })  // 错误应该使用taskId
TaskCreate({ subject: "标题", description: "描述" })  // 正确
TaskUpdate({ task_id: "1", status: "completed" })  // 错误应该使用taskId

常见问题解答

Q1: 为什么需要先使用ToolSearch

A: task工具是延迟加载的它们的模式只有在被ToolSearch工具发现后才会发送给API。没有工具模式模型无法知道正确的参数名和类型。

Q2: 每次会话都需要使用ToolSearch吗

A: 是的每次新的会话都需要先使用ToolSearch发现工具。工具发现状态不会在会话之间保留。

Q3: 使用Anthropic官方模型也需要这样吗

A: 通常不需要。Anthropic官方模型对延迟加载工具的处理更智能但为了兼容性建议在使用task工具前都先使用ToolSearch。

Q4: 可以一次性发现所有工具吗?

A: 可以,使用ToolSearch("select:TaskGet,TaskCreate,TaskUpdate,TaskList")可以一次性发现所有task工具。

Q5: 如果忘记使用ToolSearch会怎样

A: 会收到参数验证错误提示需要先使用ToolSearch。按照错误信息的指导操作即可。

最佳实践

  1. 会话开始时发现工具在开始使用task工具前先调用ToolSearch
  2. 批量发现一次性发现所有需要的task工具
  3. 检查参数名:确保使用正确的驼峰命名参数
  4. 查看错误信息:如果遇到错误,仔细阅读错误信息中的指导

示例工作流

// 1. 开始新会话
// 2. 发现task工具
ToolSearch("select:TaskGet,TaskCreate,TaskUpdate,TaskList")

// 3. 创建任务
const newTask = await TaskCreate({
  subject: "修复OpenAI兼容性问题",
  description: "解决task工具在OpenAI兼容模型下的参数名问题"
})

// 4. 获取任务详情
const taskDetails = await TaskGet({ taskId: newTask.id })

// 5. 更新任务状态
await TaskUpdate({ 
  taskId: newTask.id, 
  status: "in_progress",
  activeForm: "修复OpenAI兼容性问题"
})

// 6. 查看所有任务
const allTasks = await TaskList()
console.log(`当前有 ${allTasks.tasks.length} 个任务`)

// 7. 完成任务
await TaskUpdate({ 
  taskId: newTask.id, 
  status: "completed"
})

故障排除

错误:参数名不匹配

症状taskId参数缺失,发现task_id参数 解决:确保使用驼峰命名的taskId,而不是蛇形命名的task_id

错误:工具模式未发送

症状This tool's schema was not sent to the API 解决:先使用ToolSearch("select:工具名")发现工具

错误:工具不可用

症状:工具调用失败,没有具体错误信息 解决:检查工具是否启用(通过isTodoV2Enabled()),确保环境变量设置正确

相关配置

环境变量

# 启用OpenAI兼容模式
export CLAUDE_CODE_USE_OPENAI=1
export OPENAI_API_KEY=your-api-key
export OPENAI_BASE_URL=https://api.deepseek.com

# 配置模型映射
export OPENAI_DEFAULT_SONNET_MODEL=deepseek-chat
export OPENAI_DEFAULT_OPUS_MODEL=deepseek-chat
export OPENAI_DEFAULT_HAIKU_MODEL=deepseek-chat

设置文件

通过/login命令配置OpenAI兼容模式后设置会保存在~/.claude/settings.json

{
  "modelType": "openai",
  "openai": {
    "baseURL": "https://api.deepseek.com",
    "apiKey": "your-api-key",
    "models": {
      "haiku": "deepseek-chat",
      "sonnet": "deepseek-chat",
      "opus": "deepseek-chat"
    }
  }
}

总结

在使用OpenAI兼容模型时task工具需要先通过ToolSearch发现才能正常使用。遵循"先发现,后使用"的原则并注意参数名的正确格式驼峰命名可以确保task工具在OpenAI兼容模型下正常工作。