腾讯云API签名问题修复
# 腾讯云API接入方式改进
## 问题描述
在测试腾讯云混元大模型连接时,使用腾讯云原生API v3签名算法时出现签名验证失败错误:
```
[AuthFailure.SignatureFailure] The provided credentials could not be validated
```
## 解决方案:改用OpenAI兼容接口
腾讯云混元大模型完全支持**OpenAI兼容接口**,无需实现复杂的签名算法,只需使用简单的Bearer Token认证即可。
### OpenAI兼容接口配置
- **Base URL**: `https://api.hunyuan.cloud.tencent.com/v1`
- **认证方式**: `Authorization: Bearer {SecretId}:{SecretKey}`
- **Chat接口**: `/chat/completions`
- **Embedding接口**: `/embeddings`
- **官方文档**: https://cloud.tencent.com/document/product/1729/111007
## 代码实现
### 1. Chat接口(app/Controllers/Admin/Tencent.php)
```php
private function callTencentAi($secretId, $secretKey, $region, $model, $message)
{
// 腾讯云混元OpenAI兼容接口
$endpoint = 'https://api.hunyuan.cloud.tencent.com/v1';
// API Key格式:SecretId:SecretKey
$apiKey = $secretId . ':' . $secretKey;
$client = \Config\Services::curlrequest();
$response = $client->post($endpoint . '/chat/completions', [
'headers' => [
'Authorization' => 'Bearer ' . $apiKey,
'Content-Type' => 'application/json',
],
'json' => [
'model' => $model,
'messages' => [
['role' => 'user', 'content' => $message]
],
'stream' => false
],
'timeout' => 30,
'verify' => false
]);
$result = json_decode($response->getBody(), true);
if (isset($result['choices'][0]['message']['content'])) {
return $result['choices'][0]['message']['content'];
}
if (isset($result['error'])) {
$error = $result['error'];
$errorMsg = $error['message'] ?? '未知错误';
if (isset($error['code'])) {
$errorMsg = '[' . $error['code'] . '] ' . $errorMsg;
}
throw new \Exception($errorMsg);
}
}
```
### 2. Embedding接口(app/Controllers/Admin/Embedding.php)
```php
private function testTencentEmbedding($config, $testText)
{
// 获取腾讯云配置
$secretId = $tencentData['secret_id'] ?? '';
$secretKey = $tencentData['secret_key'] ?? '';
$model = 'hunyuan-embedding'; // 固定模型名称
// 腾讯云混元OpenAI兼容接口
$endpoint = 'https://api.hunyuan.cloud.tencent.com/v1';
// API Key格式:SecretId:SecretKey
$apiKey = $secretId . ':' . $secretKey;
$client = \Config\Services::curlrequest();
$response = $client->post($endpoint . '/embeddings', [
'headers' => [
'Authorization' => 'Bearer ' . $apiKey,
'Content-Type' => 'application/json',
],
'json' => [
'model' => $model,
'input' => $testText
],
'timeout' => 30,
'verify' => false
]);
$result = json_decode($response->getBody(), true);
if (isset($result['data'][0]['embedding'])) {
$vector = $result['data'][0]['embedding'];
// 处理向量数据...
}
}
```
### 3. Embedding服务(app/Libraries/EmbeddingService.php)
```php
private function embedWithTencent(string $text): ?array
{
// 获取腾讯云配置
$secretId = $config['secret_id'] ?? '';
$secretKey = $config['secret_key'] ?? '';
$model = $this->config['tencent_embedding_model'] ?? 'hunyuan-embedding';
// 腾讯云混元OpenAI兼容接口
$endpoint = 'https://api.hunyuan.cloud.tencent.com/v1';
// API Key格式:SecretId:SecretKey
$apiKey = $secretId . ':' . $secretKey;
$client = \Config\Services::curlrequest();
$response = $client->post($endpoint . '/embeddings', [
'headers' => [
'Authorization' => 'Bearer ' . $apiKey,
'Content-Type' => 'application/json',
],
'json' => [
'model' => $model,
'input' => mb_substr($text, 0, 2000)
],
'timeout' => 30,
'verify' => false
]);
$result = json_decode($response->getBody(), true);
if (isset($result['data'][0]['embedding'])) {
return $result['data'][0]['embedding'];
}
return null;
}
```
## 关键变化对比
### 原生API v3方式(已废弃)
**缺点:**
- 需要实现复杂的TC3-HMAC-SHA256签名算法
- 需要计算规范请求串、待签名字符串
- 需要多次HMAC-SHA256计算
- 容易出现签名错误
- 代码复杂,难以维护
**请求头:**
```php
'Authorization' => 'TC3-HMAC-SHA256 Credential=...',
'X-TC-Action' => 'ChatCompletions',
'X-TC-Version' => '2023-09-01',
'X-TC-Timestamp' => '1234567890',
'X-TC-Region' => 'ap-guangzhou'
```
**响应格式:**
```json
{
"Response": {
"Choices": [...],
"Error": {...}
}
}
```
### OpenAI兼容接口(当前使用)
**优点:**
- 无需复杂的签名算法
- 使用简单的Bearer Token认证
- 完全兼容OpenAI接口规范
- 代码简洁,易于维护
- 更可靠,不易出错
**请求头:**
```php
'Authorization' => 'Bearer {SecretId}:{SecretKey}',
'Content-Type' => 'application/json'
```
**响应格式:**
```json
{
"choices": [
{
"message": {
"content": "..."
}
}
],
"error": {...}
}
```
## 修改的文件
1. **app/Controllers/Admin/Tencent.php**
- 修改 `callTencentAi()` 方法
- 移除复杂的签名算法
- 使用OpenAI兼容接口
2. **app/Controllers/Admin/Embedding.php**
- 修改 `testTencentEmbedding()` 方法
- 移除复杂的签名算法
- 使用OpenAI兼容接口
3. **app/Libraries/EmbeddingService.php**
- 修改 `embedWithTencent()` 方法
- 移除复杂的签名算法
- 使用OpenAI兼容接口
## 测试验证
### 测试步骤
1. **测试Chat接口**
- 进入"系统配置 > 腾讯云AI"
- 填写SecretId和SecretKey
- 点击"测试连接"
- 应该显示AI回复内容
2. **测试Embedding接口**
- 进入"系统配置 > Embedding配置"
- 选择"腾讯云"作为Embedding服务商
- 点击"测试Embedding"
- 应该显示向量维度和样本数据
### 预期结果
**Chat接口测试成功:**
```
测试成功!
AI回复:你好!我是腾讯混元大模型,一个由腾讯研发的AI助手...
```
**Embedding接口测试成功:**
```
测试成功!
模式:腾讯云向量语义搜索模式
模型:hunyuan-embedding
维度:1024 维向量
样本:0.1234, -0.5678, 0.9012, ...
```
## 技术优势
### 1. 简化认证
- **原来**:需要实现TC3-HMAC-SHA256签名算法(约100行代码)
- **现在**:只需拼接SecretId和SecretKey(1行代码)
### 2. 标准接口
- 完全兼容OpenAI接口规范
- 可以直接使用OpenAI SDK
- 响应格式统一,易于处理
### 3. 更可靠
- 避免签名计算错误
- 减少调试时间
- 提高代码可维护性
### 4. 更易扩展
- 支持所有OpenAI兼容的功能
- Function Calling
- 流式输出
- 多轮对话
## 常见问题
### Q1: API Key格式是什么?
A: `{SecretId}:{SecretKey}`,用冒号连接,例如:
```
AKIDxxxxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxx
```
### Q2: 支持哪些模型?
A:
- Chat模型:`hunyuan-lite`, `hunyuan-standard`, `hunyuan-pro`, `hunyuan-turbo`, `hunyuan-turbos-latest`
- Embedding模型:`hunyuan-embedding`(固定,维度1024)
### Q3: 如何查看调试日志?
```bash
# 查看最新日志
tail -f writable/logs/log-$(date +%Y-%m-%d).log | grep -i "tencent"
```
### Q4: 还是提示错误怎么办?
检查以下几点:
1. SecretId和SecretKey是否正确(注意空格)
2. 密钥是否已启用
3. 密钥权限是否包含混元API
4. 是否有足够的API调用额度
### Q5: 与火山方舟有什么区别?
- **火山方舟**:使用火山引擎的Embedding模型
- **腾讯云**:使用腾讯混元的Embedding模型
- 两者可以独立配置,互不影响
## 参考资料
- [腾讯云混元OpenAI兼容接口文档](https://cloud.tencent.com/document/product/1729/111007)
- [OpenAI API文档](https://platform.openai.com/docs/api-reference)
- [混元大模型产品概述](https://cloud.tencent.com/document/product/1729/104753)
## 更新日志
- **2026-01-21**:改用OpenAI兼容接口,移除复杂的签名算法
- **2026-01-21**:统一三个文件中的实现方式
- **2026-01-21**:更新文档说明新的接入方式
版本 1 · 约 7,042 字
暂无评论