qGuide: Azure OpenAI Service API にリクエスト
qGuide: Request to Azure OpenAI Service API
文字列 “投入データ”・”APIキー”・”リソース名”・”デプロイID”・”APIバージョン” を Azure OpenAI Service API(AOAI API)に CORS 送信します。レスポンス(モデルが生成した文章)は、タスク処理画面上でストリーミング表示されます。プロンプト設定次第で、「誤植チェック機能」「文章リライト機能」「差戻理由の候補列挙機能」といった様々な支援機能(タスク処理者を支援する機能)を提供することが可能です。
Input / Output
- ← STRING (STRING_TEXTFIELD)
q_input - ← STRING (STRING_TEXTFIELD)
q_instruction - ← STRING (STRING_TEXTFIELD)
q_apiKey - ← STRING (STRING_TEXTFIELD)
q_resource - ← STRING (STRING_TEXTFIELD)
q_deployment - ← STRING (STRING_TEXTFIELD)
q_apiVersion - →
pre#user_result - →
div#user_status
Code Example
HTML/JavaScript (click to close)
<style>
/* AI呼び出しボタン */
.user_aiBtn {
border: 1px solid #ccc;
background-color: #fff;
padding: 6px 12px;
border-radius: 20px;
cursor: pointer;
font-size: 13px;
transition: all 0.2s ease;
color: #333;
margin-right: 8px; /* ボタン間の余白 */
margin-bottom: 12px;
}
.user_aiBtn:hover {
background-color: #f0f0f0;
border-color: #bbb;
}
.user_aiBtn:disabled {
opacity: 0.5;
cursor: not-allowed;
background-color: #eee;
}
/* 結果表示エリア */
#user_result {
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 12px;
min-height: 8em;
white-space: pre-wrap;
word-break: break-word;
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
font-size: 14px;
line-height: 1.6;
color: #222;
margin-top: 4px;
}
/* ステータス表示エリア */
#user_status {
font: 12px/1.4 system-ui, sans-serif;
opacity: 0.75;
margin-top: 8px;
min-height: 1.4em;
}
/* タイピングカーソルのアニメーション */
@keyframes blink {
50% { opacity: 0; }
}
.user_cursor {
display: inline-block;
width: 8px;
height: 1em;
background-color: #333;
margin-left: 2px;
animation: blink 1s step-end infinite;
vertical-align: text-bottom;
}
</style>
<button type="button" class="user_aiBtn">AIレビュー</button>
<pre id="user_result"></pre>
<div id="user_status"></div>
<script>
// --- 全てのボタンにイベントリスナーを設定 ---
const aiButtons = document.querySelectorAll(".user_aiBtn");
aiButtons.forEach(button => {
button.addEventListener("click", async (event) => {
// --- Questetraのデータ項目から値を取得 ---
const strKey = qbpms.form.get("q_apiKey");
const strInstruction = qbpms.form.get("q_instruction");
const strResource = qbpms.form.get("q_resource");
const strDeployment = qbpms.form.get("q_deployment");
const strApiVersion = qbpms.form.get("q_apiVersion");
const strInput = qbpms.form.get("q_input");
// --- 必要なHTML要素を取得 ---
const resultElement = document.getElementById("user_result");
const statusElement = document.getElementById("user_status");
// --- 入力チェック ---
if (!strKey || !strInput) {
statusElement.innerText = "APIキーと入力内容は必須です。";
resultElement.innerText = "";
return;
}
// --- UIを処理中状態に更新 ---
aiButtons.forEach(btn => btn.disabled = true);
statusElement.innerText = "AIに接続中...";
resultElement.innerHTML = '<span class="user_cursor"></span>';
const cursor = resultElement.querySelector(".user_cursor");
try {
// --- APIリクエストを送信 ---
const url = `https://${strResource}.openai.azure.com/openai/deployments/${strDeployment}/chat/completions?api-version=${strApiVersion}`;
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"api-key": strKey
},
body: JSON.stringify({
messages: [
{ role: "system", content: strInstruction },
{ role: "user", content: strInput }
],
stream: true
})
});
// --- エラーレスポンスの処理 ---
if (!response.ok) {
const errorData = await response.json();
throw new Error(`API Error: ${response.status}\n${JSON.stringify(errorData, null, 2)}`);
}
statusElement.innerText = "AIが文章を生成中...";
// --- レスポンスをストリーミングで処理 ---
const reader = response.body.getReader();
const decoder = new TextDecoder();
// SSEは「\n\n」で区切られる。JSONが分割される可能性があるためバッファで扱う
let buffer = "";
let doneAll = false;
while (!doneAll) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
// イベント区切りで分解
const events = buffer.split(/\n\n/);
// 最後の断片は次ループで続きとして扱う
buffer = events.pop() || "";
for (const evt of events) {
// "data: ..." 行を抽出
const dataLines = evt
.split("\n")
.map(l => l.trim())
.filter(l => l.startsWith("data:"));
for (const dataLine of dataLines) {
const payload = dataLine.replace(/^data:\s*/, "");
if (payload === "[DONE]") {
doneAll = true;
break;
}
try {
const json = JSON.parse(payload);
// AOAI /chat/completions のストリームは OpenAI と同様に delta で来る
const delta = json?.choices?.[0]?.delta;
// 役割(assistantなど)が来ることもあるので無視してOK
const contentPiece = delta?.content || "";
if (contentPiece) {
cursor.insertAdjacentText("beforebegin", contentPiece);
}
// function/tool_calls 等が来る場合は必要に応じてここで分岐処理
// if (delta?.tool_calls) { ... }
} catch (e) {
console.error("JSON parse error:", payload, e);
}
}
if (doneAll) break;
}
}
statusElement.innerText = "生成が完了しました。";
} catch (error) {
console.error("Request failed:", error);
statusElement.innerText = "エラーが発生しました。";
resultElement.innerText = error.message;
} finally {
// --- UIを元に戻す ---
cursor?.remove();
aiButtons.forEach(btn => btn.disabled = false);
}
});
});
</script>
自由改変可能な HTML/JavaScript コードです (MIT License)。いかなる保証もありません。
(JavaScript を用いたデコレーションは Professional editionでのみ利用可能です: M213)
(JavaScript を用いたデコレーションは Professional editionでのみ利用可能です: M213)
Notes
- Azure OpenAI Service の詳細はこちらのページを確認してください。Microsoft 基盤上で、OpenAI 社が提供する ChatGPT 等が利用できます。
- 各設定項目についてはこちらの「Azure OpenAI Service #Chat: パラメータ付き対話」のページのNotesを参考にしてください。
Capture

Prompt Example (q_instruction)
誤植を指摘し、行ごとにMarkdown形式の箇条書きでわかりやすく修正内容を示してください。必要に応じて複数の誤植を漏れなく指摘し、各行には簡潔な指摘文を記載してください。出力例を参考に、必ず以下の出力フォーマットを守ってください。
---
## 出力フォーマット
- 各誤植ごとに「* 」で始めるMarkdownベースの箇条書き
- [誤植文] 誤植のある文を記載
- [正] 修正後の正しい文を提示
- どこが間違いか・どのように直すべきかを端的に述べる
---
## 例
* [誤植文] 今日は天気が良いですした。
* [正] 今日は天気が良かったです。
* 「良いですした」は誤り。「良かったです」と正しく修正。
* [誤植文] 彼は昨日、映画を見いった。
* [正] 彼は昨日、映画を見に行った。
* 「見いった」は「見に行った」に修正。
---
### 注意事項・追加ガイドライン
- 誤植が複数ある場合はすべて列挙してください。
- 指摘文は一行で簡潔にまとめてください。
- 出力は必ずMarkdown形式で箇条書きにしてください。