This topic describes best practices for getting started with the Smart Proofread API and building business applications.
Prerequisites
Related APIs
- Submit a smart audit: SubmitSmartAudit
- Get a smart audit result: GetSmartAuditResult
- Export an audit report: ExportAuditContentResult
- Submit an AuditNote: SubmitAuditNote
- Get the parsing status of an AuditNote: GetAuditNoteProcessingStatus
- Confirm and post-process an AuditNote: ConfirmAndPostProcessAuditNote
- Get the semantic indexing status: GetAuditNotePostProcessingStatus
Quick start
Maven dependency
To find and use the latest version, visit the Alibaba Cloud OpenAPI Portal.Copy
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>alibabacloud-aimiaobi20230801</artifactId>
<version><latest_version></version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>
Configure environment variables
Parameter | Description |
ALIBABA_CLOUD_ACCESS_KEY_ID | |
ALIBABA_CLOUD_ACCESS_KEY_SECRET | |
WORKSPACE_ID | |
ENDPOINT | The endpoint for the Intelligent Proofreading Service: aimiaobi.cn-beijing.aliyuncs.com |
Copy the utility class
Copy AuditUtils into your project.Run the main class
- Basic content audit: ContentAuditBasicExample
- Image audit: ImageAuditExample
- Fact audit: FactAuditExample
- Rule library preparation: RuleLibraryPreparationExample
- Rule-based content audit: RuleBasedContentAuditExample
1. General tools
To run the following examples, copy this utility class to your project.
Copy
package org.example.audit;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.sdk.gateway.pop.Configuration;
import com.aliyun.sdk.gateway.pop.auth.SignatureVersion;
import com.aliyun.sdk.service.aimiaobi20230801.AsyncClient;
import com.aliyun.sdk.service.aimiaobi20230801.models.ExportAuditContentResultRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.GenerateUploadConfigRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.GenerateUploadConfigResponse;
import com.aliyun.sdk.service.aimiaobi20230801.models.GetSmartAuditResultRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.GetSmartAuditResultResponseBody;
import com.aliyun.sdk.service.aimiaobi20230801.models.GetSmartAuditResultResponseBody.ErrorItemDetails;
import darabonba.core.client.ClientOverrideConfiguration;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.entity.mime.ContentBody;
import org.apache.hc.client5.http.entity.mime.StringBody;
import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
/**
* A utility class for content audit.
*/
public class AuditUtils {
/**
* The maximum number of polling attempts. With a 5-second wait between each attempt, the total maximum wait time is approximately 25 minutes.
*/
private static final int MAX_POLLING_COUNT = 300;
/**
* Polls for the audit result of a task.
*
* @param client The async client.
* @param workspaceId The workspace ID.
* @param taskId The task ID.
* @throws InterruptedException if the thread is interrupted.
* @throws ExecutionException if the execution fails.
*/
public static void pollAuditResult(AsyncClient client, String workspaceId, String taskId)
throws InterruptedException, ExecutionException {
GetSmartAuditResultResponseBody.Data finalResponse = null;
boolean success = false;
for (int i = 0; i < MAX_POLLING_COUNT; i++) {
// Poll for the task status.
GetSmartAuditResultResponseBody body = client
.getSmartAuditResult(
GetSmartAuditResultRequest.builder().taskId(taskId).workspaceId(workspaceId)
.build()).get().getBody();
List<ErrorItemDetails> errorItemDetails = body.getData().getErrorItemDetails();
System.out.println("Polling task. Number of errors detected: " + (errorItemDetails == null ? 0 : errorItemDetails.size()));
if (!body.getSuccess()) {
System.out.println("Request failed. Please check the response.");
}
finalResponse = body.getData();
String status = finalResponse.getStatus();
if ("RUNNING".equals(status) || "PENDING".equals(status)) {
System.out.printf("Task is running. TaskId: %s, TaskStatus: %s (%d/%d)\n", taskId, status, i + 1,
MAX_POLLING_COUNT);
Thread.sleep(5000);
} else if ("FAILED".equals(status)) {
System.out.printf("Task failed. TaskId: %s, TaskStatus: %s\n", taskId, status);
break;
} else {
System.out.printf("Task completed successfully. TaskId: %s, TaskStatus: %s\n", taskId, status);
success = true;
break;
}
}
if (!success) {
String status = finalResponse.getStatus();
if ("RUNNING".equals(status) || "PENDING".equals(status)) {
throw new RuntimeException("Polling timed out. Maximum polling attempts reached: " + MAX_POLLING_COUNT + ". Task status: " + status);
}
}
for (GetSmartAuditResultResponseBody.ErrorItemDetails errorItemDetail : finalResponse.getErrorItemDetails()) {
System.out.println("Major Code: " + errorItemDetail.getMajorCode());
System.out.println("Major Code Description: " + errorItemDetail.getMajorCodeDesc());
System.out.println("Subclass Code: " + errorItemDetail.getSubClassCode());
System.out.println("Subclass Description: " + errorItemDetail.getSubClassDesc());
System.out.println("Error Level: " + errorItemDetail.getErrorLevel());
System.out.println("Context: " + errorItemDetail.getContext());
System.out.println("Error Word: " + errorItemDetail.getErrorWord());
System.out.println("Context Offset: " + errorItemDetail.getContextOffset());
System.out.println("Offset: " + errorItemDetail.getOffset());
System.out.println("Reason: " + errorItemDetail.getReason());
System.out.println("Suggested Word: " + errorItemDetail.getRightWord());
System.out.println("----------------------------\n");
}
}
/**
* Downloads a file to the system's temporary directory.
*
* <p><b>Warning:</b> This method saves the file to the system's temporary directory ({@code java.io.tmpdir}). The operating system may automatically clear this directory during restarts, disk cleanup, or when its retention period expires. To prevent data loss, process the file immediately after download, such as by moving it to a permanent location or uploading it to cloud storage.</p>
*
* @param url The URL to download the file from.
* @param fileName The name of the file.
* @return The absolute path of the downloaded file.
* @throws Exception if a download error occurs.
*/
public static String downloadResultFile(String url, String fileName) throws Exception {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {
httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
response = httpClient.execute(httpGet);
// Create the temporary directory.
String tmpDir = System.getProperty("java.io.tmpdir");
File tempDir = new File(tmpDir);
if (!tempDir.exists()) {
tempDir.mkdirs();
}
// Create a file in the temporary directory.
File outputFile = new File(tempDir, fileName);
// Get the response entity and write it to the file.
HttpEntity entity = response.getEntity();
if (entity != null) {
inputStream = entity.getContent();
outputStream = new FileOutputStream(outputFile);
byte[] buffer = new byte[4096];
int bytesRead;
// Read data and write it to the file.
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
String absolutePath = outputFile.getAbsolutePath();
System.out.println("File successfully downloaded to temporary directory: " + absolutePath);
System.out.println("Warning: Files in the temporary directory may be cleared automatically. Process them promptly.");
return absolutePath;
} else {
throw new RuntimeException(
"The response entity is null. Please check the response."
);
}
} catch (IOException e) {
System.err.println("An error occurred while downloading the file: " + e.getMessage());
throw e;
} finally {
// Ensure resources are released.
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
System.err.println("An error occurred while closing the file output stream: " + e.getMessage());
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
System.err.println("An error occurred while closing the input stream: " + e.getMessage());
}
}
if (response != null) {
try {
response.close();
} catch (IOException e) {
System.err.println("An error occurred while closing the HTTP response: " + e.getMessage());
}
}
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
System.err.println("An error occurred while closing the HTTP client: " + e.getMessage());
}
}
}
}
/**
* Exports the audit result.
*
* <p>The file is saved to the system's temporary directory. Process or clean up the file based on your business requirements.</p>
*
* @param client The async client.
* @param workspaceId The workspace ID.
* @param taskId The task ID.
* @throws Exception if an error occurs during processing.
*/
public static void exportAuditResults(AsyncClient client, String workspaceId, String taskId)
throws Exception {
// Export as a .docx file.
String downloadUrl = client.exportAuditContentResult(
ExportAuditContentResultRequest.builder().taskId(taskId).workspaceId(workspaceId).build()).get().getBody()
.getData();
System.out.println("Exported result URL (valid for 1 hour): " + downloadUrl);
// Download the audit result file to the system's temporary directory.
downloadResultFile(downloadUrl, "audit_result.docx");
}
/**
* Creates an async client.
*
* @param accessKeyId The access key ID.
* @param accessKeySecret The access key secret.
* @param endpoint The endpoint.
* @return A new async client instance.
*/
public static AsyncClient createAsyncClient(String accessKeyId, String accessKeySecret, String endpoint) {
return AsyncClient.builder().credentialsProvider(
StaticCredentialProvider.create(Credential.builder().accessKeyId(accessKeyId)
.accessKeySecret(accessKeySecret).build())
).serviceConfiguration(Configuration.create().setSignatureVersion(SignatureVersion.V3)).overrideConfiguration(
ClientOverrideConfiguration.create().setProtocol("HTTPS").setEndpointOverride(endpoint)
).build();
}
/**
* Uploads a file to the audit service.
*
* @param client The async client.
* @param workspaceId The workspace ID.
* @param filePath The path to the file.
* @return The file key.
* @throws ExecutionException if the execution fails.
* @throws InterruptedException if the thread is interrupted.
* @throws IOException if an I/O error occurs.
*/
public static String uploadFile(AsyncClient client, String workspaceId, String filePath)
throws ExecutionException, InterruptedException, IOException {
// Get the file name.
String fileName = new File(filePath).getName();
// Generate the upload configuration.
GenerateUploadConfigRequest uploadConfigRequest = GenerateUploadConfigRequest.builder()
.workspaceId(workspaceId).parentDir("temp").fileName(fileName).build();
GenerateUploadConfigResponse uploadConfig = client.generateUploadConfig(
uploadConfigRequest).get();
// Upload the file and return the file key.
return uploadFileToStorage(uploadConfig, filePath);
}
/**
* Uploads a file to the cloud storage location specified by the audit service.
*
* @param uploadConfig The upload configuration response.
* @param filePath The path to the file.
* @return The file key.
* @throws IOException if an I/O error occurs.
*/
private static String uploadFileToStorage(GenerateUploadConfigResponse uploadConfig, String filePath)
throws IOException {
String fileKey = uploadConfig.getBody().getData().getFileKey();
Map<String, ?> formDatas = uploadConfig.getBody().getData().getFormDatas();
String postUrl = uploadConfig.getBody().getData().getPostUrl();
File file = new File(filePath);
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(postUrl);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setContentType(
ContentType.MULTIPART_FORM_DATA
);
// Add form fields.
for (Map.Entry<String, ?> entry : formDatas.entrySet()) {
ContentBody stringBody = new StringBody(String.valueOf(entry.getValue()), ContentType.TEXT_PLAIN);
builder.addPart(entry.getKey(), stringBody);
}
// Add the file to be uploaded.
ContentBody fileBody = new FileBody(file, ContentType.APPLICATION_OCTET_STREAM, file.getName());
builder.addPart("file", fileBody);
// Build and set the multipart request entity.
HttpEntity multipartEntity = builder.build();
httpPost.setEntity(multipartEntity);
// Execute the request.
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
int responseCode = response.getCode();
System.out.println("Response Code: " + responseCode);
HttpEntity entity = response.getEntity();
String responseBody = entity != null ? EntityUtils.toString(entity, StandardCharsets.UTF_8) : "";
System.out.println("Response: " + responseBody);
if (responseCode >= 300) {
throw new RuntimeException("Upload file failed, response: " + responseBody);
}
return fileKey;
} catch (org.apache.hc.core5.http.ParseException e) {
throw new IOException("Failed to parse response", e);
}
}
}
}
2. Content review
This example shows how to perform content moderation using basic moderation dimensions:- Get the basic moderation dimensions for articles.
- Submit a content moderation task.
- Poll for the moderation result.
- Export the moderation report.
Copy
package org.example.audit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import com.aliyun.sdk.service.aimiaobi20230801.AsyncClient;
import com.aliyun.sdk.service.aimiaobi20230801.models.ListAuditContentErrorTypesRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.ListAuditContentErrorTypesResponseBody;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditResponse;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditResponseBody;
/**
* Basic Content Moderation Example
*
* This example demonstrates how to use basic audit dimensions for content moderation:
* 1. Get available audit dimension configurations.
* 2. Submit a content moderation task.
* 3. Poll for moderation results.
* 4. Export the audit report.
*/
public class ContentAuditBasicExample {
private static final String ALIBABA_CLOUD_ACCESS_KEY_ID = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
private static final String ALIBABA_CLOUD_ACCESS_KEY_SECRET = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
private static final String WORKSPACE_ID = System.getenv("WORKSPACE_ID");
private static final String ENDPOINT = System.getenv().getOrDefault("ENDPOINT", "aimiaobi.cn-beijing.aliyuncs.com");
public static void main(String[] args) throws Exception {
AsyncClient client = AuditUtils.createAsyncClient(ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, ENDPOINT);
// Get basic audit dimension configurations.
List<String> subCodes = listAuditContentErrorTypes(client);
// Submit a content moderation task.
String taskId = submitAuditTask(client, subCodes);
// Poll for the audit result.
AuditUtils.pollAuditResult(client, WORKSPACE_ID, taskId);
// Export the audit results.
AuditUtils.exportAuditResults(client, WORKSPACE_ID, taskId);
}
/**
* Submits a content moderation task.
*
* @param client The async client.
* @param subCodes A list of audit dimension codes.
* @return The task ID.
* @throws InterruptedException If the thread is interrupted.
* @throws ExecutionException If the task execution fails.
*/
private static String submitAuditTask(AsyncClient client, List<String> subCodes)
throws InterruptedException, ExecutionException {
// Sample text: Contains test content with various types of issues to be audited.
// Please replace this with the actual content you want to audit.
String contentToAudit =
"\nThis is an article for auditing that contains the following types of issues:\nBasic Quality\n\nPhonetic/Visual Character Errors\nAre '我在家' (wǒ zài jiā - I am at home) and '我再家' (wǒ zài jiā - a homophone error) both correct?\nIn the future, people from Earth will live on other planets. In the '末来' (mò lái - a typo for '未来' meaning 'future'), people from Earth will live on Mars.\nYesterday's weather was clear, but today's weather is not '睛朗' (jīng lǎng - a typo for '晴朗' meaning 'clear') at all; it's a misty, rainy day.\n"
+ " \nPunctuation Errors\nThe weather is nice today we are going to the park after the park we went to the riverside after arriving at the riverside we started fishing there.\nShe is a doctor; He is a "
+ "teacher\nHe has two hobbies—reading, and sports. (Using a Chinese em dash '——')\nThe cat; the dog, and the bird\nHe said: 'Hello' (Using Chinese quotation marks '“你好”')\n\"He said, ’Hello’\"\n\"(This is a comment\" or \"This is a comment)\" (Mismatched parentheses with quotes)\nThe price is $99 (Using a full-width dollar sign '$')\nThis is a test。 (Using a Chinese period '。')\netc...\n\"'The Analects' is a classic\" is correct, \"'Hello "
+ "World'\" is incorrect (Using Chinese book title marks '《》')\nHello世界 (Mixing English and Chinese)\n\n'The Weather is Nice Today' (Using Chinese book title marks '《》')\nErrors with '的', '地', '得'\nI run '的' (de) fast, you know? (Incorrect 'de' character for an adverb)\nHe runs fast. (Grammatically incomplete in Chinese: '他跑快')\nAre you going to study '认真的' (rèn zhēn de - adverbial form)? (Incorrect 'de' character for a verb complement)\nInappropriate Wording/Grammar Errors\nHe improved his ability. (Awkward phrasing in Chinese: '他提高了能力')\n \nName Errors\n "
+ "\nThe 'From the Hundred-Herb Garden to the Three-Flavors Study' written by '鲁讯' (Lǔ Xùn - a typo for the famous author Lu Xun '鲁迅') is wonderful.\n \nPolitical Errors\nTaiwan is an independent country. (Politically sensitive statement)\nPlace Name Errors\nShenzhen City, Guangdong Province, became prosperous only after the reform and opening up. (Characters for Shenzhen are reversed: '圳深' instead of '深圳')\n "
+ "\nCitation Errors\nSoftware programming is a worthwhile thing to do. (Awkward phrasing: '软件编程序是一个值得做的事')\nProper Noun / Terminology Errors\n'Blockchain' (block chain) (Space in the English term)\n \n \nIncorrect Capitalization\nHe likes to use google to search for answers. (Lowercase 'g')\nNumber Errors\n1—3 days"
+ " vs 2-5 days (Different dash types)\n \n \nNon-standard Units of Measurement\n \nThis small yard is quite large, about 100m2, and is planted with various flowers and trees. (m2 instead of m²)\n \nTraditional Chinese Characters\nHis '體' (tǐ - traditional character for 'body') physique is very strong.\n "
+ "\nContent Repetition\nThis book is very excellent, the content is extremely outstanding, and the language is very brilliant. (Redundant praise)\n \nThis product is a free gift. (Redundant: 'free' and 'gift')\nFor lunch today, I ate rice, rice.\nPolitical Errors\n[Name of a sensitive person] is a good comrade.\n "
+ "\nSecurity and Compliance\nThe AK47 is a good weapon.\n'New tea' has arrived, available for appointments. (Euphemism for prostitution)\nOur Tazhai village got rich from heroin.\nNot having children makes you a degenerate.\nKris Wu's 'Big Bowl Thick Noodle' sounds really terrible. (Insulting a public figure)\n "
+ "\nLegal Errors\nDriving against traffic on a main urban road will result in a deduction of 1 point and a fine of less than 2000 yuan. (Incorrect legal information)\n \n \nProfessional Knowledge\nOur product is the best in the world. (Hyperbole)\n\n";
SubmitSmartAuditRequest.Builder builder = SubmitSmartAuditRequest.builder().workspaceId(WORKSPACE_ID);
builder.subCodes(subCodes);
builder.text(contentToAudit);
SubmitSmartAuditResponse auditResponse = client.submitSmartAudit(builder.build()).get();
SubmitSmartAuditResponseBody.Data responseData = auditResponse.getBody().getData();
String taskId = responseData.getTaskId();
System.out.println(
"Successfully submitted the audit task. Task ID: " + taskId + ", Request ID: " + auditResponse.getBody().getRequestId());
return taskId;
}
/**
* Gets the list of basic article audit dimensions.
*
* <p>This method retrieves the four major categories of audit dimensions required for basic article auditing:</p>
* <ul>
* <li><strong>Content Accuracy (ContentAccuracy)</strong>: Phonetic/visual character errors, punctuation errors, errors in using Chinese particles "de", inappropriate wording/grammar errors, name errors, place name errors, citation errors, and proper noun/terminology errors.</li>
* <li><strong>Formatting Issues (FormatError)</strong>: Incorrect capitalization, number errors, non-standard units of measurement, and traditional Chinese characters.</li>
* <li><strong>Content Structure Issues (StructureError)</strong>: Redundant text, repetitive fragments, logical contradictions, and unfilled placeholders.</li>
* <li><strong>Political Issues (politicalError)</strong>: Sensitive content and content orientation risks, name or sorting errors, errors in established expressions, non-standard organization names, errors in quoting important speeches, disgraced officials, mismatched names and titles, and incorrect job title descriptions.</li>
* </ul>
*
* <p><strong>Why choose these four major categories?</strong></p>
* <p>Based on best practices for basic article auditing, these four categories cover the core requirements:</p>
* <ul>
* <li>Content Accuracy: Ensures the content is correct and avoids factual errors.</li>
* <li>Formatting: Ensures the article format is standardized to improve readability.</li>
* <li>Content Structure: Checks the logical and structural integrity of the article.</li>
* <li>Political Correctness: Ensures the content complies with political norms and avoids sensitive issues.</li>
* </ul>
*
* <p>If you need to use other audit dimensions (such as security and compliance, legal errors, professional knowledge errors, fact checking, image audit, custom dictionary, or rule set audit),
* you can modify the {@code majorTypes} list or remove the filtering logic to get all dimensions.</p>
*
* <p>For a complete list of sub-audit codes, see
* <a href="https://help.aliyun.com/en/model-studio/api-aimiaobi-2023-08-01-submitsmartaudit#sub-audit-code-values">Sub-audit code values</a>.</p>
*
* @param client The async client.
* @return A list of basic article audit dimension codes.
* @throws InterruptedException If the thread is interrupted.
* @throws ExecutionException If the task execution fails.
*/
private static List<String> listAuditContentErrorTypes(AsyncClient client)
throws InterruptedException, ExecutionException {
List<ListAuditContentErrorTypesResponseBody.Data> data = client.listAuditContentErrorTypes(
ListAuditContentErrorTypesRequest.builder()
.workspaceId(WORKSPACE_ID)
.build()
).get().getBody().getData();
// The four core dimensions for basic article auditing.
// In practice, these four major categories are usually sufficient to cover the core requirements for basic article auditing.
List<String> majorTypes = Arrays.asList(
"ContentAccuracy", // Content Accuracy
"politicalError", // Political Errors
"StructureError", // Structural Errors
"FormatError" // Formatting Issues
);
List<String> subAuditCodes = new ArrayList<>();
// Iterate through all major dimensions to filter and collect the sub-audit codes required for basic auditing.
for (ListAuditContentErrorTypesResponseBody.Data item : data) {
System.out.println("Major dimension name: " + item.getMajorClassName());
System.out.println("Major dimension code: " + item.getMajorClassCode());
System.out.println("Sub-dimension list:");
List<ListAuditContentErrorTypesResponseBody.SubClasses> subClasses = item.getSubClasses();
for (ListAuditContentErrorTypesResponseBody.SubClasses subItem : subClasses) {
System.out.println(" Sub-dimension name: " + subItem.getClassName());
System.out.println(" Sub-dimension code: " + subItem.getClassCode());
}
System.out.println("----------------------------\n");
// Collect only the sub-audit codes for the four major categories of basic auditing.
if (majorTypes.contains(item.getMajorClassCode())) {
subAuditCodes.addAll(
item.getSubClasses().stream()
.map(ListAuditContentErrorTypesResponseBody.SubClasses::getClassCode)
.collect(Collectors.toList())
);
}
}
System.out.println("Obtained a total of " + subAuditCodes.size() + " basic sub-audit codes (from the four major categories).");
return subAuditCodes;
}
}
3. Image moderation
This example shows how to use theImageAudit feature for content moderation:
- Submit an
ImageAudittask (supports multiple images). - Poll for the audit result.
- Export the audit report.
ImageAudit to the subCodes parameter.
Copy
package org.example.audit;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import com.aliyun.sdk.service.aimiaobi20230801.AsyncClient;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditResponse;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditResponseBody;
/**
* Image audit example.
*
* <p>This example demonstrates how to use the image audit feature for content audit:</p>
* <ol>
* <li>Submit an image audit task (supports multiple images).</li>
* <li>Poll for the audit result.</li>
* <li>Export the audit report.</li>
* </ol>
*
* <p><strong>Note:</strong> To perform an image audit, you must specify <strong>ImageAudit</strong> in the {@code subCodes} parameter.</p>
*
* <p>API reference:</p>
* <ul>
* <li>Submit an audit task: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/SubmitSmartAudit">SubmitSmartAudit</a></li>
* <li>Query a smart audit result: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/GetSmartAuditResult">GetSmartAuditResult</a>
* </li>
* <li>Export an audit report:
* <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/ExportAuditContentResult">ExportAuditContentResult</a></li>
* </ul>
*/
public class ImageAuditExample {
private static final String ALIBABA_CLOUD_ACCESS_KEY_ID = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
private static final String ALIBABA_CLOUD_ACCESS_KEY_SECRET = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
/**
* The unique identifier of the workspace.
* To get your workspace ID, see <a href="https://help.aliyun.com/model-studio/use-workspace">Use Workspace</a>.
*/
private static final String WORKSPACE_ID = System.getenv("WORKSPACE_ID");
private static final String ENDPOINT = System.getenv().getOrDefault("ENDPOINT", "aimiaobi.cn-beijing.aliyuncs.com");
public static void main(String[] args) throws Exception {
AsyncClient client = AuditUtils.createAsyncClient(ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET,
ENDPOINT);
// Submit an image audit task.
String taskId = submitAuditTask(client);
// Poll for the audit result.
AuditUtils.pollAuditResult(client, WORKSPACE_ID, taskId);
// Export the audit results.
AuditUtils.exportAuditResults(client, WORKSPACE_ID, taskId);
}
/**
* Submits an image audit task.
*
* <p>This method demonstrates how to submit an image audit task. You can audit multiple images in a single request.</p>
*
* <p><strong>Note:</strong> An image URL can be one of the following:</p>
* <ul>
* <li>A publicly accessible HTTP or HTTPS link.</li>
* <li>Base64-encoded image data (format: data:image/png;base64,xxx).</li>
* </ul>
*
* <p><strong>Note:</strong> The image URLs in this example are for demonstration purposes only. Replace them with your own image URLs.
* If you use OSS, you must generate a signed URL. For more information, see the OSS documentation: <a href="https://help.aliyun.com/en/oss/developer-reference/download-using-a-presigned-url">Generate a signed URL</a>.</p>
*
* @param client The async client.
* @return The task ID.
* @throws InterruptedException If the thread is interrupted.
* @throws ExecutionException If the execution fails.
*/
private static String submitAuditTask(AsyncClient client) throws InterruptedException, ExecutionException {
SubmitSmartAuditRequest.Builder builder = SubmitSmartAuditRequest.builder().workspaceId(WORKSPACE_ID);
// Specify image audit as the task type.
// The service code for an image audit is ImageAudit.
builder.subCodes(Collections.singletonList("ImageAudit"));
// Replace the sample URLs with your own.
SubmitSmartAuditRequest.ImageUrlList.Builder image1 = SubmitSmartAuditRequest.ImageUrlList.builder()
.url("https://example.com/images/sample1.jpg"); // Replace with your own image URL.
// Image ID: A unique identifier that maps the image to its audit result for easier tracking. This ID should be unique within your business.
image1.id("image_001");
SubmitSmartAuditRequest.ImageUrlList.Builder image2 = SubmitSmartAuditRequest.ImageUrlList.builder()
.url("https://example.com/images/sample2.jpg"); // Replace with your own image URL.
image2.id("image_002");
// Set the image list.
builder.imageUrlList(Arrays.asList(image1.build(), image2.build()));
// Submit the audit task.
SubmitSmartAuditResponse auditResponse = client.submitSmartAudit(builder.build()).get();
SubmitSmartAuditResponseBody.Data responseData = auditResponse.getBody().getData();
String taskId = responseData.getTaskId();
System.out.println(
"Successfully submitted the image audit task. Task ID: " + taskId + ", Request ID: " + auditResponse.getBody().getRequestId());
return taskId;
}
}
4. Online fact-checking
This example shows how to perform content moderation using a factual audit:- Configure trusted sources (optional) to specify your trusted data sources.
- Submit a factual audit task.
- Poll for the audit result.
- Export the audit report.
subCodes parameter when submitting an audit task.
Trusted sources: Trusted sources are the foundation for fact-checking. The system retrieves information from the data sources you configure to verify the factuality of the content.
Function: Trusted sources serve as the reference for factuality assessments. The system prioritizes these sources when searching for information to validate the content.
Impact: The quality of the sources you configure directly affects fact-checking accuracy. We recommend using authoritative and reliable data sources.
Copy
package org.example.audit;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import com.aliyun.sdk.service.aimiaobi20230801.AsyncClient;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitFactAuditUrlRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitFactAuditUrlResponse;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditResponse;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditResponseBody;
/**
* Fact Audit Example
*
* <p>This example demonstrates how to use the fact audit feature for content moderation:</p>
* <ol>
* <li>Configure trusted sources (optional, used to specify trusted data sources)</li>
* <li>Submit a fact audit task</li>
* <li>Poll for audit results</li>
* <li>Export the audit report</li>
* </ol>
*
* <p><strong>Note:</strong> The codes for fact audit include:</p>
* <ul>
* <li><strong>CorrectFact</strong>: Fact Audit - Correct Item</li>
* <li><strong>WrongFactError</strong>: Fact Audit - Error Item</li>
* </ul>
* <p>When you submit an audit task, you need to add these codes to the {@code subCodes} parameter.</p>
*
* <p><strong>About trusted sources:</strong></p>
* <p>Trusted sources are a core mechanism of fact audit. The system retrieves information from the trusted data sources that you configure to verify the factuality of the content to be audited.</p>
* <ul>
* <li><strong>Function:</strong> Trusted sources serve as the basis for factuality assessment. The system preferentially searches for relevant information from these trusted sources to verify the factuality of the content.</li>
* <li><strong>Necessity:</strong> Although configuring trusted sources is an optional step, it is highly recommended because:</li>
* <ul>
* <li>After configuration, the system verifies facts from these trusted sources, which improves audit accuracy.</li>
* <li>If not configured, the system may not be able to accurately assess certain factual information.</li>
* <li>You can configure multiple trusted sources. The system will synthesize information from multiple sources for assessment.</li>
* </ul>
* <li><strong>Impact:</strong> The quality of the configured sources directly affects the accuracy of the fact audit. We recommend that you select authoritative and reliable data sources.</li>
* </ul>
* <p>You can configure multiple trusted sources by using the {@link #configureTrustedSources(AsyncClient)} method.</p>
*
* <p>API reference:</p>
* <ul>
* <li>Submit audit task: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/SubmitSmartAudit">SubmitSmartAudit</a></li>
* <li>Configure trusted sources: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/SubmitFactAuditUrl">SubmitFactAuditUrl</a></li>
* <li>Query smart audit results: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/GetSmartAuditResult">GetSmartAuditResult</a>
* </li>
* <li>Export audit report:
* <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/ExportAuditContentResult">ExportAuditContentResult</a></li>
* </ul>
*/
public class FactAuditExample {
private static final String ALIBABA_CLOUD_ACCESS_KEY_ID = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
private static final String ALIBABA_CLOUD_ACCESS_KEY_SECRET = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
/**
* The unique identifier of the workspace.
* To obtain the workspace ID, see <a href="https://help.aliyun.com/en/model-studio/user-guide/manage-workspaces">Manage workspaces</a>.
*/
private static final String WORKSPACE_ID = System.getenv("WORKSPACE_ID");
private static final String ENDPOINT = System.getenv().getOrDefault("ENDPOINT", "aimiaobi.cn-beijing.aliyuncs.com");
public static void main(String[] args) throws Exception {
AsyncClient client = AuditUtils.createAsyncClient(ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET,
ENDPOINT);
// Configure trusted sources.
// If you do not need to configure trusted sources, you can comment out the following line of code.
configureTrustedSources(client);
// Submit a fact audit task.
String taskId = submitAuditTask(client);
// Poll for the audit result.
AuditUtils.pollAuditResult(client, WORKSPACE_ID, taskId);
// Export the audit result.
AuditUtils.exportAuditResults(client, WORKSPACE_ID, taskId);
}
/**
* Configure trusted sources.
*
* <p>This method is used to configure trusted data sources for fact audit. Trusted sources are a core mechanism of fact audit.
* The system retrieves information from the trusted data sources that you configure to verify the factuality of the content to be audited.</p>
*
* <p><strong>Function of trusted sources:</strong></p>
* <ul>
* <li>Serve as the basis for factuality assessment. The system preferentially searches for relevant information from these trusted sources.</li>
* <li>You can configure multiple trusted sources. The system synthesizes information from multiple sources for assessment.</li>
* <li>The quality of the configured sources directly affects the accuracy of the fact audit. We recommend that you select authoritative and reliable data sources.</li>
* </ul>
*
* <p><strong>Necessity of configuration:</strong></p>
* <p>Although configuring trusted sources is an optional step, it is highly recommended because:</p>
* <ul>
* <li>After configuration, the system verifies facts from these trusted sources, which improves audit accuracy.</li>
* <li>If not configured, the system may not be able to accurately assess certain factual information.</li>
* <li>You can configure multiple trusted sources. The system will synthesize information from multiple sources for assessment.</li>
* </ul>
*
* <p><strong>Note:</strong> Replace the sample URL with the URL of the trusted data source that you actually use.
* We recommend that you select authoritative and reliable data sources, such as official news websites or authoritative encyclopedias.</p>
*
* @param client The async client.
* @throws InterruptedException The InterruptedException.
* @throws ExecutionException The ExecutionException.
*/
public static void configureTrustedSources(AsyncClient client) throws InterruptedException, ExecutionException {
// Replace the following domain name with your own trusted source domain name.
for (String trustedSite : Collections.singletonList(
"hangzhou.com.cn"
)) {
// Configure the trusted source.
// Note: Replace the URL with the URL of the trusted data source that you actually use.
SubmitFactAuditUrlResponse response1 = client.submitFactAuditUrl(
SubmitFactAuditUrlRequest.builder().workspaceId(WORKSPACE_ID)
.url(trustedSite)
.build()).get();
if (response1.getBody().getSuccess()) {
System.out.println("Successfully configured the trusted source: " + trustedSite);
} else {
System.err.println("Failed to configure the trusted source: " + response1.getBody().getMessage());
}
}
}
/**
* Submit a fact audit task.
*
* <p>This method demonstrates how to submit a fact audit task. Fact audit is used to verify whether the factual information in the content is correct.</p>
*
* <p><strong>Description:</strong> To perform a fact audit, you must first configure trusted sources by using the {@link #configureTrustedSources(AsyncClient)} method.
* The system verifies the factuality of the content based on these trusted sources.</p>
*
* @param client The async client.
* @return The task ID.
* @throws InterruptedException The InterruptedException.
* @throws ExecutionException The ExecutionException.
*/
private static String submitAuditTask(AsyncClient client) throws InterruptedException, ExecutionException {
SubmitSmartAuditRequest.Builder builder = SubmitSmartAuditRequest.builder().workspaceId(WORKSPACE_ID);
// Set the audit dimension to fact audit.
// CorrectFact: Fact Audit - Correct Item
// WrongFactError: Fact Audit - Error Item
builder.subCodes(Arrays.asList("CorrectFact", "WrongFactError"));
// Sample text: The content to be audited that contains factual information.
// Replace the following text with the content that you want to audit.
builder.text("The winner of the 2025 Hangzhou Marathon is a Chinese national.");
// Submit the audit task.
SubmitSmartAuditResponse auditResponse = client.submitSmartAudit(builder.build()).get();
SubmitSmartAuditResponseBody.Data responseData = auditResponse.getBody().getData();
String taskId = responseData.getTaskId();
System.out.println(
"Successfully submitted the fact audit task. Task ID: " + taskId + ", Request ID: " + auditResponse.getBody().getRequestId());
return taskId;
}
}
5. Rule base review
Feature description Rule-based review is a content moderation feature that lets you define specific review rules based on your business needs. The system then uses these rules to moderate content. The feature has two phases: the rule preparation phase and the content review phase. Procedure- Initial setup: Run RuleLibraryPreparationExample to prepare the rule library.
- Routine audit: Run RuleBasedContentAuditExample to audit content.
- Update rules: To update the rule library, run RuleLibraryPreparationExample again.
Rule preparation
Description A rule library is a collection of custom audit rules designed to meet your business requirements. You must prepare the rule library file using the specified template. After you upload the file, the system will parse it and perform semantic indexing. Key steps:- Upload and parse the rule base file.
- Generate a semantic index for the rule base.
- The rule set file must follow the format provided in the Rule set template.
- Replace the example file path with the actual path to your rule set file.
- An incorrectly formatted rule set file may fail to parse.
- Allows you to define custom audit rules, such as blocking specific terms or restricting certain expressions.
- The system audits content based on the rule set.
- Submit an audit note SubmitAuditNote
- Query the processing status of an audit note GetAuditNoteProcessingStatus
- Confirm and post-process an audit note ConfirmAndPostProcessAuditNote
- Query the post-processing status of an audit note GetAuditNotePostProcessingStatus
Copy
package org.example.audit;
import java.util.concurrent.ExecutionException;
import com.aliyun.sdk.service.aimiaobi20230801.AsyncClient;
import com.aliyun.sdk.service.aimiaobi20230801.models.ConfirmAndPostProcessAuditNoteRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.ConfirmAndPostProcessAuditNoteResponse;
import com.aliyun.sdk.service.aimiaobi20230801.models.GetAuditNotePostProcessingStatusRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.GetAuditNotePostProcessingStatusResponse;
import com.aliyun.sdk.service.aimiaobi20230801.models.GetAuditNotePostProcessingStatusResponseBody;
import com.aliyun.sdk.service.aimiaobi20230801.models.GetAuditNoteProcessingStatusRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.GetAuditNoteProcessingStatusResponse;
import com.aliyun.sdk.service.aimiaobi20230801.models.GetAuditNoteProcessingStatusResponseBody.Data;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitAuditNoteRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitAuditNoteResponse;
/**
* Rule library preparation example.
*
* <p>This example shows how to prepare a rule library:</p>
* <ol>
* <li>Upload and parse a rule library file.</li>
* <li>Perform semantic indexing on the rule library to enable search matching in subsequent audits.</li>
* </ol>
*
* <p><strong>About the rule library:</strong></p>
* <p>A rule library is a collection of custom audit rules that you can define based on your business requirements.
* You must prepare the rule library file in the specified template format. After you upload the file, the system parses it and performs semantic indexing.</p>
* <ul>
* <li><strong>Function:</strong> A rule library lets you define custom audit rules, such as prohibiting certain words or restricting specific expressions.
* The system then audits content based on the rules in the library.</li>
* <li><strong>File format:</strong> The rule library file must adhere to the template format. See the
* <a href="https://aimiaobi-service-prod.oss-cn-beijing.aliyuncs.com/templates/%E8%A7%84%E5%88%99%E5%BA%93%E6%A8%A1%E6%9D%BF1105.xlsx">Rule Library Template</a>.</li>
* <li><strong>Processing flow:</strong> After you upload a rule library file, the system first parses it and then performs semantic indexing.
* You can use the rule library for content audits only after semantic indexing is complete.</li>
* </ul>
*
* <p><strong>Note:</strong> Replace the example file path with the actual path to your rule library file.
* The rule library file must follow the template format. Otherwise, parsing may fail.</p>
*
* <p>API reference:</p>
* <ul>
* <li>Submit a rule library: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/SubmitAuditNote">SubmitAuditNote</a></li>
* <li>Query the parsing status of a rule library: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/GetAuditNoteProcessingStatus">GetAuditNoteProcessingStatus</a></li>
* <li>Confirm and post-process a rule library: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/ConfirmAndPostProcessAuditNote">ConfirmAndPostProcessAuditNote</a></li>
* <li>Query the semantic indexing status: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/GetAuditNotePostProcessingStatus">GetAuditNotePostProcessingStatus</a></li>
* </ul>
*/
public class RuleLibraryPreparationExample {
private static final String ALIBABA_CLOUD_ACCESS_KEY_ID = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
private static final String ALIBABA_CLOUD_ACCESS_KEY_SECRET = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
private static final String WORKSPACE_ID = System.getenv("WORKSPACE_ID");
private static final String ENDPOINT = System.getenv().getOrDefault("ENDPOINT", "aimiaobi.cn-beijing.aliyuncs.com");
/**
* The maximum number of polling attempts. With a 2-second interval, the total wait time is about 10 minutes.
*/
private static final int MAX_POLLING_COUNT = 300;
public static void main(String[] args) throws Exception {
AsyncClient client = AuditUtils.createAsyncClient(ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET,
ENDPOINT);
// Example: Upload and parse the rule library file.
// Replace the file path with the actual path to your rule library file.
String ruleLibraryFilePath = "/path/to/your/RuleLibraryTemplate.xlsx";
// Example file content: Avoid colloquialisms, internet slang, and subjective emotional words in formal text. For example, terms like "awesome," "tons of," and "so good" are not allowed. Use vague intensifiers like "very" and "extremely" with caution.
// See the template file at: https://aimiaobi-service-prod.oss-cn-beijing.aliyuncs.com/templates/%E8%A7%84%E5%88%99%E5%BA%93%E6%A8%A1%E6%9D%BF1105.xlsx
uploadAndParseRuleLibrary(client, ruleLibraryFilePath);
}
/**
* Uploads and parses a rule library file.
*
* @param client The async client.
* @param filePath The path to the rule library file.
* @throws Exception if an error occurs during processing.
*/
public static void uploadAndParseRuleLibrary(AsyncClient client, String filePath)
throws Exception {
// Upload the rule library file to get a unique identifier.
String fileKey = AuditUtils.uploadFile(client, WORKSPACE_ID, filePath);
SubmitAuditNoteResponse response = client.submitAuditNote(SubmitAuditNoteRequest.builder().workspaceId(
WORKSPACE_ID).fileKey(fileKey).build()).get();
String taskId = response.getBody().getData();
System.out.println("Successfully submitted the rule library parsing task. Task ID: " + taskId);
GetAuditNoteProcessingStatusResponse processingStatusResponse = null;
boolean success = false;
for (int i = 0; i < MAX_POLLING_COUNT; i++) {
GetAuditNoteProcessingStatusRequest query = GetAuditNoteProcessingStatusRequest.builder().taskId(taskId)
.workspaceId(WORKSPACE_ID).build();
processingStatusResponse = client.getAuditNoteProcessingStatus(query).get();
String status = processingStatusResponse.getBody().getData().getStatus();
if ("RUNNING".equals(status) || "PENDING".equals(status)) {
System.out.println("Parsing the rule library. Please wait... (" + (i + 1) + "/" + MAX_POLLING_COUNT + ")");
Thread.sleep(2000);
} else {
success = true;
break;
}
}
if (!success) {
throw new RuntimeException("Rule library parsing timed out. Maximum polling attempts reached: " + MAX_POLLING_COUNT);
}
Data data = processingStatusResponse.getBody().getData();
String resultFileKey = data.getFileKey();
String resultTaskId = data.getTaskId();
System.out.println("Rule library parsed successfully. Result file: " + resultFileKey + ", task ID: " + resultTaskId);
// Start semantic indexing to enable search matching in subsequent audits.
ConfirmAndPostProcessAuditNoteResponse confirmAndPostProcessAuditNoteResponse
= client.confirmAndPostProcessAuditNote(
ConfirmAndPostProcessAuditNoteRequest.builder().taskId(resultTaskId).workspaceId(WORKSPACE_ID).build()
).get();
String embeddingTaskId = confirmAndPostProcessAuditNoteResponse.getBody().getData();
System.out.println("Successfully submitted the semantic indexing task. Task ID: " + embeddingTaskId);
GetAuditNotePostProcessingStatusResponse statusResponse = null;
boolean vectorizationSuccess = false;
for (int i = 0; i < MAX_POLLING_COUNT; i++) {
GetAuditNotePostProcessingStatusRequest build = GetAuditNotePostProcessingStatusRequest.builder()
.workspaceId(WORKSPACE_ID).taskId(embeddingTaskId).build();
statusResponse = client.getAuditNotePostProcessingStatus(build).get();
String status = statusResponse.getBody().getData().getStatus();
if ("RUNNING".equals(status) || "PENDING".equals(status)) {
System.out.println("Performing semantic indexing. Please wait... (" + (i + 1) + "/" + MAX_POLLING_COUNT + ")");
Thread.sleep(2000);
} else {
vectorizationSuccess = true;
break;
}
}
if (!vectorizationSuccess) {
throw new RuntimeException("Semantic indexing timed out. Maximum polling attempts reached: " + MAX_POLLING_COUNT);
}
GetAuditNotePostProcessingStatusResponseBody.Data data1 = statusResponse.getBody().getData();
System.out.println("Semantic indexing successful. Task status: " + data1.getStatus());
}
}
Content review
Function To moderate content, use a prepared rule set. The system evaluates the content against the rule set to ensure compliance. Note:- prerequisites: Before you use this example, ensure you have completed the rule base preparation phase (phase 1), including uploading the rule base file, parsing, and semantic indexing.
- review code: The review code for the rule base is WrongQuestionBook. You must add this code to the subCodes parameter when submitting a review task.
- Replace the sample text with your actual content.
Copy
package org.example.audit;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import com.aliyun.sdk.service.aimiaobi20230801.AsyncClient;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditRequest;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditResponse;
import com.aliyun.sdk.service.aimiaobi20230801.models.SubmitSmartAuditResponseBody;
/**
* Rule-based content audit example.
*
* <p>This example demonstrates how to use a prepared rule library for content audit. The procedure includes the following steps:</p>
* <ol>
* <li>Submit a content audit task.</li>
* <li>Poll for the audit result.</li>
* <li>Export the audit report.</li>
* </ol>
*
* <p><strong>Note:</strong> The code for rule library-based audit is <strong>WrongQuestionBook</strong>.
* When you submit an audit task, you must add this code to the {@code subCodes} parameter.</p>
*
* <p><strong>Prerequisites:</strong></p>
* <p>Before you use this example, make sure that the rule library is prepared. You can use {@link RuleLibraryPreparationExample} to prepare the rule library.
* The preparation includes uploading the rule library file, parsing the file, and processing the semantic index.</p>
*
* <p>API reference:</p>
* <ul>
* <li>Submit an audit task: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/SubmitSmartAudit">SubmitSmartAudit</a></li>
* <li>Query a smart audit result: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/GetSmartAuditResult">GetSmartAuditResult</a></li>
* <li>Export an audit report: <a href="https://api.aliyun.com/api/AiMiaoBi/2023-08-01/ExportAuditContentResult">ExportAuditContentResult</a></li>
* </ul>
*/
public class RuleBasedContentAuditExample {
private static final String ALIBABA_CLOUD_ACCESS_KEY_ID = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
private static final String ALIBABA_CLOUD_ACCESS_KEY_SECRET = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
private static final String WORKSPACE_ID = System.getenv("WORKSPACE_ID");
private static final String ENDPOINT = System.getenv().getOrDefault("ENDPOINT", "aimiaobi.cn-beijing.aliyuncs.com");
/**
* The code for the rule library-based audit type.
*/
private static final String RULE_BASED_AUDIT_TYPE = "WrongQuestionBook";
public static void main(String[] args) throws Exception {
AsyncClient client = AuditUtils.createAsyncClient(ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET,
ENDPOINT);
// Submit a content audit task.
String taskId = submitAuditTask(client);
// Poll for the audit result.
AuditUtils.pollAuditResult(client, WORKSPACE_ID, taskId);
// Export the audit results.
AuditUtils.exportAuditResults(client, WORKSPACE_ID, taskId);
}
/**
* Submits a content audit task.
*
* @param client The async client.
* @return The task ID.
* @throws InterruptedException if the thread is interrupted.
* @throws ExecutionException if the execution fails.
*/
private static String submitAuditTask(AsyncClient client) throws InterruptedException, ExecutionException {
// Sample text: Replace this with the actual content that you want to audit.
String contentToAudit
= "This event was a huge success. The turnout was massive, and the atmosphere was electric. Everyone was thrilled, and the entire process went smoothly.";
SubmitSmartAuditRequest.Builder builder = SubmitSmartAuditRequest.builder().workspaceId(WORKSPACE_ID);
builder.subCodes(Collections.singletonList(RULE_BASED_AUDIT_TYPE));
builder.text(contentToAudit);
SubmitSmartAuditResponse auditResponse = client.submitSmartAudit(builder.build()).get();
SubmitSmartAuditResponseBody.Data responseData = auditResponse.getBody().getData();
String taskId = responseData.getTaskId();
System.out.println(
"The audit task is submitted. Task ID: " + taskId + ", RequestId: " + auditResponse.getBody().getRequestId());
return taskId;
}
}