php 8.2 调用通义千问 api 时,ai 拒绝输出需检查 http 状态码(如 400/403/429)和响应体中的 error 字段或空/敏感 content,而非依赖 try-catch;应结合 curl_getinfo、json_decode 及内容关键词判断拒答。

PHP 8.2 调用通义千问(Qwen)API 时,若 AI 拒绝输出(如因敏感内容、政策限制、输入格式异常等),通常不会抛出 PHP 异常,而是返回特定的 HTTP 状态码或 JSON 响应体中的错误字段。捕获这类“拒绝输出”需重点检查响应内容而非仅依赖 try-catch。
检查 HTTP 状态码与响应体结构
通义千问官方 API(如通过阿里云百炼平台调用)在拒绝生成时,常见返回:
- HTTP 400 Bad Request:输入参数缺失、message 为空、role 错误(如非 "user"/"assistant"/"system")
- HTTP 403 Forbidden:模型权限不足、Token 过期、服务未开通
- HTTP 429 Too Many Requests:触发流控,可能伴随限流提示
-
HTTP 200 OK + 含 error 字段的 JSON:最典型情况——请求成功但模型主动拒答,例如:
{"error": {"code": "InvalidParameter", "message": "内容违反安全策略,请修改后重试。"}}
解析响应 JSON 并判断拒绝原因
务必对 json_decode($responseBody, true) 结果做健壮判断,不能只看 isset($data['choices'][0]['message']['content']):
- 先检查是否存在
error键,有则直接提取error['message'] - 若返回
choices但content为空字符串或仅含占位符(如"..."、"(拒绝回答)"),也属于隐式拒答,需业务层识别 - 部分场景返回
finish_reason: "content_filter"(尤其在阿里云百炼 v1 接口),明确表示被内容安全策略拦截
使用 cURL 时添加超时与错误处理逻辑
PHP 8.2 中建议用 curl_setopt_array() 显式设置关键选项,避免静默失败:
- 设
CURLOPT_TIMEOUT => 30防止挂起 - 设
CURLOPT_FAILONERROR => false(默认),确保即使 4xx/5xx 也能拿到响应体 - 调用
curl_getinfo($ch, CURLINFO_HTTP_CODE)获取真实状态码,再结合curl_error()判断网络层问题
示例:基础捕获逻辑(精简版)
```php
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
throw new RuntimeException('cURL error: ' . curl_error($ch));
}
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException('Invalid JSON response');
}
// 关键:优先检查 error 字段
if (isset($data['error']['message'])) {
echo "AI 拒绝输出:{$data['error']['message']}";
// 可记录日志、降级返回或提示用户修改输入
}
// 兜底检查 content 是否有效
$content = $data['choices'][0]['message']['content'] ?? '';
if (empty(trim($content)) || str_contains($content, '拒绝') || str_contains($content, '安全')) {
echo "检测到空或策略拦截内容";
}
```
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











