paper-qa を、カスタムの OpenAI 互換エンドポイントで動かす。

Updated 2026-07-30

paper-qa は LiteLLM のルーター辞書を通じてモデルを設定し、litellm_params は api_base を受け付けます。これを https://api.apisrouter.com/v1 に向け、キーを1つ渡せば、回答・要約・エージェントの各スロットが、あなたの論文ライブラリに対してカタログの任意のモデルで動くようになります。

早わかり: api_base を持つルーター辞書を、スロットごとに再利用する。

paper-qa の Settings オブジェクトは、モデル名に加えて、スロットごとに任意の LiteLLM ルーター設定を受け取ります。ルーター設定は model_list であり、その litellm_params が api_base と api_key を運びます。これは、README がローカルホストの OpenAI 互換サーバー向けにすでに使っているのと同じドキュメント記載のパターンであり、ゲートウェイは単に、それを公開 URL と実際のキーに置き換えたものにすぎません。llm と summary_llm を、宣言した model_name に設定し、その設定を両方のスロットに付け、paper-qa はゲートウェイ経由でルーティングします。 litellm_params の中のモデル文字列は、litellm のプロバイダー規約に従います。openai/<id> は、litellm にあなたの api_base に対してチャット補完を話すよう伝え、スラッシュの後ろの id はそのままエンドポイントに渡されます。したがって Claude・GPT・Gemini・GLM の id はすべて、同じ辞書でアドレスできます。

gateway_config = dict(
    model_list=[
        dict(
            model_name="claude-sonnet-4-6",
            litellm_params=dict(
                model="openai/claude-sonnet-4-6",
                api_base="https://api.apisrouter.com/v1",
                api_key=os.getenv("APISROUTER_API_KEY"),
                temperature=0.1,
            ),
        )
    ]
)

paper-qa が、どこでトークンを使うか: 3つのスロットとエンベディング。

paper-qa(GitHub 上では Future-House、スター数はおよそ9K)は、科学論文の PDF に対する検索拡張型の質問応答を、その上にエージェント型のループを重ねて行います。エージェントがいつあなたのライブラリを検索するか判断し、証拠となる断片を集め、その関連性を要約し、引用付きの回答を組み立てます。それは3つの個別に設定可能な LLM スロットに対応します。summary_llm は検索された断片ごとに証拠を評価し凝縮するため、ボリュームのスロットになります。llm は組み立てられた証拠から最終的な回答を書く、品質にとって重要なステップです。そして(エージェント設定の中の)agent_llm が、ループを導くツール選択の判断を行います。 3つすべてがデフォルトで OpenAI のモデルになっており、それぞれに対応する _config フィールド(llm_config、summary_llm_config、agent_llm_config)が同じルーター辞書を受け付けるため、1つのゲートウェイ設定オブジェクトを各スロットに付けつつ、スロットごとのモデル名は独立させておけます。よくある使い分けは、速い id で証拠を要約し、フロンティアの id で回答を書く、というものであり、どちらも1つのエンドポイントとキーを通じて行われます。 エンベディングは4つ目のワークロードであり、意図的に別扱いです。エンベディングの設定(デフォルトは text-embedding-3-small)が、あなたの論文のベクトルインデックスを構築します。チャットのスロットをゲートウェイに移しても、エンベディングは移動しません。リモートのエンドポイントから完全に独立したインデックスにしたい場合、paper-qa はローカルの sentence-transformers(st- プレフィックス、local extras 経由)にも対応しています。

フルセットアップ: スロットごとの設定を持つ Settings。

フルパターンは、アドレス可能にしたいモデルごとに1つのルーターエントリを宣言し、スロットごとに設定を付けるというものです。要約用の速いものと、回答用の強力なものという2つのエントリを宣言すれば、セットアップ全体を1つの辞書にまとめられます。 pqa は設定の表面を公開しているため、同じルーティングは CLI からも機能しますが、ゲートウェイのルーティングにおいては Python の経路の方が再現性があります。ルーター辞書はコマンドラインのフラグとしては扱いにくく、Settings オブジェクトを結果の横にログとして残すことで、リサーチの実行を再現可能にできるからです。

import os
from paperqa import Settings, ask
from paperqa.settings import AgentSettings

def entry(model_id, **params):
    return dict(
        model_name=model_id,
        litellm_params=dict(
            model=f"openai/{model_id}",
            api_base="https://api.apisrouter.com/v1",
            api_key=os.getenv("APISROUTER_API_KEY"),
            **params,
        ),
    )

