直接用于拍照答题不大理想, 可能适用其他用途, 更好的方案: 阿里云百炼(1) : 阿里云百炼应用问答_回答图片问题_方案2_提取题目再提问-CSDN博客
1.实现代码
package cn.nordrassil.ly.test.拍照答题;
import com.alibaba.dashscope.app.Application;
import com.alibaba.dashscope.app.ApplicationParam;
import com.alibaba.dashscope.app.ApplicationResult;
import com.alibaba.dashscope.app.RagOptions;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.sdk.service.bailian20231229.AsyncClient;
import com.aliyun.sdk.service.bailian20231229.models.*;
import com.google.gson.Gson;
import darabonba.core.client.ClientOverrideConfiguration;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
public class 阿里云百炼应用问答_回答图片问题_方案1_提问时上传图片文件 {
private static Map<String, String> params = new HashMap<>();
static {
params.put("accessKeyId", "");
params.put("accessKeySecret", "");
params.put("workspaceId", "");
params.put("apiKey", "");
params.put("appId", "");
params.put("filePath", "C:\\Users\\admin\\Pictures\\1.png");
}
public static void main(String[] args) throws Exception {
init();
/* 1.上传文件 */
/** 1.1.申请文档上传租约 **/
StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
// Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
.accessKeyId(params.get("accessKeyId"))
.accessKeySecret(params.get("accessKeySecret"))
//.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
.build());
// Configure the Client
AsyncClient client = AsyncClient.builder()
.region("cn-beijing") // Region ID
//.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
.credentialsProvider(provider)
//.serviceConfiguration(Configuration.create()) // Service-level configuration
// Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
.overrideConfiguration(
ClientOverrideConfiguration.create()
// Endpoint 请参考 https://api.aliyun.com/product/bailian
.setEndpointOverride("bailian.cn-beijing.aliyuncs.com")
//.setConnectTimeout(Duration.ofSeconds(30))
)
.build();
// Parameter settings for API request
ApplyFileUploadLeaseRequest applyFileUploadLeaseRequest = ApplyFileUploadLeaseRequest.builder()
.categoryType("SESSION_FILE")
.categoryId("default")
.fileName(params.get("fileName"))
.md5(params.get("fileMd5"))
.sizeInBytes(params.get("fileLength"))
.workspaceId(params.get("workspaceId"))
// Request-level configuration rewrite, can set Http request parameters, etc.
// .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
.build();
// Asynchronously get the return value of the API request
CompletableFuture<ApplyFileUploadLeaseResponse> response = client.applyFileUploadLease(applyFileUploadLeaseRequest);
// Synchronously get the return value of the API request
ApplyFileUploadLeaseResponse resp = response.get();
System.out.println("- 申请文档上传租约结果: " + new Gson().toJson(resp));
ApplyFileUploadLeaseResponseBody.Param param = resp.getBody().getData().getParam();
/** 1.2.上传文档至阿里云百炼的临时存储 **/
HttpURLConnection connection = null;
try {
// 创建URL对象
URL url = new URL(param.getUrl());
connection = (HttpURLConnection) url.openConnection();
// 设置请求方法用于文档上传,需与您在上一步中调用ApplyFileUploadLease接口实际返回的Data.Param中Method字段的值一致
connection.setRequestMethod("PUT");
// 允许向connection输出,因为这个连接是用于上传文档的
connection.setDoOutput(true);
JSONObject headers = JSONObject.parseObject(JSONObject.toJSONString(param.getHeaders()));
connection.setRequestProperty("X-bailian-extra", headers.getString("X-bailian-extra"));
connection.setRequestProperty("Content-Type", headers.getString("Content-Type"));
// 读取文档并通过连接上传
try (DataOutputStream outStream = new DataOutputStream(connection.getOutputStream());
FileInputStream fileInputStream = new FileInputStream(params.get("filePath"))) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
outStream.flush();
}
// 检查响应
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// 文档上传成功处理
System.out.println("- 上传文件成功");
} else {
// 文档上传失败处理
System.out.println("Failed to upload the file. ResponseCode: " + responseCode);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
/** 1.3.将文档添加至阿里云百炼的数据管理 **/
AddFileRequest addFileRequest = AddFileRequest.builder()
.categoryType("SESSION_FILE")
.leaseId(resp.getBody().getData().getFileUploadLeaseId())
.parser("DASHSCOPE_DOCMIND")
.categoryId("default")
.workspaceId(params.get("workspaceId"))
// Request-level configuration rewrite, can set Http request parameters, etc.
// .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
.build();
// Asynchronously get the return value of the API request
CompletableFuture<AddFileResponse> addFileresponse = client.addFile(addFileRequest);
// Synchronously get the return value of the API request
AddFileResponse addFileresp = addFileresponse.get();
System.out.println("- 将文档添加至阿里云百炼的数据管理结果: " + new Gson().toJson(addFileresp));
// Asynchronous processing of return values
/*response.thenAccept(resp -> {
System.out.println(new Gson().toJson(resp));
}).exceptionally(throwable -> { // Handling exceptions
System.out.println(throwable.getMessage());
return null;
});*/
// Finally, close the client
String fileId = addFileresp.getBody().getData().getFileId();
System.out.println("- fileId: " + fileId);
/** 1.4.查看文件是否解析 **/
DescribeFileRequest describeFileRequest = DescribeFileRequest.builder()
.workspaceId(params.get("workspaceId"))
.fileId(fileId)
// Request-level configuration rewrite, can set Http request parameters, etc.
// .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
.build();
// Asynchronously get the return value of the API request
String status = null;
while (status == null || !status.equals("FILE_IS_READY")) {
CompletableFuture<DescribeFileResponse> describeResponse = client.describeFile(describeFileRequest);
// Synchronously get the return value of the API request
DescribeFileResponse describeResp = describeResponse.get();
if (describeResp.getBody() == null) {
continue;
}
if (describeResp.getBody().getData() == null) {
continue;
}
status = describeResp.getBody().getData().getStatus();
if (status == null) {
continue;
}
System.out.println("- fileId状态: " + status);
Thread.sleep(500);
}
// 关闭
client.close();
/* 2.调用百炼应用 */
ApplicationParam aiParam = ApplicationParam.builder()
// 若没有配置环境变量,可用百炼API Key将下行替换为:.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中,以减少API Key泄露风险。
.apiKey(params.get("apiKey"))
.appId(params.get("appId")) // 替换为实际的应用ID
.prompt("请直接输出图片问题的答案, 无需多言")
.ragOptions(RagOptions.builder()
.sessionFileIds(Arrays.asList(fileId)) // 替换为实际指定的临时文件 ID,逗号隔开多个
.build())
.build();
Application application = new Application();
ApplicationResult result = application.call(aiParam);
System.out.printf("%s\n",
result.getOutput().getText());// 处理只输出文本text
System.out.println();
}
private static void init() throws Exception {
String filePath = params.get("filePath");
File file = new File(filePath);
if (!file.exists()) {
System.err.println("文件[" + filePath + "]不存在");
System.exit(1);
}
params.put("fileMd5", getMD5Checksum(file));
params.put("fileLength", String.valueOf(file.length()));
params.put("fileName", file.getName());
}
public static String getMD5Checksum(File file) throws IOException, NoSuchAlgorithmException {
FileInputStream fis = new FileInputStream(file);
MessageDigest digest = MessageDigest.getInstance("MD5");
FileChannel fileChannel = fis.getChannel();
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
// 使用MappedByteBuffer可以更高效地读取大文件
digest.update(buffer);
byte[] hashBytes = digest.digest();
// 将字节数组转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : hashBytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
fileChannel.close();
fis.close();
return hexString.toString();
}
}
2.依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dashscope-sdk-java</artifactId>
<version>2.20.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibabacloud-bailian20231229</artifactId>
<version>2.0.6</version>
</dependency>
3.百炼应用提示词
# 角色
你是一位知识渊博的专家,能够根据用户的需求提供准确、详细且有帮助的答案。你具备广泛的知识背景,并能灵活运用这些知识来解答各种问题。
## 技能
### 技能 1: 知识检索与应用
- 根据用户的问题,从知识库中检索相关信息。
### 技能 2: 问题解答
- 理解用户的问题意图和需求。
- 提供详细、准确的答案,解释关键概念和逻辑。
## 限制
- 回答问题时必须基于现有的知识库
- 知识库中没有的回复"知识库无相关信息"
# 知识库
请记住以下材料,他们可能对回答问题有帮助。
${documents}
4.测试
4.1.创建知识库导入文档
点击[中国人民解放军海军福建舰_百度百科]保存为pdf导入知识库