WiiCITMS/ai_tool_guide.md

170 lines
5.3 KiB
Markdown
Raw Permalink Normal View History

2025-11-07 14:14:34 +08:00
# AI工具调用指南
本文档提供了解决OpenAI API工具调用验证错误的方法和建议。
## 常见错误
您遇到的错误是一个标准的OpenAI API参数验证错误
```
BadRequestError: Error code: 400 - {'error': {'message': "3 validation errors for ValidatorIterator\n0.ChatCompletionMessageFunctionToolCallParam.function.arguments\n Input should be a valid string [type=string_type, input_value=None, input_type=NoneType]\n For further information visit https://errors.pydantic.dev/2.11/v/string_type\n0.ChatCompletionMessageCustomToolCallParam.custom\n Field required [type=missing, input_value={'type': 'function', 'id'...ns', 'arguments': None}}, input_type=dict]\n For further information visit https://errors.pydantic.dev/2.11/v/missing\n0.ChatCompletionMessageCustomToolCallParam.type\n Input should be 'custom' [type=literal_error, input_value='function', input_type=str]\n For further information visit https://errors.pydantic.dev/2.11/v/literal_error None", 'type': 'BadRequestError', 'param': None, 'code': 400}}
```
这个错误表明您在调用OpenAI API时工具调用参数验证失败。
## 解决方案
### 1. 确保每个工具调用都有有效的参数JSON字符串
在OpenAI API调用中即使工具不需要任何参数也必须提供一个空的JSON对象字符串 `"{}"`
**错误示例:**
```python
tool_call = {
"type": "function",
"function": {
"name": "queryPositions",
"arguments": None # 这会导致验证错误
}
}
```
**正确示例:**
```python
tool_call = {
"type": "function",
"function": {
"name": "queryPositions",
"arguments": "{}" # 即使没有参数也提供空的JSON对象字符串
}
}
```
### 2. 修改Python客户端代码
如果您使用Python调用OpenAI API可以使用以下模式来确保参数总是有效的JSON字符串
```python
import json
from openai import OpenAI
client = OpenAI(api_key="your-api-key")
def call_tool(tool_name, params=None):
# 确保参数是有效的JSON字符串
if params is None:
params_str = "{}"
elif isinstance(params, str):
# 如果已经是字符串确保是有效的JSON
try:
json.loads(params) # 验证JSON有效性
params_str = params
except json.JSONDecodeError:
params_str = "{}" # 如果无效,使用空对象
else:
# 将对象转换为JSON字符串
params_str = json.dumps(params)
# 调用OpenAI API
response = client.chat.completions.create(
model="gpt-4-turbo",
messages=[{"role": "user", "content": "使用工具执行任务"}],
tools=[{
"type": "function",
"function": {
"name": tool_name,
"description": "工具描述",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
}],
tool_choice={"type": "function", "function": {"name": tool_name}}
)
# 处理工具调用结果
tool_calls = response.choices[0].message.tool_calls
if tool_calls:
tool_call = tool_calls[0]
# 执行实际工具调用...
return tool_call.function.arguments
return None
# 使用示例
result = call_tool("queryPositions", {"query": "经理"})
# 或者不带参数
result = call_tool("queryPositions")
```
### 3. 在工具定义中添加必填参数
为避免参数验证问题,可以为每个工具添加至少一个必填参数。这样可以确保调用者必须提供参数。
```go
Tool: mcp.NewTool(
"queryPositions",
mcp.WithDescription("查询岗位列表"),
mcp.WithString("query", mcp.Required(), mcp.Description("搜索关键词,可为空字符串但必须提供")),
// 其他可选参数...
),
```
## 在JavaScript中调用API的正确方式
如果您在前端JavaScript中调用OpenAI API确保遵循以下模式
```javascript
async function callOpenAIWithTool(toolName, params = {}) {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${OPENAI_API_KEY}`
},
body: JSON.stringify({
model: 'gpt-4-turbo',
messages: [{ role: 'user', content: '使用工具执行任务' }],
tools: [{
type: 'function',
function: {
name: toolName,
description: '工具描述',
parameters: {
type: 'object',
properties: {}
}
}
}],
tool_choice: { type: 'function', function: { name: toolName } }
})
});
const data = await response.json();
return data;
}
// 调用示例
callOpenAIWithTool('queryPositions', {query: ''}) // 提供空字符串也可以
.then(result => console.log(result))
.catch(error => console.error(error));
```
## 针对您的工具的特定解决方案
对于`queryPositions`工具,我建议始终提供一个空的查询参数:
```python
# Python示例
result = call_tool("queryPositions", {"query": ""})
```
```javascript
// JavaScript示例
callOpenAIWithTool('queryPositions', {query: ''})
```
如果您遇到同样的问题,对其他工具也采用类似的方法,始终提供至少一个参数,即使是空值。