Qwen API はステートレスです。マルチターン対話を実装するには、各リクエストに会話履歴を渡します。コンテキストを管理し、トークン消費を削減するために、トリミング、要約、または取得を使用してください。
このトピックでは、OpenAI 互換のチャット補完および DashScope インターフェイスについて説明します。よりシンプルな代替方法については、「OpenAI 互換 - 応答」をご参照ください。
仕組み
マルチターン対話を実装するには、messages 配列を維持します。各ラウンドの後に、ユーザーの質問とモデルの応答を追加し、更新された配列を次のリクエストに使用します。
以下の例は、マルチターン対話中に messages 配列の状態がどのように変化するかを示しています。
-
第 1 ラウンド
messages配列にユーザーの質問を追加します。
Copy
// テキストモデルを使用
[
{"role": "user", "content": "宇宙探査をテーマにした SF 映画をおすすめしてください。"}
]
// マルチモーダルモデル(例:Qwen-VL)を使用
// {"role": "user",
// "content": [{"type": "image_url","image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"}},
// {"type": "text", "text": "画像に写っている商品は何ですか?"}]
// }
-
第 2 ラウンド
messages配列にモデルの応答とユーザーの最新の質問を追加します。
Copy
// テキストモデルを使用
[
{"role": "user", "content": "宇宙探査をテーマにした SF 映画をおすすめしてください。"},
{"role": "assistant", "content": "『XXX』をおすすめします。これは古典的な SF 作品です。"},
{"role": "user", "content": "この映画の監督は誰ですか?"}
]
// マルチモーダルモデル(例:Qwen-VL)を使用
//[
// {"role": "user", "content": [
// {"type": "image_url","image_url": {"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"}},
// {"type": "text", "text": "画像に写っている商品は何ですか?"}]},
// {"role": "assistant", "content": "画像には 3 点のアイテムが表示されています。ライトブルーのオーバーオール、青と白のストライプの半袖シャツ、白いスニーカーです。"},
// {"role": "user", "content": "それらのスタイルは何ですか?"}
//]
クイックスタート
- OpenAI 互換
- DashScope
Python
Copy
import os
from openai import OpenAI
def get_response(messages):
client = OpenAI(
# API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
# 環境変数を設定していない場合は、次の行を Model Studio API キーに置き換えてください: api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
# シンガポールリージョンの URL です。{WorkspaceId} を実際のワークスペース ID に置き換えてください。URL はリージョンによって異なります。
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
)
# モデルの一覧については、https://www.alibabacloud.com/help/en/model-studio/getting-started/models をご参照ください。
completion = client.chat.completions.create(model="qwen-plus", messages=messages)
return completion
# messages 配列を初期化
messages = [
{
"role": "system",
"content": """あなたはアリババモバイルショップの販売員です。ユーザーにスマートフォンをおすすめすることがあなたの役割です。スマートフォンには 2 つのパラメーターがあります。画面サイズ(6.1 インチ、6.5 インチ、6.7 インチ)と解像度(2K および 4K)です。
一度に 1 つのパラメーターのみをユーザーに尋ねることができます。ユーザーが完全な情報を提供しない場合、不足しているパラメーターを取得するためにフォローアップ質問をする必要があります。すべてのパラメーターが収集されたら、「購入意図を把握しました。少々お待ちください。」と言う必要があります。""",
}
]
assistant_output = "アリババモバイルショップへようこそ。どのような画面サイズをお探しですか?"
print(f"モデルの出力: {assistant_output}\n")
while "購入意図を把握しました。" not in assistant_output:
user_input = input("入力してください: ")
# ユーザーの質問を messages リストに追加
messages.append({"role": "user", "content": user_input})
assistant_output = get_response(messages).choices[0].message.content
# モデルの応答を messages リストに追加
messages.append({"role": "assistant", "content": assistant_output})
print(f"モデルの出力: {assistant_output}")
print("\n")
- Python
- Java
- curl
サンプルコードは、モバイルショップの販売員が顧客とマルチターン対話を行い、購入意図を把握してセッションを終了する例を示しています。
Copy
import os
import dashscope
# 以下はシンガポールリージョンの設定です。リージョンによって region の値は異なります。呼び出し時は、{WorkspaceId} をお使いのワークスペース ID に置き換えてください。
client = dashscope.Client(
# API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
# 環境変数が設定されていない場合は、api_key = "sk-xxx" に置き換えてください
api_key=os.getenv("DASHSCOPE_API_KEY"),
workspace="{WorkspaceId}",
region="ap-southeast-1",
)
def get_response(messages):
response = client.chat.completions.create(
# モデルの一覧については、https://www.alibabacloud.com/help/en/model-studio/getting-started/models をご参照ください。
model="qwen-plus",
messages=messages,
)
return response
# messages 配列を初期化
messages = [
{
"role": "system",
"content": """あなたはアリババモバイルショップの販売員です。ユーザーにスマートフォンをおすすめすることがあなたの役割です。スマートフォンには 2 つのパラメーターがあります。画面サイズ(6.1 インチ、6.5 インチ、6.7 インチ)と解像度(2K および 4K)です。
一度に 1 つのパラメーターのみをユーザーに尋ねることができます。ユーザーが完全な情報を提供しない場合、不足しているパラメーターを取得するためにフォローアップ質問をする必要があります。すべてのパラメーターが収集されたら、「購入意図を把握しました。少々お待ちください。」と言う必要があります。""",
}
]
assistant_output = "アリババモバイルショップへようこそ。どのような画面サイズをお探しですか?"
print(f"モデルの出力: {assistant_output}\n")
while "購入意図を把握しました。" not in assistant_output:
user_input = input("入力してください: ")
# ユーザーの質問を messages リストに追加
messages.append({"role": "user", "content": user_input})
assistant_output = get_response(messages).choices[0].message.content
# モデルの応答を messages リストに追加
messages.append({"role": "assistant", "content": assistant_output})
print(f"モデルの出力: {assistant_output}")
print("\n")
Copy
import java.util.ArrayList;
import java.util.List;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import java.util.Scanner;
import com.alibaba.dashscope.protocol.Protocol;
public class Main {
public static GenerationParam createGenerationParam(List<Message> messages) {
return GenerationParam.builder()
// API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
// 環境変数を設定していない場合は、次の行を Model Studio API キーに置き換えてください: .apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// モデルの一覧については、https://www.alibabacloud.com/help/en/model-studio/getting-started/models をご参照ください。
.model("qwen-plus")
.messages(messages)
.resultFormat(GenerationParam.ResultFormat.MESSAGE)
.build();
}
public static GenerationResult callGenerationWithMessages(GenerationParam param) throws ApiException, NoApiKeyException, InputRequiredException {
// シンガポールリージョンの URL です。{WorkspaceId} を実際のワークスペース ID に置き換えてください。URL はリージョンによって異なります。
Generation gen = new Generation(Protocol.HTTP.getValue(), "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1");
return gen.call(param);
}
public static void main(String[] args) {
try {
List<Message> messages = new ArrayList<>();
messages.add(createMessage(Role.SYSTEM, "あなたは親切なアシスタントです。"));
for (int i = 0; i < 3;i++) {
Scanner scanner = new Scanner(System.in);
System.out.print("入力してください: ");
String userInput = scanner.nextLine();
if ("exit".equalsIgnoreCase(userInput)) {
break;
}
messages.add(createMessage(Role.USER, userInput));
GenerationParam param = createGenerationParam(messages);
GenerationResult result = callGenerationWithMessages(param);
System.out.println("モデルの出力: "+result.getOutput().getChoices().get(0).getMessage().getContent());
messages.add(result.getOutput().getChoices().get(0).getMessage());
}
} catch (ApiException | NoApiKeyException | InputRequiredException e) {
e.printStackTrace();
}
System.exit(0);
}
private static Message createMessage(Role role, String content) {
return Message.builder().role(role.getValue()).content(content).build();
}
}
Copy
# ======= 重要 =======
# API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
# === 実行前にこのコメントを削除してください ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/text-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-plus",
"input":{
"messages":[
{
"role": "system",
"content": "あなたは親切なアシスタントです。"
},
{
"role": "user",
"content": "こんにちは"
},
{
"role": "assistant",
"content": "こんにちは、私は Qwen です。"
},
{
"role": "user",
"content": "あなたは何ができますか?"
}
]
}
}'
マルチモーダルモデルの場合
マルチモーダルモデルは、対話において画像や音声をサポートします。テキストモデルとは次のように実装が異なります。- ユーザーのメッセージ構築: マルチモーダルモデルのユーザーのメッセージには、テキストに加えて画像や音声などのマルチモーダル情報が含まれる場合があります。
- DashScope SDK インターフェイス: DashScope Python SDK を使用する場合は、
MultiModalConversationインターフェイスを呼び出します。DashScope Java SDK を使用する場合は、MultiModalConversationクラスを呼び出します。
マルチモーダルモデルについては、「画像および動画理解」、「および「Kimi」をご参照ください。Qwen-Omni については、「非リアルタイム (Qwen-Omni)」をご参照ください。Qwen-VL-OCR および Qwen3-Omni-Captioner は特定のシングルターンタスク用に設計されており、マルチターン対話をサポートしません。
- OpenAI 互換
- DashScope
Python
Copy
from openai import OpenAI
import os
client = OpenAI(
# API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
# 環境変数を設定していない場合は、次の行を Model Studio API キーに置き換えてください: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
# シンガポールリージョンの URL です。{WorkspaceId} を実際のワークスペース ID に置き換えてください。URL はリージョンによって異なります。
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
)
messages = [
{"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"
},
},
{"type": "text", "text": "画像に写っている商品は何ですか?"},
],
}
]
completion = client.chat.completions.create(
model="qwen3-vl-plus", # 他のマルチモーダルモデルに置き換え、必要に応じて messages を修正できます。
messages=messages,
)
print(f"第 1 ラウンドの出力: {completion.choices[0].message.content}")
assistant_message = completion.choices[0].message
messages.append(assistant_message.model_dump())
messages.append({
"role": "user",
"content": [
{
"type": "text",
"text": "それらのスタイルは何ですか?"
}
]
})
completion = client.chat.completions.create(
model="qwen3-vl-plus",
messages=messages,
)
print(f"第 2 ラウンドの出力: {completion.choices[0].message.content}")
Python
Copy
import os
import dashscope
# 以下はシンガポールリージョンの設定です。リージョンによって region の値は異なります。呼び出し時は、{WorkspaceId} をお使いのワークスペース ID に置き換えてください。
client = dashscope.Client(
# API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
# 環境変数が設定されていない場合は、api_key = "sk-xxx" に置き換えてください
api_key=os.getenv('DASHSCOPE_API_KEY'),
workspace="{WorkspaceId}",
region="ap-southeast-1",
)
messages = [
{
"role": "user",
"content": [
{
"image": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20251031/ownrof/f26d201b1e3f4e62ab4a1fc82dd5c9bb.png"
},
{"text": "画像に写っている商品は何ですか?"},
],
}
]
response = client.multimodal.chat.create(
model='qwen3-vl-plus', # 他のマルチモーダルモデルに置き換え、必要に応じて messages を修正できます。
messages=messages)
print(f"モデルの第 1 ラウンド出力 {response.output_text}")
messages.append(response.choices[0].message.model_dump(exclude_none=True))
user_msg = {"role": "user", "content": [{"text": "それらのスタイルは何ですか?"}]}
messages.append(user_msg)
response = client.multimodal.chat.create(
model='qwen3-vl-plus',
messages=messages)
print(f"モデルの第 2 ラウンド出力 {response.output_text}")
思考モデルの場合
思考モデルは、reasoning_content(思考プロセス)と content(応答)を返します。messages を更新する際は、content のみを保持し、reasoning_content は無視してください。
Copy
[
{"role": "user", "content": "宇宙探査をテーマにした SF 映画をおすすめしてください。"},
{"role": "assistant", "content": "『XXX』をおすすめします。これは古典的な SF 作品です。"}, # コンテキストに追加する際に reasoning_content フィールドを追加しないでください。
{"role": "user", "content": "この映画の監督は誰ですか?"}
]
思考モデルの詳細については、「ディープシンキング」、「画像および動画理解」をご参照ください。
Qwen3-Omni-Flash(思考モード)によるマルチターン対話の実装方法の詳細については、「オムニモーダル」をご参照ください。
- OpenAI 互換
- DashScope
- Python
- Node.js
- HTTP
サンプルコード
Copy
from openai import OpenAI
import os
# OpenAI クライアントを初期化
client = OpenAI(
# API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
# 環境変数を設定していない場合は、次の行を Model Studio API キーに置き換えてください: api_key="sk-xxx"
api_key = os.getenv("DASHSCOPE_API_KEY"),
base_url="https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
)
messages = []
conversation_idx = 1
while True:
reasoning_content = "" # 完全な思考プロセスを定義
answer_content = "" # 完全な応答を定義
is_answering = False # 思考プロセスを終了して応答を開始するかどうかを判断
print("="*20+f"会話ラウンド {conversation_idx}"+"="*20)
conversation_idx += 1
user_msg = {"role": "user", "content": input("メッセージを入力してください: ")}
messages.append(user_msg)
# チャット補完リクエストを作成
completion = client.chat.completions.create(
# 必要に応じて他のディープシンキングモデルに置き換えられます。
model="qwen-plus",
messages=messages,
extra_body={"enable_thinking": True},
stream=True,
# stream_options={
# "include_usage": True
# }
)
print("\n" + "=" * 20 + "思考プロセス" + "=" * 20 + "\n")
for chunk in completion:
# chunk.choices が空の場合は使用量を出力
if not chunk.choices:
print("\n使用量:")
print(chunk.usage)
else:
delta = chunk.choices[0].delta
# 思考プロセスを出力
if hasattr(delta, 'reasoning_content') and delta.reasoning_content != None:
print(delta.reasoning_content, end='', flush=True)
reasoning_content += delta.reasoning_content
else:
# 応答を開始
if delta.content != "" and is_answering is False:
print("\n" + "=" * 20 + "完全な応答" + "=" * 20 + "\n")
is_answering = True
# 応答プロセスを出力
print(delta.content, end='', flush=True)
answer_content += delta.content
# モデルの応答内容をコンテキストに追加
messages.append({"role": "assistant", "content": answer_content})
print("\n")
サンプルコード
Copy
import OpenAI from "openai";
import process from 'process';
import readline from 'readline/promises';
// readline インターフェイスを初期化
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// openai クライアントを初期化
const openai = new OpenAI({
// API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
apiKey: process.env.DASHSCOPE_API_KEY, // 環境変数から読み取り
baseURL: 'https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1'
});
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [];
let conversationIdx = 1;
async function main() {
while (true) {
console.log("=".repeat(20) + `会話ラウンド ${conversationIdx}` + "=".repeat(20));
conversationIdx++;
// ユーザー入力を読み取り
const userInput = await rl.question("メッセージを入力してください: ");
messages.push({ role: 'user', content: userInput });
// 状態をリセット
reasoningContent = '';
answerContent = '';
isAnswering = false;
try {
const stream = await openai.chat.completions.create({
// 必要に応じて他のディープシンキングモデルに置き換えられます。
model: 'qwen-plus',
messages: messages,
enable_thinking: true,
stream: true,
// stream_options:{
// include_usage: true
// }
});
console.log("\n" + "=".repeat(20) + "思考プロセス" + "=".repeat(20) + "\n");
for await (const chunk of stream) {
if (!chunk.choices?.length) {
console.log('\n使用量:');
console.log(chunk.usage);
continue;
}
const delta = chunk.choices[0].delta;
// 思考プロセスを処理
if (delta.reasoning_content) {
process.stdout.write(delta.reasoning_content);
reasoningContent += delta.reasoning_content;
}
// 正式な応答を処理
if (delta.content) {
if (!isAnswering) {
console.log('\n' + "=".repeat(20) + "完全な応答" + "=".repeat(20) + "\n");
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
// 完全な応答をメッセージ履歴に追加
messages.push({ role: 'assistant', content: answerContent });
console.log("\n");
} catch (error) {
console.error('エラー:', error);
}
}
}
// プログラムを開始
main().catch(console.error);
サンプルコード
- curl
Copy
# ======= 重要 =======
# API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
# === 実行前にこのコメントを削除してください ===
curl -X POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-plus",
"messages": [
{
"role": "user",
"content": "こんにちは"
},
{
"role": "assistant",
"content": "こんにちは!はじめまして。何かお手伝いできることはありますか?"
},
{
"role": "user",
"content": "あなたは誰ですか?"
}
],
"stream": true,
"stream_options": {
"include_usage": true
},
"enable_thinking": true
}'
- Python
- Java
- HTTP
サンプルコード
Copy
import os
import dashscope
# 以下はシンガポールリージョンの設定です。リージョンによって region の値は異なります。呼び出し時は、{WorkspaceId} をお使いのワークスペース ID に置き換えてください。
client = dashscope.Client(
# 環境変数が設定されていない場合は、api_key = "sk-xxx" に置き換えてください
# API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
api_key=os.getenv('DASHSCOPE_API_KEY'),
workspace="{WorkspaceId}",
region="ap-southeast-1",
)
messages = []
conversation_idx = 1
while True:
print("=" * 20 + f"Conversation Round {conversation_idx}" + "=" * 20)
conversation_idx += 1
user_input = input("メッセージを入力してください('exit' と入力すると終了します): ")
# 'exit' と入力するとマルチターン対話を終了し、無限ループを回避できます
if user_input.strip().lower() == "exit":
print("Conversation ended.")
break
user_msg = {"role": "user", "content": [{"text": user_input}]}
messages.append(user_msg)
stream = client.multimodal.chat.create(
# この例では qwen-plus を使用しています。必要に応じて他のディープシンキングモデルに置き換えられます。
model="qwen-plus",
messages=messages,
enable_thinking=True,
stream=True,
)
# 完全な思考プロセスを定義
reasoning_content = ""
# 完全な応答を定義
answer_content = ""
# 思考プロセスを終了して応答を開始するかどうかを判断
is_answering = False
print("=" * 20 + "Thinking Process" + "=" * 20)
for chunk in stream:
# 現在のチャンクの内容を取得します(ストリーミング出力はデフォルトで増分出力になります)
content_text = chunk.choices[0].delta.content or ""
reasoning_text = chunk.choices[0].delta.reasoning_content or ""
# 思考プロセスと応答の両方が空の場合は無視
if content_text == "" and reasoning_text == "":
pass
else:
# 現在が思考プロセスの場合
if reasoning_text != "" and content_text == "":
print(reasoning_text, end="",flush=True)
reasoning_content += reasoning_text
# 現在が応答の場合
elif content_text != "":
if not is_answering:
print("\n" + "=" * 20 + "Complete Response" + "=" * 20)
is_answering = True
print(content_text, end="",flush=True)
answer_content += content_text
# モデルの応答内容をコンテキストに追加
messages.append({"role": "assistant", "content": [{"text": answer_content}]})
print("\n")
# 完全な思考プロセスと完全な応答を出力するには、次のコードのコメントを外して実行してください。
# print("=" * 20 + "Complete Thinking Process" + "=" * 20 + "\n")
# print(f"{reasoning_content}")
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(f"{answer_content}")
サンプルコード
Copy
// DashScope SDK バージョン >= 2.19.4
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import java.lang.System;
import java.util.List;
import com.alibaba.dashscope.protocol.Protocol;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
private static StringBuilder reasoningContent = new StringBuilder();
private static StringBuilder finalContent = new StringBuilder();
private static boolean isFirstPrint = true;
private static void handleGenerationResult(GenerationResult message) {
if (message != null && message.getOutput() != null
&& message.getOutput().getChoices() != null
&& !message.getOutput().getChoices().isEmpty()
&& message.getOutput().getChoices().get(0) != null
&& message.getOutput().getChoices().get(0).getMessage() != null) {
String reasoning = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
String content = message.getOutput().getChoices().get(0).getMessage().getContent();
if (reasoning != null && !reasoning.isEmpty()) {
reasoningContent.append(reasoning);
if (isFirstPrint) {
System.out.println("====================思考プロセス====================");
isFirstPrint = false;
}
System.out.print(reasoning);
}
if (content != null && !content.isEmpty()) {
finalContent.append(content);
if (!isFirstPrint) {
System.out.println("\n====================完全な応答====================");
isFirstPrint = true;
}
System.out.print(content);
}
}
}
private static GenerationParam buildGenerationParam(List<Message> messages) {
return GenerationParam.builder()
// 環境変数を設定していない場合は、次の行を Model Studio API キーに置き換えてください: .apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// この例では qwen-plus を使用しています。必要に応じて他のモデル名に置き換えられます。
.model("qwen-plus")
.enableThinking(true)
.messages(messages)
.incrementalOutput(true)
.resultFormat("message")
.build();
}
public static void streamCallWithMessage(Generation gen, List<Message> messages)
throws NoApiKeyException, ApiException, InputRequiredException {
GenerationParam param = buildGenerationParam(messages);
Flowable<GenerationResult> result = gen.streamCall(param);
result.doOnError(throwable -> logger.error("ストリーム処理中にエラーが発生しました: {}", throwable.getMessage(), throwable))
.blockingForEach(Main::handleGenerationResult);
}
public static void main(String[] args) {
try {
// シンガポールリージョンの URL です。{WorkspaceId} を実際のワークスペース ID に置き換えてください。URL はリージョンによって異なります。
Generation gen = new Generation(Protocol.HTTP.getValue(), "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1");
Message userMsg1 = Message.builder()
.role(Role.USER.getValue())
.content("こんにちは")
.build();
Message assistantMsg = Message.builder()
.role(Role.ASSISTANT.getValue())
.content("こんにちは!はじめまして。何かお手伝いできることはありますか?")
.build();
Message userMsg2 = Message.builder()
.role(Role.USER.getValue())
.content("あなたは誰ですか")
.build();
List<Message> messages = Arrays.asList(userMsg1, assistantMsg, userMsg2);
streamCallWithMessage(gen, messages);
} catch (ApiException | NoApiKeyException | InputRequiredException e) {
logger.error("例外が発生しました: {}", e.getMessage(), e);
} catch (Exception e) {
logger.error("予期しないエラーが発生しました: {}", e.getMessage(), e);
} finally {
// プログラムが正常に終了することを保証
System.exit(0);
}
}
}
サンプルコード
- curl
Copy
# ======= 重要 =======
# API キーはリージョンによって異なります。API キーの取得方法については、https://www.alibabacloud.com/help/en/model-studio/get-api-key をご参照ください。
# === 実行前にこのコメントを削除してください ===
curl -X POST "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/text-generation/generation" \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H "Content-Type: application/json" \
-H "X-DashScope-SSE: enable" \
-d '{
"model": "qwen-plus",
"input":{
"messages":[
{
"role": "user",
"content": "こんにちは"
},
{
"role": "assistant",
"content": "こんにちは!はじめまして。何かお手伝いできることはありますか?"
},
{
"role": "user",
"content": "あなたは誰ですか?"
}
]
},
"parameters":{
"enable_thinking": true,
"incremental_output": true,
"result_format": "message"
}
}'
本番環境に適用
マルチターン対話は多くのトークンを消費し、モデルのコンテキスト長を超えてエラーを引き起こす可能性があります。コンテキストを管理しコストをコントロールするために、以下の戦略を使用してください。1. コンテキスト管理
messages 配列は各ラウンドで増加し、モデルのトークン制限を超える可能性があります。コンテキスト長を管理するために、以下の方法を使用してください。
1.1. コンテキストのトリミング
履歴が長くなりすぎた場合、最新の N ラウンドのみを保持します。実装は簡単ですが、以前の会話情報が失われます。1.2. ローリングサマリー
会話が進行するにつれてコンテキストを要約し、履歴を圧縮して長さをコントロールし、コア情報を失わないようにします。 a. 履歴が最大コンテキスト長の 70% に達したら、前の部分(最初の半分など)を抽出し、別途 API 呼び出しを行って「メモリサマリー」を生成します。 b. 次のリクエストでは、長い履歴を「メモリサマリー」に置き換え、最新のラウンドを追加します。1.3. ベクトル化された取得
ローリングサマリーでは一部の情報が失われる可能性があります。大規模な会話履歴からモデルが関連情報を思い出すことができるように、線形のコンテキスト渡しではなく、オンデマンド取得を使用します。 a. 各会話ラウンドの後、会話をベクトルデータベースに保存します。 b. ユーザーが質問をすると、類似性に基づいて関連する会話レコードを取得します。 c. 取得した会話レコードと最新のユーザー入力を組み合わせて、その内容をモデルに送信します。2. コスト管理
各ラウンドで入力トークンが増加し、コストが大幅に上昇します。以下のコスト管理戦略を使用してください。2.1. 入力トークンの削減
前述のコンテキスト管理戦略を使用して入力トークンを削減し、コストを下げます。2.2. コンテキストキャッシュをサポートするモデルの使用
マルチターンリクエストでは、messages 配列が繰り返し処理され、課金されます。Model Studio は、qwen-max や qwen-plus などのモデルに対してコンテキストキャッシュを提供しており、これによりコストを削減し応答速度を向上させます。コンテキストキャッシュをサポートするモデルを優先的に使用してください。
コンテキストキャッシュは自動的に有効化され、コードの変更は不要です。