Java调用千帆大模型平台:Chat API实战指南
2025.09.18 16:35浏览量:0简介:本文详细介绍Java调用千帆大模型平台对话Chat API的完整流程,涵盖环境准备、请求构建、签名生成、响应解析等核心步骤,并提供可复用的代码示例和异常处理方案。
一、环境准备与依赖配置
1.1 开发环境要求
调用千帆大模型平台Chat API需满足以下环境条件:
1.2 核心依赖配置
在Maven项目的pom.xml中添加以下依赖:
<dependencies>
<!-- HTTP客户端库(推荐OkHttp) -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
</dependency>
<!-- JSON处理库(推荐Jackson) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.4</version>
</dependency>
<!-- 签名工具库(可选) -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
</dependencies>
1.3 认证信息准备
调用API前需获取以下认证信息:
- AccessKey ID:平台分配的唯一标识
- SecretKey:用于签名计算的密钥
- API Key:部分接口可能需要单独的API Key
建议将敏感信息存储在环境变量或配置文件中,示例配置:
# config.properties
qianfan.accessKeyId=your_access_key_id
qianfan.secretKey=your_secret_key
qianfan.apiKey=your_api_key_if_needed
qianfan.endpoint=https://qianfan.baidu.com/api/v1
二、核心调用流程实现
2.1 请求签名生成
千帆平台要求对每个API请求进行HMAC-SHA256签名,实现步骤如下:
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class SignatureUtil {
public static String generateSignature(String secretKey, String stringToSign)
throws NoSuchAlgorithmException, InvalidKeyException {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(
secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256_HMAC.init(secret_key);
byte[] hash = sha256_HMAC.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hash);
}
}
2.2 请求构建与发送
完整请求流程包含以下步骤:
- 构建请求体:
```java
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
public class ChatRequest {
private String model; // 模型名称,如”ERNIE-Bot”
private String messages; // JSON格式的消息数组
private Integer temperature; // 创造力参数(0-1)
// 构造方法与getter/setter省略
public static String buildRequestBody(ChatRequest request) throws Exception {
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> body = new HashMap<>();
body.put("model", request.getModel());
body.put("messages", request.getMessages());
if (request.getTemperature() != null) {
body.put("temperature", request.getTemperature());
}
return mapper.writeValueAsString(body);
}
}
2. **构建完整请求**:
```java
import okhttp3.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class QianfanClient {
private final String endpoint;
private final String accessKeyId;
private final String secretKey;
private final OkHttpClient httpClient;
public QianfanClient(String endpoint, String accessKeyId, String secretKey) {
this.endpoint = endpoint;
this.accessKeyId = accessKeyId;
this.secretKey = secretKey;
this.httpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
}
public String chat(ChatRequest request) throws Exception {
// 1. 生成时间戳和随机字符串
long timestamp = System.currentTimeMillis() / 1000;
String nonce = String.valueOf(Math.random() * 1000000);
// 2. 构建请求体
String requestBody = ChatRequest.buildRequestBody(request);
// 3. 生成待签名字符串
String stringToSign = String.format(
"POST\n/api/v1/chat/completions\n%s\naccessKeyId=%s&nonce=%s×tamp=%s",
requestBody, accessKeyId, nonce, timestamp);
// 4. 计算签名
String signature = SignatureUtil.generateSignature(secretKey, stringToSign);
// 5. 构建请求URL和头部
String url = endpoint + "/chat/completions";
RequestBody body = RequestBody.create(
requestBody, MediaType.parse("application/json"));
Request req = new Request.Builder()
.url(url)
.post(body)
.addHeader("X-BF-ACCESSKEYID", accessKeyId)
.addHeader("X-BF-SIGNATURE", signature)
.addHeader("X-BF-NONCE", nonce)
.addHeader("X-BF-TIMESTAMP", String.valueOf(timestamp))
.addHeader("Content-Type", "application/json")
.build();
// 6. 发送请求并处理响应
try (Response response = httpClient.newCall(req).execute()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
return response.body().string();
}
}
}
2.3 响应解析与错误处理
典型成功响应示例:
{
"id": "chatcmpl-123456",
"object": "chat.completion",
"created": 1678901234,
"model": "ERNIE-Bot",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "这是模型的回复内容"
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 15,
"completion_tokens": 30,
"total_tokens": 45
}
}
解析响应的代码实现:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ChatResponse {
private String id;
private String model;
private String content;
public static ChatResponse parse(String json) throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json);
ChatResponse response = new ChatResponse();
response.id = root.path("id").asText();
response.model = root.path("model").asText();
JsonNode messageNode = root.path("choices").get(0)
.path("message");
response.content = messageNode.path("content").asText();
return response;
}
// getter方法省略
}
三、最佳实践与优化建议
3.1 性能优化策略
连接池管理:
// 创建带连接池的OkHttpClient
ConnectionPool pool = new ConnectionPool(5, 5, TimeUnit.MINUTES);
OkHttpClient client = new OkHttpClient.Builder()
.connectionPool(pool)
.build();
异步调用实现:
public void asyncChat(ChatRequest request, Callback callback) {
// 构建请求逻辑同上
httpClient.newCall(req).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callback.onFailure(e);
}
@Override
public void onResponse(Call call, Response response)
throws IOException {
String responseBody = response.body().string();
try {
ChatResponse chatResponse = ChatResponse.parse(responseBody);
callback.onSuccess(chatResponse);
} catch (Exception e) {
callback.onFailure(e);
}
}
});
}
3.2 错误处理机制
常见错误码及处理方案:
| 错误码 | 含义 | 处理建议 |
|————|———|—————|
| 401 | 认证失败 | 检查AccessKey/SecretKey有效性 |
| 403 | 权限不足 | 确认API权限配置 |
| 429 | 请求过频 | 实现指数退避重试 |
| 500 | 服务器错误 | 记录错误日志并重试 |
实现重试机制的示例:
public String chatWithRetry(ChatRequest request, int maxRetries)
throws Exception {
int retryCount = 0;
while (retryCount <= maxRetries) {
try {
return chat(request);
} catch (IOException e) {
if (retryCount >= maxRetries) {
throw e;
}
Thread.sleep((long) (Math.pow(2, retryCount) * 1000));
retryCount++;
}
}
throw new IOException("Max retries exceeded");
}
3.3 安全建议
敏感信息保护:
- 不要将AccessKey/SecretKey硬编码在代码中
- 使用JCEKS等密钥库存储敏感信息
- 实现密钥轮换机制
请求验证:
- 验证所有输入参数
- 对用户输入进行XSS过滤
- 限制请求体大小(建议不超过5MB)
四、完整调用示例
public class Main {
public static void main(String[] args) {
// 1. 加载配置
Properties prop = new Properties();
try (InputStream input = Main.class.getClassLoader()
.getResourceAsStream("config.properties")) {
prop.load(input);
} catch (IOException ex) {
System.err.println("无法加载配置文件");
return;
}
// 2. 初始化客户端
QianfanClient client = new QianfanClient(
prop.getProperty("qianfan.endpoint"),
prop.getProperty("qianfan.accessKeyId"),
prop.getProperty("qianfan.secretKey")
);
// 3. 构建请求
ChatRequest request = new ChatRequest();
request.setModel("ERNIE-Bot");
request.setTemperature(0.7);
String messages = "[{\"role\":\"user\",\"content\":\"你好,请介绍一下千帆平台\"}]";
request.setMessages(messages);
// 4. 发送请求并处理响应
try {
String result = client.chatWithRetry(request, 3);
ChatResponse response = ChatResponse.parse(result);
System.out.println("模型回复: " + response.getContent());
} catch (Exception e) {
System.err.println("调用失败: " + e.getMessage());
e.printStackTrace();
}
}
}
五、总结与展望
本文详细阐述了Java调用千帆大模型平台Chat API的完整实现方案,涵盖环境准备、请求签名、请求发送、响应解析等核心环节。通过实际代码示例展示了同步调用、异步调用、错误处理等关键场景的实现方法。
未来优化方向包括:
- 实现更完善的SDK封装,提供流式响应支持
- 添加Prometheus监控指标
- 支持gRPC等高性能传输协议
- 集成Spring Boot Starter简化使用
开发者可根据实际业务需求,基于本文提供的代码框架进行扩展和定制,快速构建稳定的AI对话应用。
发表评论
登录后可评论,请前往 登录 或 注册