この記事は、【 可茂IT塾 Advent Calendar 2025 】の18日目の記事です。
はじめに
せっかくのアドベントカレンダー。
どうせなら 「クリスマスらしく、かつエンジニア的に面白い題材」 にしたい──
そう考えて思いついたのが、
「サンタクロースの業務効率化」
というテーマでした。
毎年クリスマスが近づくと、世界中の子どもたちからサンタさんのもとに、たくさんの手紙が届きます。
それらを一通一通読み、質問に答え、心を込めて返事を書く──
とても温かい仕事ですが、実はこれ、
「かなりの重労働」 ですよね。
そこで今回は、
- 子どもが手書きで書いた手紙
- そこに含まれる質問
- サンタさんが持つ前提知識
を組み合わせて、
「サンタさんからの "お返事文" を考えるAIワークフロー」
を Dify を使って作ってみました。
入力は、例えばこんな手書きのお手紙です。
全体像:今回つくるワークフロー
今回構築するワークフローの流れは以下の通りです。
(※ 詳細なワークフロー構成は、後半で実際の画面を見ながら解説します。)
- 画像OCRで手書き文字をテキスト化
- OCR結果を文脈から補正し、自然な日本語の手紙に変換
- 手紙の内容を構造化(JSON化)
- サンタの知識をもとにQA検索
- 検索結果を用いて、サンタの返事を生成
この中で特に重要なのは、次の2点です。
- QAチャンクを用いたナレッジ設計
- OCRの不完全さを前提にしたLLM補正
ナレッジパイプラインの作成(QAチャンク)
なぜQAチャンクを使うのか?
子どもからの手紙には、高確率で「質問」が含まれます。
- サンタさんはどこに住んでるの?
- トナカイは何匹いるの?
- どうやってプレゼントを運んでるの?
こうした FAQ形式の情報は、通常のドキュメント分割よりも QAチャンクの方が検索精度が高いため、今回は QAチャンクを採用しました。
サンタの知識ドキュメント
今回は、サンタさんが持つ前提知識として
以下のようなドキュメントを用意しました(内容はChatGPT生成)。
(※本文は省略せずそのまま使用しています)
ほっほっほ〜。よい子のみんな、北の国フィンランドから来た、本物のサンタクロースが...
🎅 服装について
わしの赤い服は、北の寒〜い冬でも体をあたためてくれる特別仕立てなんじゃ。
...
❄️ 住んでいる場所
わしはフィンランドの北、ラップランドに住んでおる。
...
🦌 トナカイについて
わしのそりを引いてくれるのは、頼もしいトナカイたちじゃ。
...
この文章を QA形式のナレッジに変換します。
ナレッジパイプラインの構築
ナレッジパイプラインは
Difyの「 ナレッジ → 知識パイプラインから作成する」 から作成できます。
今回のパイプライン構成は以下です。
- ファイルからテキストを抽出
- LLMで 想定Q&AをMarkdown表として生成
- Markdownを CSVに変換
- CSVを QAチャンクとして登録
(※ Dify では QAチャンクはCSV形式のみ対応している点に注意が必要です。)
🔽 QA生成用のプロンプト
あなたは与えられたテキストからRAGのチャンクを作成するAIです。
与えられた情報からサンタさんに対する子供達からの想定質問とサンタさんの回答を作成して欲しいです。
# 出力形式
- Markdown表のみを出力すること
- 一列目はserial number, 2列目は想定質問、3列目は回答とすること
- 表は簡単にCSVに変換できるようにすること
- Markdown表以外の説明などは出力しないこと
| Index | Question | Answer |
|-------|-----------|--------|
| 1 | 質問文1 | 回答文1 |
| 2 | 質問文2 | 回答文2 |
また、 QA Chunk の Colum number は Question = 1 / Answer = 2 に設定します。
ナレッジ登録結果
ドキュメントをアップロードすると、
想定Q&Aが正しく QAチャンクとして登録されていることが確認できます。
ワークフローの作成
ここからは、実際のワークフロー構成を見ていきます。
OCR:手書き文字をテキスト化
ユーザーがアップロードした画像から、 Mistral OCR を使って文字を抽出します。
OCR結果は以下のようなJSON構造で返ってきます。
OCR 結果の抽出(Codeノード)
コードブロックで以下のコードを実行し、markdownを抜き出します。
def main(arg1):
text = arg1[0]["pages"][0]["markdown"]
return {
"result": text
}
OCR結果を「自然な手紙」に補正
OCRによって抽出されたテキストには、
- 誤認識
- 文字の欠落
- 不自然な文字列
が含まれます。
そこでLLMを使い、
「小学校低学年の子どもが書いた手紙」として自然な文章に補正します。
この補正後の文章は、最終的な返事生成でもそのまま使われるため、
子どもらしさや文体を保つことが重要です。
🔽 文章補正用のプロンプト
`メッセージの抽出(CODE)_result`(変数)は、児童がクリスマスにサンタクロース宛てに書いた手紙を、写真からOCRで文字起こしした文章です。
OCRの精度が低く、誤認識・欠落・不自然な文字列が含まれています。 あなたの役割は、 幼児(小学校低学年)が実際に書きそうな内容を文脈から推測し、 意味が通る自然な日本語の手紙として修正・補完することです。
修正のルール
- 元の文章の意図・雰囲気(子どもらしさ)を尊重する
- 難しい言葉は使わず、ひらがな中心で整える
- 内容は大きく改変せず、読み取れる範囲から自然に補完する
- 手紙として違和感のない構成にする
補正後の文章がこちらです。
若干内容が変わってしまっている部分もありますが、「返事を書くための入力」としては十分自然な形になっています。
手紙の構造化 → QA検索 → 返信生成
次に、質問とそれ以外の情報を分離するため、
LLMで手紙の内容をJSONに構造化します。
🔽 JSON化のプロンプト
`メッセージ補完(LLM)_text`(変数)は、児童がサンタクロースに書いた手紙です。
この手紙の内容を分析し、
次のJSON形式で出力してください。
{
"questions": "サンタに聞いている質問",
"other_contents": {
"name": "わかる場合は名前",
"age": "わかる場合は年齢",
"location": "わかる場合は住んでいる場所",
"wish": "欲しいプレゼント",
"message": "感謝やあいさつなど、質問以外の本文"
}
}
ルール:
- 推測できない項目は null にする
- 質問文は原文の意味を保つ
- JSON以外は出力しない
抽出した質問をもとに、
先ほど作成したQAナレッジで検索を行い、
その結果を使って返事生成用のLLMに渡します。
🔽 返事生成用のプロンプト
あなたはフィンランドの本物のサンタクロースです。 あな/たは優しくて思いやりに溢れ、ユーモアを愛する、シャイで夢を大切にする存在です。世界中の良い子にプレゼントを届けることを喜びとし、見つからないようにこっそり行動しますが、時に煙突から落ちたりとあわてんぼうな一面も持ち合わせています。彼の行動の根底には「見返りを求めない優しさ」と「誰かを助ける喜び」があります。 口調は「〜なんじゃ」「ほっほっほ〜」のようなおおらかなお爺さん風です。
`メッセージ補完(LLM)_text`(変数)は児童があなた向けに書いた手紙です。児童へのお返事の手紙を簡潔に心を込めて書いてください。なお、質問に答える際には{{#context#}}を参照してください。子供からの質問内容はちゃんと確認し、質問されていないことには一切答えないでください。
結果として、質問にきちんと答えつつ、サンタらしい文体の返信文 が生成されました 🎉
おわりに
今回は、Difyを使って
- OCR
- QAチャンク
- RAG
- LLMワークフロー
を組み合わせた、
少し温かみのある業務効率化AIを作ってみました。
もちろん本当は、サンタさん自身が心を込めて手書きするのが一番です 🎅
でも、
裏側の整理や下書きをAIが支える──
そんな使い方も、きっと「やさしい効率化」だと思います。
来年のアドベントカレンダーでも、
また少し変わったものを作れたらいいなと思います ☺️






