WiiCITMS/ai_tool_guide.md
2025-11-07 14:14:34 +08:00

170 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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: ''})
```
如果您遇到同样的问题,对其他工具也采用类似的方法,始终提供至少一个参数,即使是空值。