ログアウト中 ログイン

RAGを用いたチャットボット開発講座 第1章10.2節「引用元の設定と401エラーの解決方法」




現在の見出し:10.2節:引用元の設定と401エラーの解決方法

見出し一覧

  • 10.2節:引用元の設定と401エラーの解決方法
  • - 引用元の表示・非表示を設定する
  • - 1. 空コンテンツの排除(前後空白の除去を含む)
  • - 2. 低スコア&空コンテンツの除外(スコア閾値は環境変数で可変)
  • - 3. 参照ゼロ時は OpenAI を呼ばず即レス(引用非表示)
  • - 4. answerの安全な取得に変更
  • - 5. 「情報なし」文言を環境変数で管理
  • - 6. 「情報なし」時は sources を返さないように分岐追加
  • - Azure Functionsでキーが変わってしまう理由と対処方法
  • - filesとblobの違い
  • - 「files」から「blob」に変更する具体的な手順

【PR】『Python』を学べる企業・個人向けのプログラミングコース

引用元の表示・非表示を設定する

現在のコードだと、教師データと関係ない質問に対する回答にも引用元が表示されてしまう状態です。そこで、教師データに関係ない質問に対して情報がないことを回答する際、引用元の表示をオフにする機能を実装していきます。

まず、検索結果の扱いをより厳密にし、不要な引用や無駄なAPIAPIは、他のソフトやアプリが自分の機能を利用できるようにするためのインターフェースです。コールを避けるための修正を行います。修正内容をステップごとに詳しく解説します。

1. 空コンテンツの排除(前後空白の除去を含む)

検索結果に空文字や空白だけの文書が混ざらないよう、取得時に内容を整形します。

【修正前】
content = doc.get("content", "")

【修正後】
content = (doc.get("content") or "").strip()
  • 意図:None/空文字/空白だけのテキストを「情報なし」として扱う。
  • 効果:中身がない文書を参照情報にしない。

2. 低スコア&空コンテンツの除外(スコア閾値は環境変数で可変)

関連度が低い検索結果や空のテキストを採用せず、閾値を環境変数で調整できるようにします。

【追加】
min_score = float(os.environ.get("SEARCH_MIN_SCORE", "0"))

【修正後の採用条件】
if score >= min_score and content:
    context_list.append(f"[{file_name}] {content}")
    source_list.append({"score": round(score, 2), "source": file_name})
  • 意図:低関連度や空テキストを参照情報から除外。
  • 効果:回答の信頼性を高め、不要な引用を減らす。
  • 補足:SEARCH_MIN_SCORE で厳しさを調整可能。

3. 参照ゼロ時は OpenAI を呼ばず即レス(引用非表示)

検索結果がゼロ件なら生成を行わず、固定メッセージだけを返します。

if not context_list:
    return func.HttpResponse(
        json.dumps({"answer": "情報が見つかりませんでした。"}, ensure_ascii=False),
        mimetype="application/json",
        status_code=200
    )
  • 意図:参照ゼロなら「情報なし」と明示。
  • 効果:余計なトークン消費を防ぎ、引用表示もしない。

続いて、OpenAIの応答処理に関する修正を進めます。

4. answerの安全な取得に変更

応答が「None」や空文字でも安全に扱えるようにします。

【修正前】
answer = response.choices[0].message.content

【修正後】
answer = (response.choices[0].message.content or "").strip()

5. 「情報なし」文言を環境変数で管理

固定文言を環境変数に置き換えて運用で調整可能にします。

NO_INFO_TEXT = os.environ.get("NO_INFO_TEXT", "情報が見つかりませんでした。")
  • 意図:文言変更をコード修正なしで可能にする。
  • 効果:運用や多言語対応が容易になる。

6. 「情報なし」時は sources を返さないように分岐追加

OpenAIの応答が「情報なし」の場合、sources を含めず回答だけを返すようにします。

if answer == NO_INFO_TEXT:
    return func.HttpResponse(
        json.dumps({"answer": answer}, ensure_ascii=False),
        mimetype="application/json",
        status_code=200
    )

# 参照がある場合のみ sources を同梱
return func.HttpResponse(
    json.dumps({"answer": answer, "sources": source_list}, ensure_ascii=False),
    mimetype="application/json",
    status_code=200
)
  • 意図:「情報なし」時に引用元が並ぶ矛盾を解消。
  • 効果:ユーザー体験が自然になり、状態を正しく伝えられる。

上記の統一により「情報なし」という概念が検索処理と応答処理の双方で一貫して扱われ、文言・分岐・表示のすべてが噛み合う構成になりました。

要点まとめ

Azure Functionsでキーが変わってしまう理由と対処方法

現所のRAGを用いたチャット機能だと、時間をおいて再度実行したとき「401」エラーが表示されてしまいます。本機能における401エラーの理由は、Function keyが一致しないことを表しています。

Azure Functionsはクラウドクラウドはインターネット上にあるITリソースを、必要な時に必要なだけ利用できる仕組みです。上で動いており、サーバーサーバーはインターネットやネットワーク上で、データやプログラムを提供するために使用されるコンピューターです。は常に固定ではありません。利用が増えたり一定時間利用がなかったりすると、裏側で動いているサーバー(インスタンスインスタンスはオブジェクト指向プログラミングにおける重要な概念です。)が切り替わります。

この仕組みによって、Function KeyやHost Keyといった保存先の設定が「files」になっているとキーが安定せず、401エラーの原因となります。

filesとblobの違い

filesとblobの違いは以下の通りです。

保存方法 挙動 安定性
files サーバーのローカルに保存。サーバー切替でキーが再生成される。 不安定(401 が発生しやすい)
blob Azure Storage に保存。サーバーが変わっても共通のキーを参照できる。 安定(キーが変わらない)

Azureのストレージ(保存先)のタイプを指定する「AzureWebJobsSecretStorageType」の値を「files」から「blob」に変更すると、キーの保存先が共通化され、サーバーが切り替わっても同じキーを使い続けることができます。その結果、一定時間後に401エラーが出る問題を防止できるのです。

「files」から「blob」に変更する具体的な手順

「files」から「blob」に変更する具体的な手順は以下の通りです。

  1. Azure Portalで対象のFunction Appリソースを開く
  2. Settings(設定)をクリックする
  3. Environment variablesを選択する
  4. 検索欄に「AzureWebJobsSecretStorageType」と入力すると、該当項目が表示される

このカリキュラム通り進めている場合、こちらの値が「files」になっているはずです。こちらを「blob」に変更・保存してください。これでエラー対処完了です。

1. 空コンテンツの排除(前後空白の除去を含む)

第10章10.2節「1. 空コンテンツの排除(前後空白の除去を含む)」の続きを見る


すべてのカリキュラムを無料登録で学ぶ

プログラミング・マーケティング・AI活用方法を
今すぐ無料登録すると、全てのコンテンツが視聴可能になります。