2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【生成AI】JSON形式で確実に返させる「One-shot」プロンプト術(n8n/ChatGPT対応)

2
Last updated at Posted at 2026-02-17

unnamed-6.jpg

はじめに

業務自動化で生成AI(ChatGPT APIやGemini APIなど)を使う時、最も困るのが 「JSON以外の余計な挨拶」 が入ってパースエラーになることではありませんか?

Here is the JSON you requested:
{
  "summary": "..."
}

このたった一行の「Here is...」があるせいで、後続の n8n ノードや Google Apps Script (GAS) の JSON.parse() がコケて、ワークフロー全体が停止してしまいます。

OpenAIの「JSON Mode」を使うのも手ですが、Gemini 1.5 Flash や Claude 3 Haiku など、安価で爆速なモデル では非対応だったり、設定が面倒だったりする場合があります。

そんな時は、プロンプトの最後に 「出力例」を一つ渡すだけ で、AIの出力を劇的に安定させられます。今回はその具体的な手法を紹介します。

失敗例:フォーマット指定だけでは不安定

よくある失敗パターンが、「言葉で禁止する」アプローチです。

# 命令
以下の文章から情報を抽出し、JSON形式で出力してください。
余計な解説は絶対に不要です。JSONのみを出力してください。

# 入力テキスト
...

「余計な解説は不要」と強く言っても、LLM(特にチャット用に調整されたモデル)は学習データの影響で「ユーザーに丁寧に説明を入れたほうが良い」というバイアスがかかっています。
その結果、親切心で「はい、解析しました。結果はこちらです:」という文言をつけてしまい、自動化フローを破壊します。

解決法:「出力例」を見せる (One-shot Prompting)

システムプロンプトやユーザープロンプトの最後に、期待するJSONの具体例(One-shot) を含めることで、AIは「この形式に厳密に従うべきだ」と認識します。

「やってはいけないこと」を教えるより、「やるべき正解」を見せる方が、LLMにとっては遥かに分かりやすいのです。

成功するプロンプト構成

# 命令
以下の文章から情報を抽出し、JSON形式で出力してください。

# 出力フォーマット例(以下の形式に厳密に従うこと)
{
  "summary": "要約テキストがここに入ります",
  "tags": ["tag1", "tag2", "tag3"],
  "score": 85,
  "isUrgent": false
}

# 入力テキスト
ここに分析対象のテキストを記載...

「余計な解説は不要」という抽象的な指示よりも、具体的な「例」を見せた方が、LLMは従順になります。
これは One-shot prompting と呼ばれるテクニックの一種で、特に構造化出力が必要な業務自動化では、最もコスパの良い安定化手法です。

n8nでの実装例

n8nの「AI Agent」ノードや「Basic LLM Chain」で使用する場合の実践的な構成です。

  1. System Message または User Message の末尾に上記の「出力例」を含める。
  2. (GPT-4など対応モデルなら)「Format JSON Output」オプションも併用するとなお良し。
  3. 後続に Codeノード を置き、安全にパースする。

n8n Codeノードでの「安全なパース」コード

万が一、AIが前後に文字をつけてしまった場合に備え、正規表現でJSON部分だけを抜き出すフォールバック処理を入れておくと完璧です。

// n8n Codeノード用
const aiOutput = $('AI Agent').item.json.output; // AIの出力テキストを取得
let result;

try {
  // 1. まずはそのままパースを試みる
  // 出力例を提示していれば、大抵はここで成功します
  result = JSON.parse(aiOutput);
} catch (e) {
  // 2. 失敗した場合のフォールバック
  // 正規表現で最初の中括弧 { から 最後の中括弧 } までを抽出する
  const match = aiOutput.match(/\{[\s\S]*\}/);
  if (match) {
    try {
      result = JSON.parse(match[0]);
    } catch (e2) {
      throw new Error("JSONの抽出に失敗しました: " + aiOutput);
    }
  } else {
    throw new Error("有効なJSONが見つかりません: " + aiOutput);
  }
}

return result;

なぜ「例」が効くのか

LLMは確率的に「次の単語」を予測するマシンです。
抽象的な制約(「JSONだけ出して」)を与えられた場合、AIは「会話」の続きとして自然な言葉を選ぼうとします。

しかし、具体的なパターン(「こういうJSONを出したら正解」) が文脈(Context)の最後に提示されていると、モデルは「このパターンの続き」を生成しようとします。つまり、JSONの構文を開始する確率が極めて高くなるのです。

これは特に以下のモデルで有効です:

  • Gemini 1.5 Flash: JSON Modeの設定がAPI経由だと少々手間だが、プロンプトだけで制御できれば非常に高速・安価。
  • Claude 3 Haiku: 高速だが、厳密なJSON出力には明確な指示が必要。
  • GPT-3.5 / 4o-mini: JSON Modeがあるが、One-shotを併用することで精度がさらに向上する。

応用:スキーマ定義の提示

より厳密に制御したい場合は、出力例に加えて「型定義(スキーマ)」も含めます。
TypeScriptのInterface定義風に書くと、LLMは理解しやすいです。

# 出力スキーマ
- summary: string (200文字以内)
- tags: string[] (最大5件)
- score: number (0-100の整数)
- isUrgent: boolean

# 出力例
{
  "summary": "...",
  "tags": ["example"],
  "score": 80,
  "isUrgent": false
}

これにより、キーのスペルミス(Score vs score)や、型の不一致("80" vs 80)も防げます。

まとめ

  • 「JSONで返して」だけでは、LLMは親切心で余計な説明を入れがち。
  • 「出力例」をプロンプトに含めることで、意図した形式に安定化させる。
  • 正規表現による抽出ロジック(Codeノード)を挟めば、エラー率はほぼゼロに。
  • JSON Mode非対応の安価なモデル(Gemini Flash等)でも実用レベルになる。

業務でAIを使うなら「出力例(One-shot)」は必須のテクニックです。
たった数行の追加で、エラーハンドリングやリトライのコストを大幅に削減できます。ぜひ試してみてください。

この記事を書いた人✏️@YushiYamamoto
株式会社プロドウガ CEO / AIアーキテクト
Next.js / TypeScript / n8nを活用した自律型アーキテクチャ設計を専門としています。
日々の自動化の検証結果や、ビジネス側の視点(ROI等)に関するより深い考察は、以下の公式サイトおよびnoteで発信しています。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?