This topic provides a best practice on how to build a Retrieval-Augmented Generation (RAG) application for unstructured data in Alibaba Cloud Model Studio and how to call the application through API or SDK with low code.
Prepare the application
Step 1: Import Data
Log on to the Alibaba Cloud Model Studio.
In the left-side navigation pane, choose
.On the Unstructured Data tab, select a category and click Import Data.
On the Import Data page, upload your local files. Then, click Confirm.
When the Status becomes Imported, the files are imported.
Step 2: Create a knowledge index
In the left-side navigation pane, choose
. Then, click Create Knowledge Base.On the Create Knowledge Base, specify a name for the knowledge base. For other parameters, you can use the default settings. Then, Click Next Step.
Select the files you just uploaded and click Import.
When the Status becomes Parsed, the files are imported.
Go back to the Knowledge Base Management page. Click the icon to view the knowledge base ID, which is necessary if you want to call the knowledge base through Assistant API.
Step 3: Create an application
In the left-side navigation pane, choose
. Then, click Create Application.Select a model. You can also configure related parameters.
Enable the Knowledge Retrieval Augmentation feature and select the knowledge base you created in Step 2: Create a knowledge index.
Click Publish on the upper-right corner to publish the application. You can also test the application in the right side.
Go back to the My Applications page. View the application ID of the application you just created.
Call the application
Prerequisites
An API key is obtained. For more information, see Obtain an API key.
An SDK of the latest version is installed. For more information, see Install the SDK.
Use API or SDK
In the following sample code, replace YOUR_API_KEY with your API key and YOUR_APP_ID with your application ID.
from http import HTTPStatus
from dashscope import Application
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
def call_agent_app():
response = Application.call(app_id='YOUR_APP_ID',
prompt='What is workspace in Alibaba Cloud Model Studio? How to use workspace?',
api_key='YOUR_API_KEY',
)
if response.status_code != HTTPStatus.OK:
print('request_id=%s, code=%s, message=%s\n' % (response.request_id, response.status_code, response.message))
else:
print('request_id=%s\n output=%s\n usage=%s\n' % (response.request_id, response.output, response.usage))
if __name__ == '__main__':
call_agent_app()
import com.alibaba.dashscope.app.*;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import java.util.List;
import com.alibaba.dashscope.utils.Constants;
public class Main{
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
public static void callAgentApp()
throws ApiException, NoApiKeyException, InputRequiredException {
ApplicationParam param = ApplicationParam.builder()
.apiKey("YOUR_API_KEY")
.appId("YOUR_APP_ID")
.prompt("What is workspace in Alibaba Cloud Model Studio? How to use workspace?")
.build();
Application application = new Application();
ApplicationResult result = application.call(param);
System.out.printf("requestId: %s, text: %s, finishReason: %s\n",
result.getRequestId(), result.getOutput().getText(), result.getOutput().getFinishReason());
}
public static void main(String[] args) {
try {
callAgentApp();
} catch (ApiException | NoApiKeyException | InputRequiredException e) {
System.out.printf("Exception: %s", e.getMessage());
}
System.exit(0);
}
}
curl --location 'https://dashscope-intl.aliyuncs.com/api/v1/apps/{YOUR_APP_ID}/completion' \
--header 'Authorization: Bearer {YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data-raw '{
"input": {
"prompt": "What is workspace in Alibaba Cloud Model Studio? How to use workspace?"
},
"parameters": {},
"debug": {}
}' --verbose
Use Assistant API
In the following sample code, replace YOUR_DASHSCOPE_API_KEY with your API key. Or, set your API key as an environment variable. For more information, see Set API key as an environment variable.
export DASHSCOPE_API_KEY=YOUR_DASHSCOPE_API_KEY
Replace YOUR_PIPELINE_ID with the knowledge index ID of the knowledge base created in Step 2: Create a knowledge index.
Ensure that the placeholder
${document1}
used inquery_word/value
of the RAG tool matches the placeholder used ininstructions
of the sample code.
from dashscope import Assistants, Messages, Runs, Threads
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
assistant = Assistants.create(
model='qwen-max',
name='smart helper',
description='Inteliigent assistant supporting knowledge base retrieval and plug-ins.',
instructions='You are an intelligent assistant. Remember the following information. ${document1}',
tools=[
{
"type": "code_interpreter"
},
{
"type": "rag",
"prompt_ra": {
"pipeline_id": "YOUR_PIPELINE_ID",
"parameters": {
"type": "object",
"properties": {
"query_word": {
"type": "str",
"value": "${document1}"
}
}
}
}
}]
)
def send_message(assistant, message='What is Alibaba Cloud Model Studio?'):
print(f"Query: {message}")
# create thread.
# create a thread.
thread = Threads.create()
print(thread)
# create a message.
message = Messages.create(thread.id, content=message)
# create run
run = Runs.create(thread.id, assistant_id=assistant.id)
print(run)
# # get run statue
# run_status = Runs.get(run.id, thread_id=thread.id)
# print(run_status)
# wait for run completed or requires_action
run_status = Runs.wait(run.id, thread_id=thread.id)
# print(run_status)
# if prompt input tool result, submit tool result.
run_status = Runs.get(run.id, thread_id=thread.id)
print(run_status)
# verify_status_code(run_status)
# get the thread messages.
msgs = Messages.list(thread.id)
# print(msgs)
# print(json.dumps(msgs, default=lambda o: o.__dict__, sort_keys=True, indent=4))
print("Result:")
for message in msgs['data'][::-1]:
print("content: ", message['content'][0]['text']['value'])
print("\n")
if __name__ == "__main__":
send_message(assistant, message='What is Alibaba Cloud Model Studio?')
import com.alibaba.dashscope.assistants.Assistant;
import com.alibaba.dashscope.assistants.AssistantParam;
import com.alibaba.dashscope.assistants.Assistants;
import com.alibaba.dashscope.common.GeneralListParam;
import com.alibaba.dashscope.common.ListResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.InvalidateParameter;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.threads.AssistantThread;
import com.alibaba.dashscope.threads.ContentText;
import com.alibaba.dashscope.threads.ThreadParam;
import com.alibaba.dashscope.threads.Threads;
import com.alibaba.dashscope.threads.messages.Messages;
import com.alibaba.dashscope.threads.messages.TextMessageParam;
import com.alibaba.dashscope.threads.messages.ThreadMessage;
import com.alibaba.dashscope.threads.runs.Run;
import com.alibaba.dashscope.threads.runs.RunParam;
import com.alibaba.dashscope.threads.runs.Runs;
import com.alibaba.dashscope.tools.ToolBase;
import com.google.gson.JsonObject;
import com.google.gson.annotations.SerializedName;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.SuperBuilder;
import com.alibaba.dashscope.utils.Constants;
public class AssistantApiRag {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
public static Assistant createAssistant(String pipelineId) throws ApiException, NoApiKeyException {
// Make sure the placeholder ${document1} in instructions is the same with ${document1} in buildPromptRa
AssistantParam assistantParam = AssistantParam.builder()
.model("qwen-max")
.name("smart helper")
.description("Inteliigent assistant supporting knowledge base retrieval and plug-ins.")
.instructions("You are an intelligent assistant. Remember the following information. ${document1}")
.tool(ToolRag.builder()
.promptRa(ToolRag.buildPromptRa("${document1}", pipelineId))
.build())
.build();
Assistants assistants = new Assistants();
return assistants.create(assistantParam);
}
public static void sendMessage(Assistant assistant, String message) throws NoApiKeyException, InputRequiredException, InvalidateParameter, InterruptedException {
Threads threads = new Threads();
AssistantThread assistantThread = threads.create(ThreadParam.builder().build());
Runs runs = new Runs();
// create a new message
TextMessageParam textMessageParam = TextMessageParam.builder()
.role("user")
.content(message)
.build();
Messages messages = new Messages();
ThreadMessage threadMessage = messages.create(assistantThread.getId(), textMessageParam);
System.out.println(threadMessage);
RunParam runParam = RunParam.builder().assistantId(assistant.getId()).build();
Run run = runs.create(assistantThread.getId(), runParam);
while (true) {
if (run.getStatus().equals(Run.Status.CANCELLED) ||
run.getStatus().equals(Run.Status.COMPLETED) ||
run.getStatus().equals(Run.Status.FAILED) ||
run.getStatus().equals(Run.Status.REQUIRES_ACTION) ||
run.getStatus().equals(Run.Status.EXPIRED)) {
break;
} else {
Thread.sleep(1000);
}
run = runs.retrieve(assistantThread.getId(), run.getId());
}
System.out.println(run);
GeneralListParam listParam = GeneralListParam.builder().limit(100L).build();
ListResult<ThreadMessage> threadMessages = messages.list(assistantThread.getId(), listParam);
for (ThreadMessage threadMessage2 : threadMessages.getData()) {
System.out.printf("content: %s\n", ((ContentText) threadMessage2.getContent().get(0)).getText().getValue());
}
}
public static void main(String[] args) throws NoApiKeyException, InputRequiredException, InvalidateParameter, InterruptedException {
String pipelineId = "wa9vj93fwv";
Assistant assistant = createAssistant(pipelineId);
sendMessage(assistant, "What is Alibaba Cloud Model Studio?");
}
}
@Data
@EqualsAndHashCode(callSuper = false)
@SuperBuilder
class ToolRag extends ToolBase {
static {
registerTool("rag", ToolRag.class);
}
@Builder.Default
private String type = "rag";
@SerializedName("prompt_ra")
private JsonObject promptRa;
@Override
public String getType() {
return type;
}
public static JsonObject buildPromptRa(String placeholder, String pipelineId) {
JsonObject queryWord = new JsonObject();
queryWord.addProperty("type", "str");
queryWord.addProperty("value", placeholder);
JsonObject properties = new JsonObject();
properties.add("query_word", queryWord);
JsonObject parameters = new JsonObject();
parameters.addProperty("type", "object");
parameters.add("properties", properties);
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("pipeline_id", pipelineId);
jsonObject.add("parameters", parameters);
return jsonObject;
}
}