gateway = dict(model_list=[
    entry("claude-sonnet-4-6", temperature=0.1),
    entry("claude-haiku-4-5-20251001", temperature=0.1),
])

answer = ask(
    "What is the evidence for LK-99 room-temperature superconductivity?",
    settings=Settings(
        llm="claude-sonnet-4-6",
        llm_config=gateway,
        summary_llm="claude-haiku-4-5-20251001",
        summary_llm_config=gateway,
        agent=AgentSettings(
            agent_llm="claude-sonnet-4-6",
            agent_llm_config=gateway,
        ),
        paper_directory="./papers",
    ),
)

スロットごとにモデルを選ぶ。

証拠パイプラインを固定してチューニングしてください。同じライブラリ、同じ質問、1度に1つのスロットだけ入れ替える。1つのエンドポイントの裏では、各候補はモデル名の文字列であり、キーごとの利用ログが、質問ごとに各構成の価格を教えてくれます。それこそが、研究室が実際に予算を組む数字です。

  • summary_llm は、質問1つにつき証拠の断片ごとに1回実行されます。本格的なライブラリでは、これが呼び出しの圧倒的多数を占めるため、速い id(claude-haiku-4-5-20251001)がシステム全体のコストの床を決めます。関連性さえ判断できればよく、文章を書く必要はありません。
  • llm は、組み立てられた証拠から引用付きの回答を書きます。ここが、ヘッジされた正確な科学的な文章が生まれるかどうかの分かれ目であり、claude-sonnet-4-6 と gpt-5.5 が頼れる選択肢です。このスロットは質問あたりの呼び出しが少ないため、プレミアムの範囲は限定的です。
  • agent_llm はループを導きます。再検索するか、証拠をさらに集めるか、回答するか。ここでの弱い判断は他のあらゆる場所でトークンを無駄にするため、このスロットのボリュームが少ないにもかかわらず、ミドルティア以上の id が経済的な選択になります。
  • gemini-3.1-pro-preview のような長文脈対応 id は、複数の論文から一度に証拠を引き出す質問に対して、回答スロットとしてテストする価値があります。

従量課金 · 公式価格より安い

Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.

モデル公式価格当社価格
Claude Sonnet 4.6$3.00 / $15.00 per M$2.40 / $12.00 per M
Claude Haiku 4.5 20251001$1.00 / $5.00 per M$0.80 / $4.00 per M
GPT-5.5$5.00 / $30.00 per M$4.00 / $24.00 per M
Gemini 3.1 Pro Preview$2.00 / $12.00 per M$1.60 / $9.60 per M
GLM-5.2$1.14 / $4.00 per M$1.10 / $4.00 per M

paper-qa に特有の失敗パターン。

デフォルトのままのスロット。llm と llm_config を設定しても summary_llm_config を設定しないと、要約はデフォルトの OpenAI モデルのままになり、OPENAI_API_KEY を要求して失敗します(あるいは、そのキーが存在する場合、あなたのルーティングを2つのエンドポイントに静かに分裂させます)。各スロットには独自の _config フィールドがあります。移動させたいすべてのスロットにゲートウェイの辞書を付けてください。agent_llm_config も含めて。 一致しない名前。Settings.llm は model_list の中の model_name と等しくなければなりません。litellm_params.model こそが実際にワイヤーに乗るものです。外側の名前を取り違えるとルーターにルートがなくなり、内側の id をタイプミスするとゲートウェイが model-not-found を返します。デバッグの際は、この2つの文字列を別々に確認してください。失敗の仕方が異なるからです。 追従すると想定されるエンベディング。エンベディングのスロットはベクトルインデックスを構築し検索し、独自のデフォルトと設定を持ちます。デフォルトのエンベディング用の OpenAI キーがない場合は、embedding を明示的に設定するか、st- プレフィックスでローカルの sentence-transformers を使ってください。後でエンベディングを切り替えることは、再インデックスも意味します。異なるエンベディングモデルから来たベクトルは混ざりません。 長い回答のための生成上限の欠如。litellm_params はエントリごとに max_tokens を受け付け、upstream のローカルエンドポイントの例は意図的にそれを設定しています。適切な上限のない回答スロットは、長い引用付きの回答を切り詰めることがあり、それはモデルの弱さのように見えますが、実際はパラメータの問題です。 解析の問題をルーティングのせいにする。paper-qa の品質は、モデルが文章を見る前の PDF 解析とチャンク分割に依存します。関連性があるとわかっているライブラリで回答が何も引用しない場合は、インデックス作成のステップを調べてください。ゲートウェイには、検索が送ってきたものしか見えません。

