Spring Boot项目 实现百度文心一言流式输出及 Java 流式输出常用方法
引言
在当今的软件开发领域,流式输出技术扮演着重要的角色。它能够让数据逐个元素或按块输出,而非一次性输出全部数据,这不仅降低了内存占用,还能使数据在生成时就开始传输,显著提升了效率。一方面,百度文心一言作为强大的大语言模型,其流式输出功能可在 Java 的 Spring Boot 项目中实现,为用户带来更好的交互体验;另一方面,Java 本身也提供了多种实现流式输出的常用方法,适用于不同的应用场景。本文将详细介绍如何在 Spring Boot 项目中实现百度文心一言流式输出,同时深入探讨 Java 中实现流式输出的常用方法。
利用 Java 和 Spring Boot 实现百度文心一言流式输出
环境准备
在开始之前,你需要确保已经安装了以下环境:
- Java 开发环境:建议使用 Java 8 及以上版本。
- Maven:用于管理项目依赖。
- Spring Boot:创建 Spring Boot 项目,你可以使用 Spring Initializr(https://start.spring.io/)来快速搭建项目结构。
引入依赖
在 pom.xml 文件中添加必要的依赖:
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
dependency>
dependency>
groupId>com.squareup.okhttp3groupId>
artifactId>okhttpartifactId>
version>4.9.3version>
dependency>
dependency>
groupId>com.fasterxml.jackson.coregroupId>
artifactId>jackson-databindartifactId>
dependency>
dependencies>
获取百度文心一言 API 密钥
你需要在百度云平台上创建一个文心一言应用,获取 API Key 和 Secret Key,这两个密钥将用于后续的身份验证。
实现流式输出逻辑
1. 创建配置类
创建一个配置类,用于存储 API 相关的信息:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "wenxin")
public class WenxinConfig {
private String apiKey;
private String secretKey;
private String apiUrl;
// Getters and Setters
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getApiUrl() {
return apiUrl;
}
public void setApiUrl(String apiUrl) {
this.apiUrl = apiUrl;
}
}
在 application.properties 中配置 API 信息:
wenxin.apiKey=your_api_key
wenxin.secretKey=your_secret_key
wenxin.apiUrl=https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_stream
2. 创建获取访问令牌的工具类
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class TokenUtil {
@Autowired
private WenxinConfig wenxinConfig;
public String getAccessToken() throws IOException {
String apiKey = wenxinConfig.getApiKey();
String secretKey = wenxinConfig.getSecretKey();
String url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.get()
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful() && response.body() != null) {
String responseBody = response.body().string();
// 解析 JSON 数据获取 access_token
int startIndex = responseBody.indexOf(""access_token":"") + 15;
int endIndex = responseBody.indexOf(""", startIndex);
return responseBody.substring(startIndex, endIndex);
}
}
return null;
}
}
3. 创建流式输出服务类
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
@Service
public class WenxinStreamService {
@Autowired
private WenxinConfig wenxinConfig;
@Autowired
private TokenUtil tokenUtil;
public void streamOutput(String prompt, Callback callback) throws IOException {
String accessToken = tokenUtil.getAccessToken();
String apiUrl = wenxinConfig.getApiUrl() + "?access_token=" + accessToken;
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.get("application/json; charset=utf-8");
String json = "{"messages": [{"role": "user", "content": "" + prompt + ""}]}";
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(apiUrl)
.post(body)
.build();
client.newCall(request).enqueue(callback);
}
}
4. 创建控制器类
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RestController
public class WenxinController {
@Autowired
private WenxinStreamService wenxinStreamService;
@GetMapping("/stream")
public void stream(@RequestParam String prompt) throws IOException {
wenxinStreamService.streamOutput(prompt, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful() && response.body() != null) {
try (ResponseBody responseBody = response.body()) {
BufferedSource source = responseBody.source();
String line;
while ((line = source.readUtf8Line()) != null) {
if (!line.isEmpty()) {
// 处理每一行输出
System.out.println(line);
}
}
}
}
}
});
}
}
测试
启动 Spring Boot 项目,访问 http://localhost:8080/stream?prompt=你好,你将在控制台看到文心一言的流式输出结果。
Java 中实现流式输出的常用方法
1. 使用 java.io 包中的流
java.io 包提供了基础的输入输出流,你可以用它实现流式输出。
示例:将数据逐行写入文件
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class StreamOutputExample {
public static void main(String[] args) {
try (PrintWriter writer = new PrintWriter(new FileWriter("output.txt"))) {
for (int i = 0; i 10; i++) {
// 逐行输出数据
writer.println("Line " + i);
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
解释:
- 借助
PrintWriter和FileWriter把数据写入文件。 - 利用
println方法逐行输出数据,每输出一行就调用flush方法将缓冲区的数据刷新到文件中。
2. 使用 java.nio 包中的通道和缓冲区
java.nio 包提供了更高效的 I/O 操作,你可以用通道和缓冲区实现流式输出。
示例:将数据写入文件
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class NioStreamOutputExample {
public static void main(String[] args) {
try (FileOutputStream fos = new FileOutputStream("output_nio.txt");
FileChannel channel = fos.getChannel()) {
for (int i = 0; i 10; i++) {
String line = "Line " + i + "n";
ByteBuffer buffer = ByteBuffer.wrap(line.getBytes());
while (buffer.hasRemaining()) {
channel.write(buffer);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
解释:
- 运用
FileOutputStream获取FileChannel。 - 把数据写入
ByteBuffer,再通过FileChannel将缓冲区的数据写入文件。
3. 使用 Java 8 的 Stream API
Java 8 引入了 Stream API,能够对集合进行流式处理,同时也可用于输出。
示例:将集合元素逐行输出到控制台
import java.util.Arrays;
import java.util.List;
public class StreamApiOutputExample {
public static void main(String[] args) {
ListString> lines = Arrays.asList("Line 1", "Line 2", "Line 3");
lines.stream()
.forEach(System.out::println);
}
}
解释:
- 把集合转换为流,再使用
forEach方法逐个输出元素。
4. 使用 Servlet 实现流式输出到客户端
在 Web 应用里,你可以用 Servlet 实现流式输出,将数据逐步发送给客户端。
示例:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/stream")
public class StreamServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
for (int i = 0; i 10; i++) {
out.println("Line " + i);
out.flush();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
out.close();
}
}
解释:
- 在 Servlet 里,通过
HttpServletResponse获取PrintWriter。 - 逐行输出数据,每次输出后调用
flush方法将数据发送给客户端。
总结
通过以上内容,我们详细介绍了如何在 Java 的 Spring Boot 项目中实现百度文心一言的流式输出,以及 Java 中实现流式输出的常用方法。流式输出技术在不同场景下都能发挥重要作用,无论是与大语言模型交互还是进行文件操作、Web 数据传输等。希望本文能帮助你更好地理解和运用流式输出技术,让你的 Java 程序更加高效和灵活。如果你在实践过程中遇到任何问题,欢迎留言讨论。
文章来源于互联网:Spring Boot项目 实现百度文心一言流式输出及 Java 流式输出常用方法
相关推荐: 文心一言、讯飞星火、GPT、通义千问等线上API调用示例
大模型相关目录 大模型,包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容从0起步,扬帆起航。 大模型应用向开发路径及一点个人思考 大模型应用开发实用开源项目汇总 大模型问答项目问答性能…
5bei.cn大模型教程网










