1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プロンプトを書くのはもうやめる。DSPy でプロンプトを「コンパイル」して自動最適化する技術

Posted at

はじめに:プロンプト職人は廃業する運命なのか

前回の記事
『プロンプトで祈るのはもうやめる。Outlines / Guidance で LLM の出力を 100% 制御する技術』

では、LLMの 出力(Output) を論理的に制御する方法を解説しました。

多くの反響をいただき、現場のエンジニアがいかに
LLMの不安定な挙動に悩まされているか を再確認しました。


出力は制御できた。では入力は?

出力は制御できるようになりました。
しかし、入力(Input)=プロンプト はどうでしょうか?

  • 「もう少し丁寧に考えて」
  • 「ステップ・バイ・ステップで」
  • 「あなたは優秀なアシスタントです」

相変わらず、私たちは
文字列の魔術(プロンプトエンジニアリング) に時間を費やしています。

  • モデルのバージョンが変わるたびに微調整
  • Few-shot の例を手作業で入れ替え
  • なぜ効いたのか分からないまま運用

これは本当に エンジニアリング と呼べるのでしょうか?


本記事では、スタンフォード大学発のライブラリ DSPy を紹介します。

DSPy は、

プロンプトを「手書き」するのをやめ、
評価指標に基づいて コンパイル(自動最適化) する

という、LLM開発の前提をひっくり返す技術です。


DSPy とは:LLMアプリを「PyTorch」のように書く

DSPy(Declarative Self-improving Language Programs)の核心は、
次の思想にあります。

プロンプトは文字列ではなく、最適化可能なパラメータである

従来の開発

  • 長大なプロンプト文字列を f-string で結合
  • 試行錯誤と勘に頼った調整
  • モデルが変わると全部やり直し

DSPy の開発

  • 入出力の型(Signature)を定義
  • ロジック(Module)を書く
  • データと評価関数を与えて Compile

これはまさに、

PyTorch でニューラルネットを定義して学習させる感覚

で、LLMアプリを書くという体験です。


仕組み:なぜ「コンパイル」で賢くなるのか?

DSPy の中核にあるのが
Teleprompter(Optimizer) という概念です。

構成要素

  • Signature
    入出力の定義(例:質問 → 回答)
  • Dataset
    少量の教師データ(質問と正解)
  • Metric
    良し悪しを判定する評価関数
  • Compile
    Optimizer が LLM を何度も叩いて最適化

Compile 中に行われていること

Optimizer は、以下を 自動探索 します。

  • タスクに最適な Instruction(指示文)
  • 問いに最も効果的な Few-shot 例示(Demo)
  • 有効な Chain of Thought(思考ステップ)

人間が

「どの例を見せれば賢くなるかな……」

と悩んでいた部分を、
アルゴリズムが総当たりで最適化 してくれるわけです。


実践:DSPy で RAG の精度を上げる

今回は、単純な QA タスク(RAG 想定)で
DSPy がどのようにプロンプトを自動生成するかを見ていきます。


1. 環境構築

pip install dspy-ai

2. モジュール定義

ここでは dspy.ChainOfThought を使います。
これだけで「推論してから回答せよ」というロジックになります。

プロンプトを書く必要はありません。

import dspy

# LLMの設定(OpenAI / Local)
# turbo = dspy.OpenAI(model='gpt-3.5-turbo')
# dspy.settings.configure(lm=turbo)
# ローカルLLMの場合は HFClientVLLM などを使用

# 1. Signature(入出力定義)
class GenerateAnswer(dspy.Signature):
    """質問に対して、文脈を踏まえて論理的に回答する"""
    context = dspy.InputField(desc="回答の根拠となる情報")
    question = dspy.InputField(desc="ユーザーからの質問")
    answer = dspy.OutputField(desc="短く簡潔な回答")

# 2. Module(処理ロジック)
class RAG(dspy.Module):
    def __init__(self):
        super().__init__()
        self.generate_answer = dspy.ChainOfThought(GenerateAnswer)

    def forward(self, context, question):
        return self.generate_answer(context=context, question=question)

3. コンパイル(最適化)の実行

ここが DSPy のハイライト です。

今回は BootstrapFewShot を使います。
これは、

成功した推論プロセスだけを Few-shot として残す

最適化手法です。

from dspy.teleprompt import BootstrapFewShot

# 教師データ
trainset = [
    dspy.Example(
        context="Pythonは1991年にグイド・ヴァン・ロッサムによって開発された。",
        question="Pythonの開発者は誰?",
        answer="グイド・ヴァン・ロッサム"
    ).with_inputs('context', 'question'),
    # ... 数件追加 ...
]

# 評価関数(簡易的に完全一致)
def validate_answer(example, pred, trace=None):
    return example.answer == pred.answer

# コンパイル!
teleprompter = BootstrapFewShot(
    metric=validate_answer,
    max_labeled_demos=4
)
compiled_rag = teleprompter.compile(
    RAG(),
    trainset=trainset
)

検証結果:何が変わったのか?

pred = compiled_rag(context="...", question="...")
dspy.inspect_history(n=1)

Before(最適化前)

  • 単純な
    質問: ... 文脈: ... → 回答:
    という素っ気ないプロンプト

After(最適化後)

  • DSPy が自動選定した 成功した推論パターン
    Few-shot として複数挿入
  • Instruction 部分も自動で微調整

DSPy は、こちらが一切指示していないにも関わらず、

「このタイプの質問は、この思考ステップを踏めば正解できる」

というパターンを発見し、
それをプロンプトにハードコードしてくれました。


精度比較(例)

手書きプロンプト(Zero-shot) : 正答率 60%
DSPy(BootstrapFewShot)       : 正答率 85%

※ タスク・データによって変動します


まとめ:LLM開発のパラダイムシフト

プロンプトエンジニアリングは重要ですが、
人間が手作業でやるには限界 があります。

DSPy がもたらす変化:

  • モジュール化
    ロジックとプロンプトの分離
  • 移植性
    モデル変更時は compile し直すだけ
  • 性能向上
    人間が思いつかない Few-shot を発見

最強の組み合わせ

  • 入力:DSPy で最適化
  • 出力:Outlines で制御

これで私たちは、

  • お祈りから解放され
  • 作文からも解放され
  • 真の意味での Software Engineering 2.0

に集中できるはずです。


参考リンク

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?