整体思路是:
1创建ram用户,授权
2上传文件获取FileSession
3调用智能体对话,传入FileSession
接下来每个步骤的细节:
1官方不推荐使用超级管理员用户获得accessKeyId和accessKeySecret,所以登录超级管理员账号创建ram用户,给这个用户授权想用的权限即可
创建ram用户 可以使用官方概览这里有个快速开始,我这里只是想开发人员使用key,所以选择了“创建程序用户”
最重要的需要授权
点击上个页面上的授权,搜素AliyunBailianFullAccess或AliyunBailianControlFullAccess。然后第二步授予workspace权限授予工作空间权限!这个不要忘否则调用的时候会报“401”
2上传文件主要有三个步骤,官方文档快速开始里面有在线调试和sdk开始。看官网就行。
上传文档参数说明
api接口调用在线调试
注意这个上传文档可以使用oss,但是需要是公开的,于是我使用本地文档上传,通用写法。我使用的是java,传入ossId为文档id,也可以直接换成本地绝对路径,就不需要从ossId转localFilePath了,其中的params 放入按照前面获取到的数据放入即可,如
` private static Map<String, String> params = new HashMap<>();
static {
params.put("accessKeyId", " ");
params.put("accessKeySecret", " ");
params.put("workspaceId", " ");
params.put("apiKey", "sk- ");
params.put("appId", " ");`
public String getFileSession(Long ossId) throws IOException {
String localFilePath = "";
if (null!=ossId) {
Path downloadedPath = null;
try {
downloadedPath = this.getTempFullFilePath(ossId);
if (!StrUtil.isBlankIfStr(downloadedPath)) {
String strPath = downloadedPath.toAbsolutePath().toString();
localFilePath = strPath;
} else {
return null;
}
//上传bailian文件
init(localFilePath);
/* 1.上传文件 */
/** 1.1.申请文档上传租约 **/
StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
.accessKeyId(params.get("accessKeyId"))
.accessKeySecret(params.get("accessKeySecret"))
.build());
AsyncClient client = AsyncClient.builder()
.credentialsProvider(provider)
configuration rewrite, can set Endpoint, Http request parameters, etc.
.overrideConfiguration(
ClientOverrideConfiguration.create()
.setEndpointOverride("bailian.cn-beijing.aliyuncs.com")
)
.build();
ApplyFileUploadLeaseRequest applyFileUploadLeaseRequest = ApplyFileUploadLeaseRequest.builder()
.categoryType(params.get("CategoryType"))
.categoryId(params.get("CategoryId") )
.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 = new URL(param.getUrl());
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("PUT");
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));
// 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)
.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();
return fileId;
} catch (Exception e) {
log.error("处理ossId为 {} 的文件失败: {}",ossId, e.getMessage(), e);
} finally {
Path tempDir = null;
if (null != downloadedPath) {
tempDir = downloadedPath.getParent().toAbsolutePath();
}
if (null != tempDir) {
// 递归删除目录(包括所有子目录和文件)
Files.walkFileTree(tempDir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
// 删除文件
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
// 删除空目录
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
log.info("临时目录已删除!");
}
}
return localFilePath;
}
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();
}
3调用智能体
ApplicationParam aiParam = ApplicationParam.builder()
.apiKey("sk- ")
.appId(" ")
// 增量输出,即后续输出内容不包含已输出的内容。实时地逐个读取这些片段以获得完整的结果。
.incrementalOutput(true)
.prompt(chatModelDto.getMessage())
//可传入历史记录
// .messages()
.ragOptions(RagOptions.builder()
.sessionFileIds(fileSessionList)
.build())
.build();
Application application = new Application();
ApplicationResult result = application.call(aiParam);
String text = result.getOutput().getText();
return text;
//流式输出 createResult可忽略,返回Flux<String>
// Application application = new Application();
// Flowable<ApplicationResult> result = application.streamCall(aiParam);
// Flux<Result> resultFlux = Flux.from(result)
// .map(applicationResult -> {
// String response = applicationResult.getOutput().getText();
// return createResult(response);
// });
// return resultFlux;