QVQ モデルは強力な視覚的推論機能を備えています。最初に思考プロセスを出力し、次に応答内容を出力します。現在、QVQ はストリーミング出力のみをサポートしています。
対応モデル
QVQ は、視覚的入力と連鎖的思考出力をサポートする視覚的推論モデルです。数学、プログラミング、視覚分析、創作、および一般的なタスクにおいて、より強力な機能を発揮します。
名前 | バージョン | コンテキストウィンドウ | 最大入力 | 最大 CoT | 最大応答 | 入力価格 | 出力価格 | 無料枠 |
(トークン) | (百万トークン) | |||||||
qvq-max qvq-max-2025-03-25 と同じパフォーマンス | 安定版 | 131,072 | 106,496 画像あたり最大 16,384 | 16,384 | 8,192 | $1.2 | $4.8 | それぞれ 100 万トークン アクティベーション後 180 日間有効 |
qvq-max-latest 常に最新のスナップショットと同じパフォーマンス | 最新版 | |||||||
qvq-max-2025-03-25 qvq-max-0325 とも呼ばれます | スナップショット |
同時実行レート制限については、レート制限 を参照してください。
始めよう
前提条件:API キーを取得 し、環境変数として構成 する必要があります。 SDK を使用するには、OpenAI または DashScope SDK をインストール する必要があります。 Java 用の DashScope SDK は、バージョン 2.19.0 以降である必要があります。
推論時間が長いため、現在 QVQ はストリーミング出力のみをサポートしています。
QVQ では思考を無効にすることはできません。
QVQ はシステムメッセージをサポートしていません。
DashScope メソッドの場合:
incremental_output
はデフォルトでtrue
であり、false
にすることはできません。result_format
はデフォルトで"message"
であり、"text"
にすることはできません。
次のサンプルコードは、理解のために画像 URL を使用しています。
入力画像の制限 セクションを確認してください。ローカル画像を使用するには、ローカルファイルの使用 を参照してください。
OpenAI
Python
サンプルコード
from openai import OpenAI
import os
# OpenAI クライアントを初期化します
client = OpenAI(
# 環境変数が構成されていない場合は、Model Studio API キーに置き換えます。api_key="sk-xxx"
api_key = os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
)
reasoning_content = "" # 完全な思考プロセスを定義します
answer_content = "" # 完全な応答を定義します
is_answering = False # 思考プロセスが終了し、応答が開始されたかどうかを判断します
# チャット補完リクエストを作成します
completion = client.chat.completions.create(
model="qvq-max", # 例として qvq-max を使用していますが、必要に応じて他のモデル名に置き換えることができます
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"
},
},
{"type": "text", "text": "この問題を解く方法は?"},
],
},
],
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
# print("=" * 20 + "完全な推論プロセス" + "=" * 20 + "\n")
# print(reasoning_content)
# print("=" * 20 + "完全な応答" + "=" * 20 + "\n")
# print(answer_content)
Node.js
サンプルコード
import OpenAI from "openai";
import process from 'process';
// openai クライアントを初期化します
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY, // 環境変数から読み取ります
baseURL: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1'
});
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [
{
role: "user",
content: [
{ type: "image_url", image_url: { "url": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg" } },
{ type: "text", text: "この問題を解いてください" },
]
}]
async function main() {
try {
const stream = await openai.chat.completions.create({
model: 'qvq-max',
messages: messages,
stream: 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;
}
// 正式な応答を処理します
else if (delta.content) {
if (!isAnswering) {
console.log('\n' + '='.repeat(20) + '完全な応答' + '='.repeat(20) + '\n');
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
} catch (error) {
console.error('エラー:', error);
}
}
main();
HTTP
サンプルコード
curl --location 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "qvq-max",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"
}
},
{
"type": "text",
"text": "この問題を解いてください"
}
]
}
],
"stream":true,
"stream_options":{"include_usage":true}
}'
DashScope
Python
サンプルコード
import os
import dashscope
from dashscope import MultiModalConversation
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
messages = [
{
"role": "user",
"content": [
{"image": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"},
{"text": "この問題を解いてください。"}
]
}
]
response = MultiModalConversation.call(
# 環境変数が構成されていない場合は、Model Studio API キーに置き換えます。api_key="sk-xxx"
api_key=os.getenv('DASHSCOPE_API_KEY'),
model="qvq-max", # 例として qvq-max を使用していますが、必要に応じて他のモデル名に置き換えることができます
messages=messages,
stream=True,
)
# 完全な思考プロセスを定義します
reasoning_content = ""
# 完全な応答を定義します
answer_content = ""
# 思考プロセスが終了し、応答が開始されたかどうかを判断します
is_answering = False
print("=" * 20 + "推論プロセス" + "=" * 20)
for chunk in response:
# 思考プロセスと応答の両方が空の場合は、無視します
message = chunk.output.choices[0].message
reasoning_content_chunk = message.get("reasoning_content", None)
if (chunk.output.choices[0].message.content == [] and
reasoning_content_chunk == ""):
pass
else:
# 現在のチャンクが思考プロセスである場合
if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []:
print(chunk.output.choices[0].message.reasoning_content, end="")
reasoning_content += chunk.output.choices[0].message.reasoning_content
# 現在のチャンクが応答である場合
elif chunk.output.choices[0].message.content != []:
if not is_answering:
print("\n" + "=" * 20 + "完全な応答" + "=" * 20)
is_answering = True
print(chunk.output.choices[0].message.content[0]["text"], end="")
answer_content += chunk.output.choices[0].message.content[0]["text"]
# 完全な思考プロセスと完全な応答を出力する必要がある場合は、次のコードのコメントを外します
# print("=" * 20 + "完全な推論プロセス" + "=" * 20 + "\n")
# print(f"{reasoning_content}")
# print("=" * 20 + "完全な応答" + "=" * 20 + "\n")
# print(f"{answer_content}")
Java
サンプルコード
// dashscope SDK バージョン >= 2.19.0
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.exception.InputRequiredException;
import java.lang.System;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
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(MultiModalConversationResult message) {
String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
String reasoning = Objects.isNull(re)?"":re; // デフォルト値
List> content = message.getOutput().getChoices().get(0).getMessage().getContent();
if (!reasoning.isEmpty()) {
reasoningContent.append(reasoning);
if (isFirstPrint) {
System.out.println("====================推論プロセス====================");
isFirstPrint = false;
}
System.out.print(reasoning);
}
if (Objects.nonNull(content) && !content.isEmpty()) {
Object text = content.get(0).get("text");
finalContent.append(content.get(0).get("text"));
if (!isFirstPrint) {
System.out.println("\n====================完全な応答====================");
isFirstPrint = true;
}
System.out.print(text);
}
}
public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) {
return MultiModalConversationParam.builder()
// 環境変数が構成されていない場合は、Model Studio API キーに置き換えます。.apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// 例として qvq-max を使用していますが、必要に応じて他のモデル名に置き換えることができます
.model("qvq-max")
.messages(Arrays.asList(Msg))
.incrementalOutput(true)
.build();
}
public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg)
throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException {
MultiModalConversationParam param = buildMultiModalConversationParam(Msg);
Flowable result = conv.streamCall(param);
result.blockingForEach(message -> {
handleGenerationResult(message);
});
}
public static void main(String[] args) {
try {
MultiModalConversation conv = new MultiModalConversation();
MultiModalMessage userMsg = MultiModalMessage.builder()
.role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("image", "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"),
Collections.singletonMap("text", "この問題を解いてください")))
.build();
streamCallWithMessage(conv, userMsg);
// 最終結果を出力します
// if (reasoningContent.length() > 0) {
// System.out.println("\n====================完全な応答====================");
// System.out.println(finalContent.toString());
// }
} catch (ApiException | NoApiKeyException | UploadFileException | InputRequiredException e) {
logger.error("例外が発生しました:{}", e.getMessage());
}
System.exit(0);
}
}
HTTP
サンプルコード
curl
curl -X POST https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'X-DashScope-SSE: enable' \
-d '{
"model": "qvq-max",
"input":{
"messages":[
{
"role": "user",
"content": [
{"image": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"},
{"text": "この問題を解いてください"}
]
}
]
}
}'
複数ラウンドの会話
デフォルトでは、QVQ API は会話履歴を保存しません。 複数ラウンドの会話機能により、モデルは過去のやり取りを「記憶」する機能を備え、フォローアップの質問や情報収集などのシナリオに対応できます。 QVQ から reasoning_content
と content
を受け取ります。 {'role': 'assistant', 'content': 連結されたストリーミング出力コンテンツ}
を使用して、コンテキストに content
を含めるだけです。 reasoning_content
は必須ではありません。
OpenAI
OpenAI SDK または OpenAI 互換の HTTP メソッドを介して複数ラウンドの会話を実装します。
Python
サンプルコード
from openai import OpenAI
import os
# OpenAI クライアントを初期化します
client = OpenAI(
# 環境変数が構成されていない場合は、Model Studio API キーに置き換えます。api_key="sk-xxx"
api_key = os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
)
messages = [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"
},
},
{"type": "text", "text": "この問題を解いてください"},
],
}
]
conversation_idx = 1
while True:
reasoning_content = "" # 完全な思考プロセスを定義します
answer_content = "" # 完全な応答を定義します
is_answering = False # 思考プロセスが終了し、応答が開始されたかどうかを判断します
print("="*20+f"ラウンド {conversation_idx}"+"="*20)
conversation_idx += 1
# チャット補完リクエストを作成します
completion = client.chat.completions.create(
model="qvq-max", # 例として qvq-max を使用していますが、必要に応じて他のモデル名に置き換えることができます
messages=messages,
stream=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})
messages.append({
"role": "user",
"content": [
{
"type": "text",
"text": input("\nメッセージを入力してください:")
}
]
})
print("\n")
# print("=" * 20 + "完全な推論プロセス" + "=" * 20 + "\n")
# print(reasoning_content)
# print("=" * 20 + "完全な応答" + "=" * 20 + "\n")
# print(answer_content)
Node.js
サンプルコード
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({
apiKey: process.env.DASHSCOPE_API_KEY, // 環境変数から読み取ります
baseURL: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1'
});
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"
},
},
{"type": "text", "text": "この問題を解いてください"},
],
}
];
let conversationIdx = 1;
async function main() {
while (true) {
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
console.log("=".repeat(20) + `ラウンド ${conversationIdx}` + "=".repeat(20));
conversationIdx++;
// 状態をリセットします
reasoningContent = '';
answerContent = '';
isAnswering = false;
try {
const stream = await openai.chat.completions.create({
model: 'qvq-max',
messages: messages,
stream: 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 });
const userInput = await rl.question("メッセージを入力してください:");
messages.push({"role": "user", "content":userInput});
console.log("\n");
} catch (error) {
console.error('エラー:', error);
}
}
}
// プログラムを開始します
main().catch(console.error);
HTTP
サンプルコード
curl
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "qvq-max",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"
}
},
{
"type": "text",
"text": "この問題を解いてください"
}
]
},
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "直方体:表面積は 52、体積は 24 です。立方体:表面積は 54、体積は 27 です。"
}
]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "三角形の面積の公式は何ですか?"
}
]
}
],
"stream":true,
"stream_options":{"include_usage":true}
}'
DashScope
DashScope SDK または HTTP メソッドを介して複数ラウンドの会話を実装します。
Python
サンプルコード
import os
import dashscope
from dashscope import MultiModalConversation
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
messages = [
{
"role": "user",
"content": [
{"image": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"},
{"text": "この問題を解いてください"}
]
}
]
conversation_idx = 1
while True:
print("=" * 20 + f"ラウンド {conversation_idx}" + "=" * 20)
conversation_idx += 1
response = MultiModalConversation.call(
# 環境変数が構成されていない場合は、Model Studio API キーに置き換えます。api_key="sk-xxx"
api_key=os.getenv('DASHSCOPE_API_KEY'),
model="qvq-max", # 例として qvq-max を使用していますが、必要に応じて他のモデル名に置き換えることができます
messages=messages,
stream=True,
)
# 完全な思考プロセスを定義します
reasoning_content = ""
# 完全な応答を定義します
answer_content = ""
# 思考プロセスが終了し、応答が開始されたかどうかを判断します
is_answering = False
print("=" * 20 + "推論プロセス" + "=" * 20)
for chunk in response:
# 思考プロセスと応答の両方が空の場合は、無視します
message = chunk.output.choices[0].message
reasoning_content_chunk = message.get("reasoning_content", None)
if (chunk.output.choices[0].message.content == [] and
reasoning_content_chunk == ""):
pass
else:
# 現在のチャンクが思考プロセスである場合
if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []:
print(chunk.output.choices[0].message.reasoning_content, end="")
reasoning_content += chunk.output.choices[0].message.reasoning_content
# 現在のチャンクが応答である場合
elif chunk.output.choices[0].message.content != []:
if not is_answering:
print("\n" + "=" * 20 + "完全な応答" + "=" * 20)
is_answering = True
print(chunk.output.choices[0].message.content[0]["text"], end="")
answer_content += chunk.output.choices[0].message.content[0]["text"]
messages.append({"role": "assistant", "content": answer_content})
messages.append({
"role": "user",
"content": [
{
"type": "text",
"text": input("\nメッセージを入力してください:")
}
]
})
print("\n")
# 完全な思考プロセスと完全な応答を出力する必要がある場合は、次のコードのコメントを外します
# print("=" * 20 + "完全な推論プロセス" + "=" * 20 + "\n")
# print(f"{reasoning_content}")
# print("=" * 20 + "完全な応答" + "=" * 20 + "\n")
# print(f"{answer_content}")
Java
サンプルコード
// dashscope SDK バージョン >= 2.19.0
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.exception.InputRequiredException;
import java.lang.System;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
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(MultiModalConversationResult message) {
String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
String reasoning = Objects.isNull(re)?"":re; // デフォルト値
List> content = message.getOutput().getChoices().get(0).getMessage().getContent();
if (!reasoning.isEmpty()) {
reasoningContent.append(reasoning);
if (isFirstPrint) {
System.out.println("====================推論プロセス====================");
isFirstPrint = false;
}
System.out.print(reasoning);
}
if (Objects.nonNull(content) && !content.isEmpty()) {
Object text = content.get(0).get("text");
finalContent.append(content.get(0).get("text"));
if (!isFirstPrint) {
System.out.println("\n====================完全な応答====================");
isFirstPrint = true;
}
System.out.print(text);
}
}
public static MultiModalConversationParam buildMultiModalConversationParam(List Msg) {
return MultiModalConversationParam.builder()
// 環境変数が構成されていない場合は、Model Studio API キーに置き換えます。.apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// 例として qvq-max を使用していますが、必要に応じて他のモデル名に置き換えることができます
.model("qvq-max")
.messages(Msg)
.incrementalOutput(true)
.build();
}
public static void streamCallWithMessage(MultiModalConversation conv, List Msg)
throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException {
MultiModalConversationParam param = buildMultiModalConversationParam(Msg);
Flowable result = conv.streamCall(param);
result.blockingForEach(message -> {
handleGenerationResult(message);
});
}
public static void main(String[] args) {
try {
MultiModalConversation conv = new MultiModalConversation();
MultiModalMessage userMsg1 = MultiModalMessage.builder()
.role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("image", "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"),
Collections.singletonMap("text", "この問題を解いてください")))
.build();
MultiModalMessage AssistantMsg = MultiModalMessage.builder()
.role(Role.ASSISTANT.getValue())
.content(Arrays.asList(Collections.singletonMap("text", "直方体:表面積は 52、体積は 24 です。立方体:表面積は 54、体積は 27 です。")))
.build();
MultiModalMessage userMsg2 = MultiModalMessage.builder()
.role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("text", "三角形の面積の公式は何ですか?")))
.build();
List Msg = Arrays.asList(userMsg1,AssistantMsg,userMsg2);
streamCallWithMessage(conv, Msg);
// 最終結果を出力します
// if (reasoningContent.length() > 0) {
// System.out.println("\n====================完全な応答====================");
// System.out.println(finalContent.toString());
// }
} catch (ApiException | NoApiKeyException | UploadFileException | InputRequiredException e) {
logger.error("例外が発生しました:{}", e.getMessage());
}
System.exit(0);
}
}
HTTP
サンプルコード
curl
curl -X POST https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'X-DashScope-SSE: enable' \
-d '{
"model": "qvq-max",
"input":{
"messages":[
{
"role": "user",
"content": [
{"image": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"},
{"text": "この問題を解いてください"}
]
},
{
"role": "assistant",
"content": [
{"text": "直方体:表面積は 52、体積は 24 です。立方体:表面積は 54、体積は 27 です。"}
]
},
{
"role": "user",
"content": [
{"text": "三角形の面積の公式は何ですか?"}
]
}
]
}
}'
複数画像入力
QVQ は 1 回のリクエストで複数の画像を処理でき、モデルはそれらすべてに基づいて応答します。 画像は URL またはローカルファイル、あるいはその両方として入力できます。 サンプルコードは URL を使用しています。
入力画像の合計トークン数は、モデルの最大入力数未満である必要があります。 画像枚数制限 に基づいて、画像の最大枚数を計算してください。
OpenAI
Python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
reasoning_content = "" # 思考プロセス全体を定義
answer_content = "" # 完全な応答を定義
is_answering = False # 思考プロセスが終了し、応答が開始されたかどうかを判断
completion = client.chat.completions.create(
model="qvq-max",
messages=[
{"role": "user", "content": [
# 最初の画像リンク。ローカルファイルを渡す場合は、url 値を画像の Base64 エンコード形式に置き換えます
{"type": "image_url", "image_url": {
"url": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"}, },
# 2 番目の画像リンク。ローカルファイルを渡す場合は、url 値を画像の Base64 エンコード形式に置き換えます
{"type": "image_url",
"image_url": {"url": "https://img.alicdn.com/imgextra/i1/O1CN01ukECva1cisjyK6ZDK_!!6000000003635-0-tps-1500-1734.jpg"}, },
{"type": "text", "text": "最初の画像の質問に答え、次に 2 番目の画像の記事を解釈してください。"},
],
}
],
stream=True,
# 最後のチャンクでトークンの使用状況を返すには、次のコメントを外します
# stream_options={
# "include_usage": True
# }
)
print("\n" + "=" * 20 + "Reasoning Process" + "=" * 20 + "\n")
for chunk in completion:
# chunk.choices が空の場合は、使用状況を出力します
if not chunk.choices:
print("\nUsage:")
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 + "Complete Response" + "=" * 20 + "\n")
is_answering = True
# 応答プロセスを出力
print(delta.content, end='', flush=True)
answer_content += delta.content
# print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n")
# print(reasoning_content)
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(answer_content)
Node.js
import OpenAI from "openai";
import process from 'process';
// openai クライアントを初期化
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY, // 環境変数から読み込み
baseURL: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1'
});
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [
{role: "user",content: [
// 最初の画像リンク。ローカルファイルを渡す場合は、url 値を画像の Base64 エンコード形式に置き換えます
{type: "image_url",image_url: {"url": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"}},
// 2 番目の画像リンク。ローカルファイルを渡す場合は、url 値を画像の Base64 エンコード形式に置き換えます
{type: "image_url",image_url: {"url": "https://img.alicdn.com/imgextra/i1/O1CN01ukECva1cisjyK6ZDK_!!6000000003635-0-tps-1500-1734.jpg"}},
{type: "text", text: "最初の画像の質問に答え、次に 2 番目の画像の記事を解釈してください。" },
]}]
async function main() {
try {
const stream = await openai.chat.completions.create({
model: 'qvq-max',
messages: messages,
stream: true
});
console.log('\n' + '='.repeat(20) + 'Reasoning Process' + '='.repeat(20) + '\n');
for await (const chunk of stream) {
if (!chunk.choices?.length) {
console.log('\nUsage:');
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;
}
// 正式な応答を処理
else if (delta.content) {
if (!isAnswering) {
console.log('\n' + '='.repeat(20) + 'Complete Response' + '='.repeat(20) + '\n');
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
} catch (error) {
console.error('Error:', error);
}
}
main();
curl
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "qvq-max",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"
}
},
{
"type": "image_url",
"image_url": {
"url": "https://img.alicdn.com/imgextra/i1/O1CN01ukECva1cisjyK6ZDK_!!6000000003635-0-tps-1500-1734.jpg"
}
},
{
"type": "text",
"text": "最初の画像の質問に答え、次に 2 番目の画像の記事を解釈してください。"
}
]
}
],
"stream":true,
"stream_options":{"include_usage":true}
}'
DashScope
Python
import os
import dashscope
from dashscope import MultiModalConversation
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
messages = [
{
"role": "user",
"content": [
# 最初の画像リンク。ローカルファイルを渡す場合は、画像のBase64エンコード形式に置き換えてください。
{"image": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"},
# 2 番目の画像リンク。ローカルファイルを渡す場合は、画像のBase64エンコード形式に置き換えてください。
{"image": "https://img.alicdn.com/imgextra/i1/O1CN01ukECva1cisjyK6ZDK_!!6000000003635-0-tps-1500-1734.jpg"},
{"text": "最初の画像の質問に答え、次に 2 番目の画像の記事を解釈してください。"}
]
}
]
response = MultiModalConversation.call(
# 環境変数が設定されていない場合は、Model Studio API キーに置き換えてください: api_key="sk-xxx"
api_key=os.getenv('DASHSCOPE_API_KEY'),
model="qvq-max", # qvq-max を例として使用していますが、必要に応じて他のモデル名に置き換えることができます
messages=messages,
stream=True,
)
# 思考プロセス全体を定義
reasoning_content = ""
# 完全な応答を定義
answer_content = ""
# 思考プロセスが終了し、応答が開始されたかどうかを判断
is_answering = False
print("=" * 20 + "Reasoning Process" + "=" * 20)
for chunk in response:
# 思考プロセスと応答の両方が空の場合は無視します
message = chunk.output.choices[0].message
reasoning_content_chunk = message.get("reasoning_content", None)
if (chunk.output.choices[0].message.content == [] and
reasoning_content_chunk == ""):
pass
else:
# 現在のものが思考プロセスである場合
if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []:
print(chunk.output.choices[0].message.reasoning_content, end="")
reasoning_content += chunk.output.choices[0].message.reasoning_content
# 現在のものが応答である場合
elif chunk.output.choices[0].message.content != []:
if not is_answering:
print("\n" + "=" * 20 + "Complete Response" + "=" * 20)
is_answering = True
print(chunk.output.choices[0].message.content[0]["text"], end="")
answer_content += chunk.output.choices[0].message.content[0]["text"]
# 完全な思考プロセスと完全な応答を出力する必要がある場合は、次のコードのコメントを外してください
# print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n")
# print(f"{reasoning_content}")
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(f"{answer_content}")
Java
// dashscope SDK version >= 2.19.0
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.exception.InputRequiredException;
import java.lang.System;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
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(MultiModalConversationResult message) {
String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
String reasoning = Objects.isNull(re)?"":re; // デフォルト値
List> content = message.getOutput().getChoices().get(0).getMessage().getContent();
if (!reasoning.isEmpty()) {
reasoningContent.append(reasoning);
if (isFirstPrint) {
System.out.println("====================Reasoning Process====================");
isFirstPrint = false;
}
System.out.print(reasoning);
}
if (Objects.nonNull(content) && !content.isEmpty()) {
Object text = content.get(0).get("text");
finalContent.append(text);
if (!isFirstPrint) {
System.out.println("\n====================Complete Response====================");
isFirstPrint = true;
}
System.out.print(text);
}
}
public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) {
return MultiModalConversationParam.builder()
// 環境変数が設定されていない場合は、Model Studio API キーに置き換えてください:.apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// qvq-max を例として使用していますが、必要に応じて他のモデル名に置き換えることができます
.model("qvq-max")
.messages(Arrays.asList(Msg))
.incrementalOutput(true)
.build();
}
public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg)
throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException {
MultiModalConversationParam param = buildMultiModalConversationParam(Msg);
Flowable result = conv.streamCall(param);
result.blockingForEach(message -> {
handleGenerationResult(message);
});
}
public static void main(String[] args) {
try {
MultiModalConversation conv = new MultiModalConversation();
MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
.content(Arrays.asList(
// 最初の画像リンク
Collections.singletonMap("image", "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241022/emyrja/dog_and_girl.jpeg"),
// ローカル画像を使用する場合は、以下の行のコメントを外してください。
// new HashMap(){{put("image", filePath);}},
// 2 番目の画像リンク
Collections.singletonMap("image", "https://dashscope.oss-cn-beijing.aliyuncs.com/images/tiger.png"),
// 3 番目の画像リンク
Collections.singletonMap("image", "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/hbygyo/rabbit.jpg"),
Collections.singletonMap("text", "これらの画像は何を描写していますか?"))).build();
streamCallWithMessage(conv, userMessage);
// 最終結果を出力
// if (reasoningContent.length() > 0) {
// System.out.println("\n====================Complete Response====================");
// System.out.println(finalContent.toString());
// }
} catch (ApiException | NoApiKeyException | UploadFileException | InputRequiredException e) {
logger.error("例外が発生しました: {}", e.getMessage());
}
System.exit(0);
}
}
curl
curl --location 'https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
-H 'X-DashScope-SSE: enable' \
--data '{
"model": "qvq-max",
"input":{
"messages":[
{
"role": "user",
"content": [
{"image": "https://img.alicdn.com/imgextra/i1/O1CN01gDEY8M1W114Hi3XcN_!!6000000002727-0-tps-1024-406.jpg"},
{"image": "https://img.alicdn.com/imgextra/i1/O1CN01ukECva1cisjyK6ZDK_!!6000000003635-0-tps-1500-1734.jpg"},
{"text": "最初の画像の質問に答え、次に 2 番目の画像の記事を解釈してください。"}
]
}
]
}
}'
動画理解
画像リストまたは動画ファイルとして動画を入力します。
画像リスト
最低 4 枚の画像、最大 512 枚の画像。
画像シーケンス URL のサンプルコード。ローカル動画を渡すには、ローカルファイルの使用 (Base64 エンコード) をご参照ください。
OpenAI
Python
import os
from openai import OpenAI
client = OpenAI(
# 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
reasoning_content = "" # 完全な思考プロセスを定義する
answer_content = "" # 完全な応答を定義する
is_answering = False # 思考プロセスが終了し、応答が開始されたかどうかを判断する
completion = client.chat.completions.create(
model="qvq-max",
messages=[{"role": "user","content": [
# 画像リストを渡す場合、ユーザーメッセージの "type" パラメーターは "video" です
# OpenAI SDK を使用する場合、画像シーケンスはデフォルトで 0.5 秒間隔で動画から抽出され、変更はサポートされていません。フレーム抽出頻度をカスタマイズする必要がある場合は、DashScope SDK を使用してください。
{"type": "video","video": [
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg"]},
{"type": "text","text": "この動画の具体的なプロセスを説明してください"},
]}],
stream=True,
# 最後のチャンクでトークンの使用状況を返すには、以下をコメント解除します
# stream_options={
# "include_usage": True
# }
)
print("\n" + "=" * 20 + "Reasoning Process" + "=" * 20 + "\n")
for chunk in completion:
# chunk.choices が空の場合、使用状況を出力します
if not chunk.choices:
print("\nUsage:")
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 + "Complete Response" + "=" * 20 + "\n")
is_answering = True
# 応答プロセスを出力する
print(delta.content, end='', flush=True)
answer_content += delta.content
# print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n")
# print(reasoning_content)
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(answer_content)
Node.js
import OpenAI from "openai";
import process from 'process';
// openai クライアントを初期化する
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY, // 環境変数から読み取る
baseURL: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1'
});
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [{
role: "user",
content: [
{
// 画像リストを渡す場合、ユーザーメッセージの "type" パラメーターは "video" です
// OpenAI SDK を使用する場合、画像シーケンスはデフォルトで 0.5 秒間隔でビデオから抽出され、変更はサポートされていません。フレーム抽出頻度をカスタマイズする必要がある場合は、DashScope SDK を使用してください。
type: "video",
video: [
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg"
]
},
{
type: "text",
text: "このビデオの具体的なプロセスを説明してください"
}
]
}]
async function main() {
try {
const stream = await openai.chat.completions.create({
model: 'qvq-max',
messages: messages,
stream: true
});
console.log('\n' + '='.repeat(20) + 'Reasoning Process' + '='.repeat(20) + '\n');
for await (const chunk of stream) {
if (!chunk.choices?.length) {
console.log('\nUsage:');
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;
}
// 正式な応答を処理する
else if (delta.content) {
if (!isAnswering) {
console.log('\n' + '='.repeat(20) + 'Complete Response' + '='.repeat(20) + '\n');
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
} catch (error) {
console.error('Error:', error);
}
}
main();
HTTP
curl
curl -X POST https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "qvq-max",
"messages": [{"role": "user",
"content": [{"type": "video",
"video": ["https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg"]},
{"type": "text",
"text": "このビデオの具体的なプロセスを説明してください"}]}],
"stream":true,
"stream_options":{"include_usage":true}
}'
DashScope
Python
import os
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
messages = [{"role": "user",
"content": [
{"video":["https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg"],
"fps":2}, # qvq を使用する場合、fps パラメーターを指定できます。これは、画像シーケンスが 1/fps 秒間隔でビデオから抽出されることを示します。
{"text": "このビデオの具体的なプロセスを説明してください"}]}]
response = dashscope.MultiModalConversation.call(
# 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
model='qvq-max',
messages=messages,
stream=True
)
# 完全な思考プロセスを定義する
reasoning_content = ""
# 完全な応答を定義する
answer_content = ""
# 思考プロセスが終了し、応答が開始されたかどうかを判断する
is_answering = False
print("=" * 20 + "Reasoning Process" + "=" * 20)
for chunk in response:
# 思考プロセスと応答の両方が空の場合は無視する
message = chunk.output.choices[0].message
reasoning_content_chunk = message.get("reasoning_content", None)
if (chunk.output.choices[0].message.content == [] and
reasoning_content_chunk == ""):
pass
else:
# 現在が思考プロセスである場合
if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []:
print(chunk.output.choices[0].message.reasoning_content, end="")
reasoning_content += chunk.output.choices[0].message.reasoning_content
# 現在が応答である場合
elif chunk.output.choices[0].message.content != []:
if not is_answering:
print("\n" + "=" * 20 + "Complete Response" + "=" * 20)
is_answering = True
print(chunk.output.choices[0].message.content[0]["text"], end="")
answer_content += chunk.output.choices[0].message.content[0]["text"]
# 完全な思考プロセスと完全な応答を出力する必要がある場合は、以下のコードのコメントを解除します
# print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n")
# print(f"{reasoning_content}")
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(f"{answer_content}")
Java
// dashscope SDK バージョン >= 2.19.0
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.exception.InputRequiredException;
import java.lang.System;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
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(MultiModalConversationResult message) {
String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
String reasoning = Objects.isNull(re)?"":re; // デフォルト値
List> content = message.getOutput().getChoices().get(0).getMessage().getContent();
if (!reasoning.isEmpty()) {
reasoningContent.append(reasoning);
if (isFirstPrint) {
System.out.println("====================Reasoning Process====================");
isFirstPrint = false;
}
System.out.print(reasoning);
}
if (Objects.nonNull(content) && !content.isEmpty()) {
Object text = content.get(0).get("text");
finalContent.append(text);
if (!isFirstPrint) {
System.out.println("\n====================Complete Response====================");
isFirstPrint = true;
}
System.out.print(text);
}
}
public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) {
return MultiModalConversationParam.builder()
// 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: .apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// qvq-max を例として使用していますが、必要に応じて他のモデル名に置き換えることができます
.model("qvq-max")
.messages(Arrays.asList(Msg))
.incrementalOutput(true)
.build();
}
public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg)
throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException {
MultiModalConversationParam param = buildMultiModalConversationParam(Msg);
Flowable result = conv.streamCall(param);
result.blockingForEach(message -> {
handleGenerationResult(message);
});
}
public static void main(String[] args) {
try {
MultiModalConversation conv = new MultiModalConversation();
Map params = Map.of(
"video", Arrays.asList("https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg")
);
MultiModalMessage userMessage = MultiModalMessage.builder()
.role(Role.USER.getValue())
.content(Arrays.asList(
params,
Collections.singletonMap("text", "このビデオの具体的なプロセスを説明してください")))
.build();
streamCallWithMessage(conv, userMessage);
// 最終結果を出力する
// if (reasoningContent.length() > 0) {
// System.out.println("\n====================Complete Response====================");
// System.out.println(finalContent.toString());
// }
} catch (ApiException | NoApiKeyException | UploadFileException | InputRequiredException e) {
logger.error("例外が発生しました: {}", e.getMessage());
}
System.exit(0);
}}
HTTP
curl
curl -X POST https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'X-DashScope-SSE: enable' \
-d '{
"model": "qvq-max",
"input": {
"messages": [
{
"role": "user",
"content": [
{
"video": [
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/xzsgiz/football1.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/tdescd/football2.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/zefdja/football3.jpg",
"https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20241108/aedbqh/football4.jpg"
]
},
{
"text": "このビデオの具体的なプロセスを説明してください"
}
]
}
]
}
}'
動画ファイル
サイズ:
動画 URL の場合:最大 1 GB。
ローカルファイルの場合:OpenAI SDK を使用する場合、Base64 エンコードされた動画は 10 MB 未満である必要があります。ローカルファイルの使用 (Base64 エンコード) をご参照ください。
形式:MP4、AVI、MKV、MOV、FLV、WMV。
再生時間:2 秒から 10 分。
寸法:制限なし。ただし、動画ファイルは約 600,000 ピクセルに調整されます。動画の寸法が大きくても、理解効果は向上しません。
現在、動画ファイルの音声理解はサポートされていません。
次のサンプルコードは動画 URL 用です。ローカル動画を渡すには、ローカルファイルの使用 (Base64 エンコード) をご参照ください。
OpenAI
Python
import os
from openai import OpenAI
client = OpenAI(
# 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx"
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
reasoning_content = "" # 完全な思考プロセスを定義する
answer_content = "" # 完全な応答を定義する
is_answering = False # 思考プロセスが終了し、応答が開始されたかどうかを判断する
completion = client.chat.completions.create(
model="qvq-max",
messages=[{"role": "user","content": [
# 画像リストを渡す場合、ユーザーメッセージの "type" パラメーターは "video" です
# OpenAI SDK を使用する場合、画像シーケンスはデフォルトで 0.5 秒間隔でビデオから抽出され、変更はサポートされていません。フレーム抽出頻度をカスタマイズする必要がある場合は、DashScope SDK を使用してください。
{"type": "video_url","video_url":{"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250328/eepdcq/phase_change_480p.mov"} },
{"type": "text","text": "これはビデオの冒頭部分です。分析して、ビデオがどのような知識を説明しているか推測してください。"},
]}],
stream=True,
# 最後のチャンクでトークンの使用状況を返すには、以下をコメント解除します
# stream_options={
# "include_usage": True
# }
)
print("\n" + "=" * 20 + "Reasoning Process" + "=" * 20 + "\n")
for chunk in completion:
# chunk.choices が空の場合、使用状況を出力します
if not chunk.choices:
print("\nUsage:")
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 + "Complete Response" + "=" * 20 + "\n")
is_answering = True
# 応答プロセスを出力する
print(delta.content, end='', flush=True)
answer_content += delta.content
# print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n")
# print(reasoning_content)
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(answer_content)
Node.js
import OpenAI from "openai";
import process from 'process';
// openai クライアントを初期化する
const openai = new OpenAI({
apiKey: process.env.DASHSCOPE_API_KEY, // 環境変数から読み取る
baseURL: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1'
});
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [
{
role: "user",
content: [
// OpenAI SDK を使用する場合、画像シーケンスはデフォルトで 0.5 秒間隔でビデオから抽出され、変更はサポートされていません。フレーム抽出頻度をカスタマイズする必要がある場合は、DashScope SDK を使用してください。
{ type: "video_url", video_url: { "url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250328/eepdcq/phase_change_480p.mov" } },
{ type: "text", text: "これはビデオの冒頭部分です。分析して、ビデオがどのような知識を説明しているか推測してください。" },
]
}]
async function main() {
try {
const stream = await openai.chat.completions.create({
model: 'qvq-max',
messages: messages,
stream: true
});
console.log('\n' + '='.repeat(20) + 'Reasoning Process' + '='.repeat(20) + '\n');
for await (const chunk of stream) {
if (!chunk.choices?.length) {
console.log('\nUsage:');
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;
}
// 正式な応答を処理する
else if (delta.content) {
if (!isAnswering) {
console.log('\n' + '='.repeat(20) + 'Complete Response' + '='.repeat(20) + '\n');
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
} catch (error) {
console.error('Error:', error);
}
}
main();
HTTP
curl
curl --location 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1/chat/completions' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "qvq-max",
"messages": [
{
"role": "user",
"content": [
{
"type": "video_url",
"video_url": {
"url": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250328/eepdcq/phase_change_480p.mov"
}
},
{
"type": "text",
"text": "これはビデオの冒頭部分です。分析して、ビデオがどのような知識を説明しているか推測してください。"
}
]
}
],
"stream":true,
"stream_options":{"include_usage":true}
}'
DashScope
Python
import os
import dashscope
from dashscope import MultiModalConversation
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
messages = [
{
"role": "user",
"content": [
# fps パラメーターを指定できます。これは、画像シーケンスが 1/fps 秒間隔でビデオから抽出されることを示します。手順については、https://www.alibabacloud.com/help/en/model-studio/use-qwen-by-calling-api?#2ed5ee7377fum をご参照ください。
{"video": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250328/eepdcq/phase_change_480p.mov,"fps":2"},
{"text": "これはビデオの冒頭部分です。分析して、ビデオがどのような知識を説明しているか推測してください。"}
]
}
]
response = MultiModalConversation.call(
# 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx"
api_key=os.getenv('DASHSCOPE_API_KEY'),
model="qvq-max", # qvq-max を例として使用していますが、必要に応じて他のモデル名に置き換えることができます
messages=messages,
stream=True,
)
# 完全な思考プロセスを定義する
reasoning_content = ""
# 完全な応答を定義する
answer_content = ""
# 思考プロセスが終了し、応答が開始されたかどうかを判断する
is_answering = False
print("=" * 20 + "Reasoning Process" + "=" * 20)
for chunk in response:
# 思考プロセスと応答の両方が空の場合は無視する
message = chunk.output.choices[0].message
reasoning_content_chunk = message.get("reasoning_content", None)
if (chunk.output.choices[0].message.content == [] and
reasoning_content_chunk == ""):
pass
else:
# 現在が思考プロセスである場合
if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []:
print(chunk.output.choices[0].message.reasoning_content, end="")
reasoning_content += chunk.output.choices[0].message.reasoning_content
# 現在が応答である場合
elif chunk.output.choices[0].message.content != []:
if not is_answering:
print("\n" + "=" * 20 + "Complete Response" + "=" * 20)
is_answering = True
print(chunk.output.choices[0].message.content[0]["text"], end="")
answer_content += chunk.output.choices[0].message.content[0]["text"]
# 完全な思考プロセスと完全な応答を出力する必要がある場合は、以下のコードのコメントを解除します
# print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n")
# print(f"{reasoning_content}")
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(f"{answer_content}")
Java
// dashscope SDK バージョン >= 2.19.0
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import io.reactivex.Flowable;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.common.MultiModalMessage;
import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.dashscope.exception.InputRequiredException;
import java.lang.System;
import com.alibaba.dashscope.utils.Constants;
public class Main {
static {
Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1";
}
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(MultiModalConversationResult message) {
String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent();
String reasoning = Objects.isNull(re)?"":re; // デフォルト値
List> content = message.getOutput().getChoices().get(0).getMessage().getContent();
if (!reasoning.isEmpty()) {
reasoningContent.append(reasoning);
if (isFirstPrint) {
System.out.println("====================Reasoning Process====================");
isFirstPrint = false;
}
System.out.print(reasoning);
}
if (Objects.nonNull(content) && !content.isEmpty()) {
Object text = content.get(0).get("text");
finalContent.append(content.get(0).get("text"));
if (!isFirstPrint) {
System.out.println("\n====================Complete Response====================");
isFirstPrint = true;
}
System.out.print(text);
}
}
public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) {
return MultiModalConversationParam.builder()
// 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: .apiKey("sk-xxx")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
// qvq-max を例として使用していますが、必要に応じて他のモデル名に置き換えることができます
.model("qvq-max")
.messages(Arrays.asList(Msg))
.incrementalOutput(true)
.build();
}
public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg)
throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException {
MultiModalConversationParam param = buildMultiModalConversationParam(Msg);
Flowable result = conv.streamCall(param);
result.blockingForEach(message -> {
handleGenerationResult(message);
});
}
public static void main(String[] args) {
try {
MultiModalConversation conv = new MultiModalConversation();
MultiModalMessage userMsg = MultiModalMessage.builder()
.role(Role.USER.getValue())
.content(Arrays.asList(Collections.singletonMap("video", "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250328/eepdcq/phase_change_480p.mov"),
Collections.singletonMap("text", "これはビデオの冒頭部分です。分析して、ビデオがどのような知識を説明しているか推測してください。")))
.build();
streamCallWithMessage(conv, userMsg);
// 最終結果を出力する
// if (reasoningContent.length() > 0) {
// System.out.println("\n====================Complete Response====================");
// System.out.println(finalContent.toString());
// }
} catch (ApiException | NoApiKeyException | UploadFileException | InputRequiredException e) {
logger.error("例外が発生しました: {}", e.getMessage());
}
System.exit(0);
}}
HTTP
curl
curl -X POST https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation \
-H "Authorization: Bearer $DASHSCOPE_API_KEY" \
-H 'Content-Type: application/json' \
-H 'X-DashScope-SSE: enable' \
-d '{
"model": "qvq-max",
"input":{
"messages":[
{
"role": "user",
"content": [
{"video": "https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20250328/eepdcq/phase_change_480p.mov"},
{"text": "これはビデオの冒頭部分です。分析して、ビデオがどのような知識を説明しているか推測してください。"}
]
}
]
}
}'
ローカルファイルの使用(Base64 エンコードまたはファイルパス)
ローカルファイルのアップロード方法:
方法 1: ローカルファイルを Base64 形式でエンコードする(OpenAI と DashScope SDK の両方に適用可能)
Base64 エンコードファイルをアップロードするには、次の手順に従います。
方法 2: ファイルパスを直接渡す(DashScope SDK のみ)
プログラミング言語とオペレーティングシステムに基づいてファイルパスを作成するには、以下の表を参照してください。
Base64 エンコードはデータ量を増やし、エンコードされた画像は 10 MB 未満である必要があります。ファイルパスを直接渡す場合は、画像自体が 10 MB 未満である必要があります。ファイルパス方式を使用すると、安定性が向上するため、推奨されます。ただし、小さい画像(1 MB 未満)の場合は、Base64 エンコード方式も許容されます。
画像
ローカルファイル test.jpg を例として使用します。
入力画像の制限事項は、使用上の注意 で確認できます。画像 URL の受け渡しについては、はじめに をご参照ください。
OpenAI
Python
from openai import OpenAI
import os
import base64
# base 64 エンコード形式
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode("utf-8")
# xxxx/test.jpg をローカル画像の絶対パスに置き換えます
base64_image = encode_image("xxx/test.jpg")
# OpenAI クライアントを初期化します
client = OpenAI(
# 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx"
api_key = os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
)
reasoning_content = "" # 推論プロセス全体を定義します
answer_content = "" # 完全な応答を定義します
is_answering = False # 推論プロセスが終了し、応答が開始されたかどうかを判断します
# チャット補完リクエストを作成します
completion = client.chat.completions.create(
model="qvq-max", # 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
# Base64 を渡す場合は、画像形式 (image/{format}) がサポートされている画像リストの Content Type と一致している必要があることに注意してください。 "f" は文字列フォーマットメソッドです。
# PNG 画像: f"data:image/png;base64,{base64_image}"
# JPEG 画像: f"data:image/jpeg;base64,{base64_image}"
# WEBP 画像: f"data:image/webp;base64,{base64_image}"
"image_url": {"url": f"data:image/png;base64,{base64_image}"},
},
{"type": "text", "text": "この問題を解決するにはどうすればよいですか?"},
],
}
],
stream=True,
# 最後のチャンクでトークンの使用状況を返すには、次のコメントを外します
# stream_options={
# "include_usage": True
# }
)
print("\n" + "=" * 20 + "Reasoning Process" + "=" * 20 + "\n")
for chunk in completion:
# chunk.choices が空の場合は、使用状況を出力します
if not chunk.choices:
print("\nUsage:")
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 + "Complete Response" + "=" * 20 + "\n")
is_answering = True
# 応答プロセスを出力します
print(delta.content, end='', flush=True)
answer_content += delta.content
# print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n")
# print(reasoning_content)
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(answer_content)
Node.js
import OpenAI from "openai";
import { readFileSync } from 'fs';
const openai = new OpenAI(
{
// 環境変数が設定されていない場合は、次の行を Model Studio API キーに置き換えます: apiKey: "sk-xxx"
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
}
);
const encodeImage = (imagePath) => {
const imageFile = readFileSync(imagePath);
return imageFile.toString('base64');
};
// xxxx/test.jpg をローカル画像の絶対パスに置き換えます
const base64Image = encodeImage("xxx/test.jpg")
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [
{
role: "user",
content: [
{ type: "image_url", image_url: {"url": `data:image/png;base64,${base64Image}`} },
{ type: "text", text: "この問題を解決してください" },
]
}]
async function main() {
try {
const stream = await openai.chat.completions.create({
model: 'qvq-max',
messages: messages,
stream: true
});
console.log('\n' + '='.repeat(20) + 'Reasoning Process' + '='.repeat(20) + '\n');
for await (const chunk of stream) {
if (!chunk.choices?.length) {
console.log('\nUsage:');
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;
}
// 正式な応答を処理します
else if (delta.content) {
if (!isAnswering) {
console.log('\n' + '='.repeat(20) + 'Complete Response' + '='.repeat(20) + '\n');
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
} catch (error) {
console.error('Error:', error);
}
}
main();
DashScope
Base64 エンコードされたローカルファイルを渡します。
Python
import os import base64 import dashscope dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1' # base 64 エンコード形式 def encode_image(image_path): with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode("utf-8") # xxxx/test.jpg をローカル画像の絶対パスに置き換えます base64_image = encode_image("xxxx/test.jpg") messages = [{'role':'user', 'content': [{'image': f"data:image/jpg;base64,{base64_image}"}, {'text': 'この問題を解決するにはどうすればよいですか?'}]}] response = dashscope.MultiModalConversation.call( # 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx", api_key=os.getenv('DASHSCOPE_API_KEY'), model="qvq-max", # 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます。 messages=messages, stream=True, ) # 推論プロセス全体を定義します reasoning_content = "" # 完全な応答を定義します answer_content = "" # 推論プロセスが終了し、応答が開始されたかどうかを判断します is_answering = False print("=" * 20 + "Reasoning Process" + "=" * 20) for chunk in response: # 推論プロセスと応答の両方が空の場合は無視します message = chunk.output.choices[0].message reasoning_content_chunk = message.get("reasoning_content", None) if (chunk.output.choices[0].message.content == [] and reasoning_content_chunk == ""): pass else: # 現在のものが推論プロセスである場合 if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []: print(chunk.output.choices[0].message.reasoning_content, end="") reasoning_content += chunk.output.choices[0].message.reasoning_content # 現在のものが応答である場合 elif chunk.output.choices[0].message.content != []: if not is_answering: print("\n" + "=" * 20 + "Complete Response" + "=" * 20) is_answering = True print(chunk.output.choices[0].message.content[0]["text"], end="") answer_content += chunk.output.choices[0].message.content[0]["text"] # 推論プロセス全体と完全な応答を出力するには、次のコードのコメントを外します # print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n") # print(f"{reasoning_content}") # print("=" * 20 + "Complete Response" + "=" * 20 + "\n") # print(f"{answer_content}")
Java
// dashscope SDK バージョン >= 2.19.0 import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.NoApiKeyException; import io.reactivex.Flowable; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; import com.alibaba.dashscope.common.MultiModalMessage; import com.alibaba.dashscope.exception.UploadFileException; import com.alibaba.dashscope.exception.InputRequiredException; import java.lang.System; import com.alibaba.dashscope.utils.Constants; public class Main { static { Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1"; } 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 String encodeImageToBase64(String imagePath) throws IOException { Path path = Paths.get(imagePath); byte[] imageBytes = Files.readAllBytes(path); return Base64.getEncoder().encodeToString(imageBytes); } private static void handleGenerationResult(MultiModalConversationResult message) { String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent(); String reasoning = Objects.isNull(re)?"":re; // デフォルト値 List<Map<String, Object>> content = message.getOutput().getChoices().get(0).getMessage().getContent(); if (!reasoning.isEmpty()) { reasoningContent.append(reasoning); if (isFirstPrint) { System.out.println("====================Reasoning Process===================="); isFirstPrint = false; } System.out.print(reasoning); } if (Objects.nonNull(content) && !content.isEmpty()) { Object text = content.get(0).get("text"); finalContent.append(text); if (!isFirstPrint) { System.out.println("\n====================Complete Response===================="); isFirstPrint = true; } System.out.print(text); } } public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) { return MultiModalConversationParam.builder() // 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY"))// // 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます .model("qvq-max") .messages(Arrays.asList(Msg)) .incrementalOutput(true) .build(); } public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg) throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException { MultiModalConversationParam param = buildMultiModalConversationParam(Msg); Flowable<MultiModalConversationResult> result = conv.streamCall(param); result.blockingForEach(message -> { handleGenerationResult(message); }); } public static void main(String[] args) { try { String localPath = "xxx/test.png"; String base64Image = encodeImageToBase64(localPath); MultiModalConversation conv = new MultiModalConversation(); MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue()) .content(Arrays.asList(new HashMap<String, Object>(){{put("image", "data:image/png;base64," + base64Image);}}, new HashMap<String, Object>(){{put("text", "この問題を解決してください");}})).build(); streamCallWithMessage(conv, userMessage); // 最終結果を出力します // if (reasoningContent.length() > 0) { // System.out.println("\n====================Complete Response===================="); // System.out.println(finalContent.toString()); // } } catch (ApiException | NoApiKeyException | UploadFileException | IOException | InputRequiredException e) { logger.error("例外が発生しました: {}", e.getMessage()); } System.exit(0); } }
ファイルパスを直接渡します。詳細については、ファイルパスの作成 をご参照ください。
Python
import os import dashscope dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1' # xxxx/test.jpg をローカル画像の絶対パスに置き換えます local_path = "xxx/test.jpg" image_path = f"file://{local_path}" messages = [{'role':'user', 'content': [{'image': image_path}, {'text': 'この問題を解決してください'}]}] response = dashscope.MultiModalConversation.call( # 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx", api_key=os.getenv('DASHSCOPE_API_KEY'), model="qvq-max", # 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます。 messages=messages, stream=True, ) # 推論プロセス全体を定義します reasoning_content = "" # 完全な応答を定義します answer_content = "" # 推論プロセスが終了し、応答が開始されたかどうかを判断します is_answering = False print("=" * 20 + "Reasoning Process" + "=" * 20) for chunk in response: # 推論プロセスと応答の両方が空の場合は無視します message = chunk.output.choices[0].message reasoning_content_chunk = message.get("reasoning_content", None) if (chunk.output.choices[0].message.content == [] and reasoning_content_chunk == ""): pass else: # 現在のものが推論プロセスである場合 if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []: print(chunk.output.choices[0].message.reasoning_content, end="") reasoning_content += chunk.output.choices[0].message.reasoning_content # 現在のものが応答である場合 elif chunk.output.choices[0].message.content != []: if not is_answering: print("\n" + "=" * 20 + "Complete Response" + "=" * 20) is_answering = True print(chunk.output.choices[0].message.content[0]["text"], end="") answer_content += chunk.output.choices[0].message.content[0]["text"] # 推論プロセス全体と完全な応答を出力するには、次のコードのコメントを外します # print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n") # print(f"{reasoning_content}") # print("=" * 20 + "Complete Response" + "=" * 20 + "\n") # print(f"{answer_content}")
Java
// dashscope SDK バージョン >= 2.19.0 import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.NoApiKeyException; import io.reactivex.Flowable; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; import com.alibaba.dashscope.common.MultiModalMessage; import com.alibaba.dashscope.exception.UploadFileException; import com.alibaba.dashscope.exception.InputRequiredException; import java.lang.System; import com.alibaba.dashscope.utils.Constants; public class Main { static { Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1"; } 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(MultiModalConversationResult message) { String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent(); String reasoning = Objects.isNull(re)?"":re; // デフォルト値 List<Map<String, Object>> content = message.getOutput().getChoices().get(0).getMessage().getContent(); if (!reasoning.isEmpty()) { reasoningContent.append(reasoning); if (isFirstPrint) { System.out.println("====================Reasoning Process===================="); isFirstPrint = false; } System.out.print(reasoning); } if (Objects.nonNull(content) && !content.isEmpty()) { Object text = content.get(0).get("text"); finalContent.append(text); if (!isFirstPrint) { System.out.println("\n====================Complete Response===================="); isFirstPrint = true; } System.out.print(text); } } public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) { return MultiModalConversationParam.builder() // 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY")) // 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます .model("qvq-max") .messages(Arrays.asList(Msg)) .incrementalOutput(true) .build(); } public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg) throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException { MultiModalConversationParam param = buildMultiModalConversationParam(Msg); Flowable<MultiModalConversationResult> result = conv.streamCall(param); result.blockingForEach(message -> { handleGenerationResult(message); }); } public static void main(String[] args) { try { String localPath = "xxx/test.png"; String filePath = "file://"+ localPath; MultiModalConversation conv = new MultiModalConversation(); MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue()) .content(Arrays.asList(new HashMap<String, Object>(){{put("image", filePath);}}, new HashMap<String, Object>(){{put("text", "この問題を解決してください");}})).build(); streamCallWithMessage(conv, userMessage); // 最終結果を出力します // if (reasoningContent.length() > 0) { // System.out.println("\n====================Complete Response===================="); // System.out.println(finalContent.toString()); // } } catch (ApiException | NoApiKeyException | UploadFileException | InputRequiredException e) { logger.error("例外が発生しました: {}", e.getMessage()); } System.exit(0); } }
動画
動画ファイル
ローカルファイル test.mp4 を例として使用します。
OpenAI
Python
from openai import OpenAI
import os
import base64
# base 64 エンコード形式
def encode_video(video_path):
with open(video_path, "rb") as video_file:
return base64.b64encode(video_file.read()).decode("utf-8")
# xxxx/test.mp4 をローカルビデオの絶対パスに置き換えます
base64_video = encode_video("xxx/test.mp4")
# OpenAI クライアントを初期化します
client = OpenAI(
# 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx"
api_key = os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
)
reasoning_content = "" # 推論プロセス全体を定義します
answer_content = "" # 完全な応答を定義します
is_answering = False # 推論プロセスが終了し、応答が開始されたかどうかを判断します
# チャット補完リクエストを作成します
completion = client.chat.completions.create(
model="qvq-max", # 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます
messages=[
{
"role": "user",
"content": [
{
"type": "video_url",
# Base64 エンコードを渡す場合は、video/mp4 をローカルビデオの形式に応じて変更する必要があることに注意してください
"video_url": {"url": f"data:video/mp4;base64,{base64_video}"},
},
{"type": "text", "text": "このビデオは何についてですか?"},
],
}
],
stream=True,
# 最後のチャンクでトークンの使用状況を返すには、次のコメントを外します
# stream_options={
# "include_usage": True
# }
)
print("\n" + "=" * 20 + "Reasoning Process" + "=" * 20 + "\n")
for chunk in completion:
# chunk.choices が空の場合は、使用状況を出力します
if not chunk.choices:
print("\nUsage:")
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 + "Complete Response" + "=" * 20 + "\n")
is_answering = True
# 応答プロセスを出力します
print(delta.content, end='', flush=True)
answer_content += delta.content
# print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n")
# print(reasoning_content)
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(answer_content)
Node.js
import OpenAI from "openai";
import { readFileSync } from 'fs';
const openai = new OpenAI(
{
// 環境変数が設定されていない場合は、次の行を Model Studio API キーに置き換えます: apiKey: "sk-xxx"
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
}
);
const encodeVideo = (videoPath) => {
const videoFile = readFileSync(videoPath);
return videoFile.toString('base64');
};
// xxxx/test.mp4 をローカルビデオの絶対パスに置き換えます
const base64Video = encodeVideo("xxx/test.mp4")
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [
{
role: "user",
content: [
// Base64 エンコードを渡す場合は、video/mp4 をローカルビデオの形式に応じて変更する必要があることに注意してください
{ type: "video_url", video_url: {"url": `data:video/mp4;base64,${base64Video}`} },
{ type: "text", text: "このビデオは何についてですか?" },
]
}]
async function main() {
try {
const stream = await openai.chat.completions.create({
model: 'qvq-max',
messages: messages,
stream: true
});
console.log('\n' + '='.repeat(20) + 'Reasoning Process' + '='.repeat(20) + '\n');
for await (const chunk of stream) {
if (!chunk.choices?.length) {
console.log('\nUsage:');
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;
}
// 正式な応答を処理します
else if (delta.content) {
if (!isAnswering) {
console.log('\n' + '='.repeat(20) + 'Complete Response' + '='.repeat(20) + '\n');
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
} catch (error) {
console.error('Error:', error);
}
}
main();
DashScope
Base64 エンコードされたローカルファイルを渡します。
Python
import base64 import os import dashscope dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1' def encode_video(video_path): with open(video_path, "rb") as video_file: return base64.b64encode(video_file.read()).decode("utf-8") # xxxx/test.mp4 をローカルビデオの絶対パスに置き換えます base64_video = encode_video("xxxx/fruits.mp4") messages = [{'role':'user', 'content': [{'video': f"data:video/mp4;base64,{base64_video}"}, {'text': 'このビデオは何についてですか?'}]}] response = dashscope.MultiModalConversation.call( # 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx", api_key=os.getenv('DASHSCOPE_API_KEY'), model="qvq-max", # 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます。 messages=messages, stream=True, ) # 推論プロセス全体を定義します reasoning_content = "" # 完全な応答を定義します answer_content = "" # 推論プロセスが終了し、応答が開始されたかどうかを判断します is_answering = False print("=" * 20 + "Reasoning Process" + "=" * 20) for chunk in response: # 推論プロセスと応答の両方が空の場合は無視します message = chunk.output.choices[0].message reasoning_content_chunk = message.get("reasoning_content", None) if (chunk.output.choices[0].message.content == [] and reasoning_content_chunk == ""): pass else: # 現在のものが推論プロセスである場合 if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []: print(chunk.output.choices[0].message.reasoning_content, end="") reasoning_content += chunk.output.choices[0].message.reasoning_content # 現在のものが応答である場合 elif chunk.output.choices[0].message.content != []: if not is_answering: print("\n" + "=" * 20 + "Complete Response" + "=" * 20) is_answering = True print(chunk.output.choices[0].message.content[0]["text"], end="") answer_content += chunk.output.choices[0].message.content[0]["text"] # 推論プロセス全体と完全な応答を出力するには、次のコードのコメントを外します # print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n") # print(f"{reasoning_content}") # print("=" * 20 + "Complete Response" + "=" * 20 + "\n") # print(f"{answer_content}")
Java
// dashscope SDK バージョン >= 2.19.0 import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.NoApiKeyException; import io.reactivex.Flowable; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; import com.alibaba.dashscope.common.MultiModalMessage; import com.alibaba.dashscope.exception.UploadFileException; import com.alibaba.dashscope.exception.InputRequiredException; import java.lang.System; import com.alibaba.dashscope.utils.Constants; public class Main { static { Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1"; } 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 String encodeVideoToBase64(String videoPath) throws IOException { Path path = Paths.get(videoPath); byte[] videoBytes = Files.readAllBytes(path); return Base64.getEncoder().encodeToString(videoBytes); } private static void handleGenerationResult(MultiModalConversationResult message) { String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent(); String reasoning = Objects.isNull(re)?"":re; // デフォルト値 List<Map<String, Object>> content = message.getOutput().getChoices().get(0).getMessage().getContent(); if (!reasoning.isEmpty()) { reasoningContent.append(reasoning); if (isFirstPrint) { System.out.println("====================Reasoning Process===================="); isFirstPrint = false; } System.out.print(reasoning); } if (Objects.nonNull(content) && !content.isEmpty()) { Object text = content.get(0).get("text"); finalContent.append(text); if (!isFirstPrint) { System.out.println("\n====================Complete Response===================="); isFirstPrint = true; } System.out.print(text); } } public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) { return MultiModalConversationParam.builder() // 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY"))// // 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます .model("qvq-max") .messages(Arrays.asList(Msg)) .incrementalOutput(true) .build(); } public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg) throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException { MultiModalConversationParam param = buildMultiModalConversationParam(Msg); Flowable<MultiModalConversationResult> result = conv.streamCall(param); result.blockingForEach(message -> { handleGenerationResult(message); }); } public static void main(String[] args) { try { // xxx/test.mp4 をローカル画像の絶対パスに置き換えます String base64Video = encodeVideoToBase64("xxx/test.mp4"); MultiModalConversation conv = new MultiModalConversation(); MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue()) .content(Arrays.asList(new HashMap<String, Object>(){{put("video", "data:video/mp4;base64," + base64Video);}}, new HashMap<String, Object>(){{put("text", "このビデオは何についてですか?");}})).build(); streamCallWithMessage(conv, userMessage); // 最終結果を出力します // if (reasoningContent.length() > 0) { // System.out.println("\n====================Complete Response===================="); // System.out.println(finalContent.toString()); // } } catch (ApiException | NoApiKeyException | UploadFileException | IOException | InputRequiredException e) { logger.error("例外が発生しました: {}", e.getMessage()); } System.exit(0); } }
ファイルパスを直接渡します。詳細については、ファイルパスの作成 をご参照ください。
Python
import os import dashscope dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1' # xxxx/test.mp4 をローカルビデオの絶対パスに置き換えます local_path = "xxx/test.mp4" video_path = f"file://{local_path}" messages = [{'role':'user', 'content': [{'video': video_path}, {'text': 'この問題を解決してください'}]}] response = MultiModalConversation.call( # 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx", api_key=os.getenv('DASHSCOPE_API_KEY'), model="qvq-max", # 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます。 messages=messages, stream=True, ) # 推論プロセス全体を定義します reasoning_content = "" # 完全な応答を定義します answer_content = "" # 推論プロセスが終了し、応答が開始されたかどうかを判断します is_answering = False print("=" * 20 + "Reasoning Process" + "=" * 20) for chunk in response: # 推論プロセスと応答の両方が空の場合は無視します message = chunk.output.choices[0].message reasoning_content_chunk = message.get("reasoning_content", None) if (chunk.output.choices[0].message.content == [] and reasoning_content_chunk == ""): pass else: # 現在のものが推論プロセスである場合 if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []: print(chunk.output.choices[0].message.reasoning_content, end="") reasoning_content += chunk.output.choices[0].message.reasoning_content # 現在のものが応答である場合 elif chunk.output.choices[0].message.content != []: if not is_answering: print("\n" + "=" * 20 + "Complete Response" + "=" * 20) is_answering = True print(chunk.output.choices[0].message.content[0]["text"], end="") answer_content += chunk.output.choices[0].message.content[0]["text"] # 推論プロセス全体と完全な応答を出力するには、次のコードのコメントを外します # print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n") # print(f"{reasoning_content}") # print("=" * 20 + "Complete Response" + "=" * 20 + "\n") # print(f"{answer_content}")
Java
// dashscope SDK バージョン >= 2.19.0 import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.NoApiKeyException; import io.reactivex.Flowable; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; import com.alibaba.dashscope.common.MultiModalMessage; import com.alibaba.dashscope.exception.UploadFileException; import com.alibaba.dashscope.exception.InputRequiredException; import java.lang.System; import com.alibaba.dashscope.utils.Constants; public class Main { static { Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1"; } 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(MultiModalConversationResult message) { String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent(); String reasoning = Objects.isNull(re)?"":re; // デフォルト値 List<Map<String, Object>> content = message.getOutput().getChoices().get(0).getMessage().getContent(); if (!reasoning.isEmpty()) { reasoningContent.append(reasoning); if (isFirstPrint) { System.out.println("====================Reasoning Process===================="); isFirstPrint = false; } System.out.print(reasoning); } if (Objects.nonNull(content) && !content.isEmpty()) { Object text = content.get(0).get("text"); finalContent.append(text); if (!isFirstPrint) { System.out.println("\n====================Complete Response===================="); isFirstPrint = true; } System.out.print(text); } } public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) { return MultiModalConversationParam.builder() // 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY")) // 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます .model("qvq-max") .messages(Arrays.asList(Msg)) .incrementalOutput(true) .build(); } public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg) throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException { MultiModalConversationParam param = buildMultiModalConversationParam(Msg); Flowable<MultiModalConversationResult> result = conv.streamCall(param); result.blockingForEach(message -> { handleGenerationResult(message); }); } public static void main(String[] args) { try { String localPath = "xxx/test.mp4"; String filePath = "file://"+ localPath; MultiModalConversation conv = new MultiModalConversation(); MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue()) .content(Arrays.asList(new HashMap<String, Object>(){{put("video", filePath);}}, new HashMap<String, Object>(){{put("text", "このビデオは何についてですか?");}})).build(); streamCallWithMessage(conv, userMessage); // 最終結果を出力します // if (reasoningContent.length() > 0) { // System.out.println("\n====================Complete Response===================="); // System.out.println(finalContent.toString()); // } } catch (ApiException | NoApiKeyException | UploadFileException | InputRequiredException e) { logger.error("例外が発生しました: {}", e.getMessage()); } System.exit(0); } }
画像リスト
ローカルファイル football1.jpg、football2.jpg、football3.jpg、football4.jpg を例として使用します。
OpenAI
Python
import os
from openai import OpenAI
import base64
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode("utf-8")
base64_image1 = encode_image("football1.jpg")
base64_image2 = encode_image("football2.jpg")
base64_image3 = encode_image("football3.jpg")
base64_image4 = encode_image("football4.jpg")
client = OpenAI(
# 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
)
reasoning_content = "" # 推論プロセス全体を定義します
answer_content = "" # 完全な応答を定義します
is_answering = False # 推論プロセスが終了し、応答が開始されたかどうかを判断します
completion = client.chat.completions.create(
model="qvq-max",
messages=[{"role": "user","content": [
# 画像リストを渡す場合は、ユーザーメッセージの "type" パラメーターは "video" です
{"type": "video","video": [
f"data:image/png;base64,{base64_image1}",
f"data:image/png;base64,{base64_image2}",
f"data:image/png;base64,{base64_image3}",
f"data:image/png;base64,{base64_image4}",]},
{"type": "text","text": "このビデオの具体的なプロセスを説明してください。"},
]}],
stream=True,
# 最後のチャンクでトークンの使用状況を返すには、次のコメントを外します
# stream_options={
# "include_usage": True
# }
)
print("\n" + "=" * 20 + "Reasoning Process" + "=" * 20 + "\n")
for chunk in completion:
# chunk.choices が空の場合は、使用状況を出力します
if not chunk.choices:
print("\nUsage:")
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 + "Complete Response" + "=" * 20 + "\n")
is_answering = True
# 応答プロセスを出力します
print(delta.content, end='', flush=True)
answer_content += delta.content
# print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n")
# print(reasoning_content)
# print("=" * 20 + "Complete Response" + "=" * 20 + "\n")
# print(answer_content)
Node.js
import OpenAI from "openai";
import { readFileSync } from 'fs';
const openai = new OpenAI(
{
// 環境変数が設定されていない場合は、次の行を Model Studio API キーに置き換えます: apiKey: "sk-xxx"
apiKey: process.env.DASHSCOPE_API_KEY,
baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
}
);
const encodeImage = (imagePath) => {
const imageFile = readFileSync(imagePath);
return imageFile.toString('base64');
};
const base64Image1 = encodeImage("football1.jpg")
const base64Image2 = encodeImage("football2.jpg")
const base64Image3 = encodeImage("football3.jpg")
const base64Image4 = encodeImage("football4.jpg")
let reasoningContent = '';
let answerContent = '';
let isAnswering = false;
let messages = [{
role: "user",
content: [
{
// 画像リストを渡す場合は、ユーザーメッセージの "type" パラメーターは "video" です
type: "video",
video: [
`data:image/png;base64,${base64Image1}`,
`data:image/png;base64,${base64Image2}`,
`data:image/png;base64,${base64Image3}`,
`data:image/png;base64,${base64Image4}`
]
},
{
type: "text",
text: "このビデオの具体的なプロセスを説明してください"
}
]
}]
async function main() {
try {
const stream = await openai.chat.completions.create({
model: 'qvq-max',
messages: messages,
stream: true
});
console.log('\n' + '='.repeat(20) + 'Reasoning Process' + '='.repeat(20) + '\n');
for await (const chunk of stream) {
if (!chunk.choices?.length) {
console.log('\nUsage:');
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;
}
// 正式な応答を処理します
else if (delta.content) {
if (!isAnswering) {
console.log('\n' + '='.repeat(20) + 'Complete Response' + '='.repeat(20) + '\n');
isAnswering = true;
}
process.stdout.write(delta.content);
answerContent += delta.content;
}
}
} catch (error) {
console.error('Error:', error);
}
}
main();
DashScope
Base64 エンコードされたローカルファイルを渡します。
Python
import base64 import os import dashscope dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1' # base 64 エンコード形式 def encode_image(image_path): with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode("utf-8") base64_image1 = encode_image("football1.jpg") base64_image2 = encode_image("football2.jpg") base64_image3 = encode_image("football3.jpg") base64_image4 = encode_image("football4.jpg") messages = [{"role": "system", "content": [{"text": "あなたは親切なアシスタントです。"}]}, {'role':'user', 'content': [ {'video': [f"data:image/png;base64,{base64_image1}", f"data:image/png;base64,{base64_image2}", f"data:image/png;base64,{base64_image3}", f"data:image/png;base64,{base64_image4}" ] }, {'text': 'このビデオの具体的なプロセスを説明してください。'}]}] response = dashscope.MultiModalConversation.call( # 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx", api_key=os.getenv("DASHSCOPE_API_KEY"), model='qvq-max', messages=messages, stream=True ) # 推論プロセス全体を定義します reasoning_content = "" # 完全な応答を定義します answer_content = "" # 推論プロセスが終了し、応答が開始されたかどうかを判断します is_answering = False print("=" * 20 + "Reasoning Process" + "=" * 20) for chunk in response: # 推論プロセスと応答の両方が空の場合は無視します message = chunk.output.choices[0].message reasoning_content_chunk = message.get("reasoning_content", None) if (chunk.output.choices[0].message.content == [] and reasoning_content_chunk == ""): pass else: # 現在のものが推論プロセスである場合 if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []: print(chunk.output.choices[0].message.reasoning_content, end="") reasoning_content += chunk.output.choices[0].message.reasoning_content # 現在のものが応答である場合 elif chunk.output.choices[0].message.content != []: if not is_answering: print("\n" + "=" * 20 + "Complete Response" + "=" * 20) is_answering = True print(chunk.output.choices[0].message.content[0]["text"], end="") answer_content += chunk.output.choices[0].message.content[0]["text"] # 推論プロセス全体と完全な応答を出力するには、次のコードのコメントを外します # print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n") # print(f"{reasoning_content}") # print("=" * 20 + "Complete Response" + "=" * 20 + "\n") # print(f"{answer_content}")
Java
// dashscope SDK バージョン >= 2.19.0 import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.NoApiKeyException; import io.reactivex.Flowable; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; import com.alibaba.dashscope.common.MultiModalMessage; import com.alibaba.dashscope.exception.UploadFileException; import com.alibaba.dashscope.exception.InputRequiredException; import java.lang.System; import com.alibaba.dashscope.utils.Constants; public class Main { static { Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1"; } 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 String encodeImageToBase64(String imagePath) throws IOException { Path path = Paths.get(imagePath); byte[] imageBytes = Files.readAllBytes(path); return Base64.getEncoder().encodeToString(imageBytes); } private static void handleGenerationResult(MultiModalConversationResult message) { String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent(); String reasoning = Objects.isNull(re)?"":re; // デフォルト値 List<Map<String, Object>> content = message.getOutput().getChoices().get(0).getMessage().getContent(); if (!reasoning.isEmpty()) { reasoningContent.append(reasoning); if (isFirstPrint) { System.out.println("====================Reasoning Process===================="); isFirstPrint = false; } System.out.print(reasoning); } if (Objects.nonNull(content) && !content.isEmpty()) { Object text = content.get(0).get("text"); finalContent.append(text); if (!isFirstPrint) { System.out.println("\n====================Complete Response===================="); isFirstPrint = true; } System.out.print(text); } } public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) { return MultiModalConversationParam.builder() // 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY")) // 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます .model("qvq-max") .messages(Arrays.asList(Msg)) .incrementalOutput(true) .build(); } public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg) throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException { MultiModalConversationParam param = buildMultiModalConversationParam(Msg); Flowable<MultiModalConversationResult> result = conv.streamCall(param); result.blockingForEach(message -> { handleGenerationResult(message); }); } public static void main(String[] args) { try { MultiModalConversation conv = new MultiModalConversation(); String localPath1 = "xxx/football1.jpg"; String localPath2 = "xxx/football2.jpg"; String localPath3 = "xxx/football3.jpg"; String localPath4 = "xxx/football4.jpg"; String base64Image1 = encodeImageToBase64(localPath1); // Base64 エンコード String base64Image2 = encodeImageToBase64(localPath2); String base64Image3 = encodeImageToBase64(localPath3); String base64Image4 = encodeImageToBase64(localPath4); MultiModalMessage userMessage = MultiModalMessage.builder() .role(Role.USER.getValue()) .content(Arrays.asList(Collections.singletonMap("video", Arrays.asList( "data:image/jpeg;base64," + base64Image1, "data:image/jpeg;base64," + base64Image2, "data:image/jpeg;base64," + base64Image3, "data:image/jpeg;base64," + base64Image4)), Collections.singletonMap("text", "このビデオの具体的なプロセスを説明してください"))).build(); streamCallWithMessage(conv, userMessage); // 最終結果を出力します // if (reasoningContent.length() > 0) { // System.out.println("\n====================Complete Response===================="); // System.out.println(finalContent.toString()); // } } catch (ApiException | NoApiKeyException | UploadFileException | IOException | InputRequiredException e) { logger.error("例外が発生しました: {}", e.getMessage()); } System.exit(0); }}
ファイルパスを直接渡します。詳細については、ファイルパスの作成 をご参照ください。
Python
import os import dashscope dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1' local_path1 = "football1.jpg" local_path2 = "football2.jpg" local_path3 = "football3.jpg" local_path4 = "football4.jpg" image_path1 = f"file://{local_path1}" image_path2 = f"file://{local_path2}" image_path3 = f"file://{local_path3}" image_path4 = f"file://{local_path4}" messages = [{"role": "user", "content": [ {"video":[image_path1,image_path2,image_path3,image_path4]}, {"text": "このビデオの具体的なプロセスを説明してください"}]}] response = dashscope.MultiModalConversation.call( # 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: api_key="sk-xxx", api_key=os.getenv("DASHSCOPE_API_KEY"), model='qvq-max', messages=messages, stream=True ) # 推論プロセス全体を定義します reasoning_content = "" # 完全な応答を定義します answer_content = "" # 推論プロセスが終了し、応答が開始されたかどうかを判断します is_answering = False print("=" * 20 + "Reasoning Process" + "=" * 20) for chunk in response: # 推論プロセスと応答の両方が空の場合は無視します message = chunk.output.choices[0].message reasoning_content_chunk = message.get("reasoning_content", None) if (chunk.output.choices[0].message.content == [] and reasoning_content_chunk == ""): pass else: # 現在のものが推論プロセスである場合 if reasoning_content_chunk != None and chunk.output.choices[0].message.content == []: print(chunk.output.choices[0].message.reasoning_content, end="") reasoning_content += chunk.output.choices[0.message.reasoning_content # 現在のものが応答である場合 elif chunk.output.choices[0].message.content != []: if not is_answering: print("\n" + "=" * 20 + "Complete Response" + "=" * 20) is_answering = True print(chunk.output.choices[0].message.content[0]["text"], end="") answer_content += chunk.output.choices[0].message.content[0]["text"] # 推論プロセス全体と完全な応答を出力するには、次のコードのコメントを外します # print("=" * 20 + "Complete Reasoning Process" + "=" * 20 + "\n") # print(f"{reasoning_content}") # print("=" * 20 + "Complete Response" + "=" * 20 + "\n") # print(f"{answer_content}")
Java
// dashscope SDK バージョン >= 2.19.0 import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.dashscope.common.Role; import com.alibaba.dashscope.exception.ApiException; import com.alibaba.dashscope.exception.NoApiKeyException; import io.reactivex.Flowable; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; import com.alibaba.dashscope.common.MultiModalMessage; import com.alibaba.dashscope.exception.UploadFileException; import com.alibaba.dashscope.exception.InputRequiredException; import java.lang.System; import com.alibaba.dashscope.utils.Constants; public class Main { static { Constants.baseHttpApiUrl="https://dashscope-intl.aliyuncs.com/api/v1"; } 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(MultiModalConversationResult message) { String re = message.getOutput().getChoices().get(0).getMessage().getReasoningContent(); String reasoning = Objects.isNull(re)?"":re; // デフォルト値 List<Map<String, Object>> content = message.getOutput().getChoices().get(0).getMessage().getContent(); if (!reasoning.isEmpty()) { reasoningContent.append(reasoning); if (isFirstPrint) { System.out.println("====================Reasoning Process===================="); isFirstPrint = false; } System.out.print(reasoning); } if (Objects.nonNull(content) && !content.isEmpty()) { Object text = content.get(0).get("text"); finalContent.append(text); if (!isFirstPrint) { System.out.println("\n====================Complete Response===================="); isFirstPrint = true; } System.out.print(text); } } public static MultiModalConversationParam buildMultiModalConversationParam(MultiModalMessage Msg) { return MultiModalConversationParam.builder() // 環境変数が設定されていない場合は、Model Studio API キーに置き換えます: .apiKey("sk-xxx") .apiKey(System.getenv("DASHSCOPE_API_KEY")) // 例として qvq-max を使用していますが、必要に応じてモデル名を変更できます .model("qvq-max") .messages(Arrays.asList(Msg)) .incrementalOutput(true) .build(); } public static void streamCallWithMessage(MultiModalConversation conv, MultiModalMessage Msg) throws NoApiKeyException, ApiException, InputRequiredException, UploadFileException { MultiModalConversationParam param = buildMultiModalConversationParam(Msg); Flowable<MultiModalConversationResult> result = conv.streamCall(param); result.blockingForEach(message -> { handleGenerationResult(message); }); } public static void main(String[] args) { try { MultiModalConversation conv = new MultiModalConversation(); String localPath1 = "xxx/football1.jpg"; String localPath2 = "xxx/football2.jpg"; String localPath3 = "xxx/football3.jpg"; String localPath4 = "xxx/football4.jpg"; String filePath1 = "file://" + localPath1; String filePath2 = "file://" + localPath2; String filePath3 = "file://" + localPath3; String filePath4 = "file://" + localPath4; MultiModalMessage userMessage = MultiModalMessage.builder() .role(Role.USER.getValue()) .content(Arrays.asList(Collections.singletonMap("video", Arrays.asList( filePath1, filePath2, filePath3, filePath4)), Collections.singletonMap("text", "このビデオの具体的なプロセスを説明してください"))).build(); streamCallWithMessage(conv, userMessage); // 最終結果を出力します // if (reasoningContent.length() > 0) { // System.out.println("\n====================Complete Response===================="); // System.out.println(finalContent.toString()); // } } catch (ApiException | NoApiKeyException | UploadFileException | InputRequiredException e) { logger.error("例外が発生しました: {}", e.getMessage()); } System.exit(0); }}
使用方法に関する注意事項
対応 画像 フォーマット
対応している 画像 フォーマットは次のとおりです。OpenAI SDK を使用してローカル 画像 を入力する場合は、[コンテンツ タイプ] 列に従って image/{format}
を設定します。
画像 フォーマット | ファイル名拡張子 | コンテンツ タイプ |
BMP | .bmp | image/bmp |
JPEG | .jpe、.jpeg、.jpg | image/jpeg |
PNG | .png | image/png |
TIFF | .tif、.tiff | image/tiff |
WEBP | .webp | image/webp |
HEIC | .heic | image/heic |
画像 サイズの制限
単一の 画像 ファイルのサイズは 10 MB を超えてはなりません。OpenAI SDK を使用する場合、Base64 エンコードされた 画像 も 10 MB を超えてはなりません。詳細については、 を参照してください。
画像 の幅と高さはどちらも 10 ピクセルより大きくする必要があります。縦横比は 200:1 または 1:200 を超えてはなりません。
モデルは理解する前に 画像 をスケーリングおよび前処理するため、単一の 画像 のピクセル数に制限はありません。画像 が大きいほど、理解のパフォーマンスが向上するとは限りません。推奨ピクセル値:
qvq-max
、qvq-max-latest
、またはqvq-max-2025-03-25
への単一の 画像 入力の場合、ピクセル数は 1,003,520 を超えてはなりません。
画像 枚数の制限
複数 画像 入力の場合、画像 の枚数は、モデルのテキストと 画像 の合計トークン制限(最大入力)によって制限されます。すべての 画像 の合計トークン数は、モデルの最大入力より少なくなければなりません。
たとえば、qvq-max の最大入力は 106,496 トークンです。デフォルトのトークン制限は 画像 あたり 1,280 です。DashScope で vl_high_resolution_images
を設定すると、トークン制限を 画像 あたり 16,384 に増やすことができます。入力 画像 がすべて 1280 × 1280 の場合:
画像 あたりのトークン制限 | 調整済み 画像 | 画像 トークン | 画像 の最大枚数 |
1,280 (デフォルト) | 980 x 980 | 1,227 | 86 |
16,384 | 1288 x 1288 | 2,118 | 50 |
API リファレンス
入力パラメーターと出力パラメーターの詳細については、「Qwen」をご参照ください。
エラーコード
呼び出しが失敗し、エラーメッセージが返された場合は、「エラーメッセージ」をご参照ください。