ゲートウェイ経由で paper-qa を使うのは誰か。

  • 共有ライブラリに対して文献 QA を実行するリサーチグループで、キーごとの利用状況が「研究室は質問1つにいくら使っているか」を推測ではなくレポートに変えてくれる場合。
  • 回答スロットで Claude 品質の科学的な文章を望みつつ、要約のボリュームは速い id に保ちたいチームで、両方とも1つのキーで済む場合。
  • 内部ツールに paper-qa を組み込むビルダーで、環境ごとの一束のベンダーシークレットを1つのゲートウェイ認証情報に置き換える人。
  • 固定された証拠パイプラインで回答モデルを比較するベンチマーカーで、各候補は設定文字列であり、ベンダー統合ではない場合。
  • 特定ベンダーの請求手段にアクセスできない開発者。チャージ制でカード不要のアクセスなら、プロバイダーごとのサインアップという依存を取り除けます。

エンドポイントを検証し、最初の質問をデバッグする。

宣言した id をゲートウェイが提供していることを確認してください。openai/ の後ろの litellm_params.model の文字列は、提供されている id と正確に一致していなければなりません。 最初の ask() の失敗のはしごはこうです。OPENAI_API_KEY を要求するエラーは、どこかのスロットがまだデフォルトのモデルのままで、設定が付いていないことを意味します。llm、summary_llm、agent_llm のどれを移動させ忘れたか確認してください。ゲートウェイからの 401 は、litellm_params の中の api_key の問題です。未知のモデルについてのルーターエラーは、Settings.llm が model_list のどの model_name とも一致していないことを意味します。回答時ではなくインデックス作成中の失敗は、エンベディングの設定か PDF 解析を指しており、チャットのルーティングではありません。 1つの質問は、多数の要約呼び出しとエージェントのステップ、そして最終的な回答へと展開するため、最初の成功実行の後、APIsRouter コンソールのリクエストごとのビューが、実トークンでスロットの内訳を示してくれます。ライブラリが大きくなるにつれて注視すべき数字です。要約のボリュームは質問数だけでなく検索された証拠の量に応じてスケールするからです。

curl -s https://api.apisrouter.com/v1/models \
  -H "Authorization: Bearer $APISROUTER_API_KEY" | head -50

よくある質問

paper-qa はカスタムの OpenAI 互換ベース URL にどう対応していますか?

LiteLLM のルーター設定を通じてです。llm_config、summary_llm_config、agent_llm_config のそれぞれが、litellm_params に api_base と api_key を含む model_list を受け付けます。これは、paper-qa がローカルホストの OpenAI 互換サーバー向けにすでに使っている同じドキュメント記載のパターンを、ゲートウェイの URL に向けたものです。

回答モデルと要約モデルは異なるベンダーから選べますか?

はい。各スロットはモデル名と独自の設定をペアにするため、速い Claude の id が証拠を要約し、GPT-5.5 や Gemini が最終回答を書く、ということが、1つの api_base と1つのキーを通じて可能です。id ごとに1つの model_list エントリを宣言し、スロットごとにそれらを参照してください。

エンベディングモデルも変更する必要がありますか?

いいえ。通常は同じステップで変更すべきではありません。エンベディングの設定はチャットのスロットとは独立しており、エンベディングモデルを切り替えると既存のベクトルインデックスが無効になります。デフォルトのエンベディング用のキーがない場合は、embedding を明示的に設定するか、st- プレフィックスでローカルの sentence-transformers を使ってください。

agent_llm スロットとは何で、それにも設定は必要ですか?

AgentSettings の中にある agent_llm は、いつ検索し、証拠を集め、回答するかというツール選択を導きます。他のスロットと同様にデフォルトで OpenAI のモデルになっているため、同じゲートウェイの辞書で agent_llm_config を付けてください。そうしないと、依然としてデフォルトのプロバイダーにルーティングしようとします。

上書きした後も、なぜ paper-qa は OPENAI_API_KEY を要求するのですか?

少なくとも1つのスロットが、まだデフォルトのモデルのままでルーター設定が付いていません。llm、summary_llm、agent_llm とそれぞれの _config フィールドを確認してください。エラーは呼び出そうとしたモデルの名前を示すため、どのスロットを見逃したか特定できます。

これは pqa の CLI からも Python と同じように動作しますか?

CLI も同じ設定の表面を公開していますが、ゲートウェイのルーティングにおいては Python の経路の方が実践的です。ルーター辞書はコマンドラインのフラグとしては扱いにくく、結果の横にログとして残せる Settings オブジェクトの方が、リサーチの実行を再現可能にします。