RAGSpine
リファレンス

拡張ポイント

プロバイダ、ストア、検索、チャンキング、ルーティング、ワークフローマッチング、コネクタ、サービスエッジのための型付きシーム。

RAGSpine のプラガビリティはプラグインレジストリではなく、単純な構造的型付けです。各外部 依存は Python の Protocol であり、コアは抽象に依存し、ベンダー SDK には決して依存しません。 プロバイダ、ベクトルストア、リランカー、OCR エンジンの追加は新規ファイル 1 つで済み、 重い SDK はすべて遅延インポートされるため、コアはクリーンにインポートでき、決定論的な MockProvider で完全にオフラインで動作します。

以下のすべてのシームは @runtime_checkable な Protocol です — 実装は何かをサブクラス化する 必要はなく、正しいメソッドシグネチャを持つだけで十分です。コアは mypy --strict でカバーされ、 anthropic / openai / sentence-transformers / paddleocr の各 SDK は具体的な実装の内部で のみインポートされ、シーム側では決してインポートされません。

シーム一覧

LLMProvider

corespine(agent/llm_provider.py 経由で再エクスポート)— chat(messages, tools) が ChatCompletion を返す。OpenAI chat-completions 形式。

EmbeddingBackend

retrieval/lexical/retrieval.py — 注入可能なベクトルチャネルのために、テキストをバッチでベクトルに変換する。

ListwiseJudge

retrieval/rerank/listwise_rerank.py — リストワイズ再ランキング:候補のインデックスを最良順に返す。

OcrBackend

extraction/extractors/pdf_scanned_extractor.py — スキャンされた 1 ページの画像を認識する。

NarrativeRetriever

agent/agent.py — オーケストレータに注入されるナラティブ検索のシーム。

TaskQueue

service/tasks/task_queue.py — 非同期ジョブキュー(テストでは FakeQueue、本番では RQQueue)。

SourceConnector

ingestion/source/connector.py — iter_documents() がナレッジベースのソース(ファイルシステム、HTTP、Notion、インメモリ)から RawDoc を yield する。

RelationExtractor

graph/extractor.py — extract(chunks) がグラフのエッジを返す。build_relation_graph の隣にあるオプトインのナラティブ関係スロット。

Chunker

retrieval/chunking/chunker.py — テキストと DocumentMeta を、系譜を保持するチャンクに変換する。組み込み実装とサードパーティのエントリポイント。

LibraryRouter / FilterExtractor

retrieval/routing および filtering — 決定論的なライブラリ選択と、オプションの構造化メタデータフィルタ抽出。

TemplateMatcher

workflows/matching.py — 自然言語によるひな形生成のために、メタデータのみの実行可能テンプレート参照をランク付けする。

現在の検索およびワークフローのシーム

Chunker.chunk(text, meta, *, max_chars, overlap_chars) -> list[Chunk] がチャンク戦略を担います。 make_chunker は、決定論的デフォルト、レイアウト、親子、センテンスウィンドウ、法令、QA、 書籍、セマンティックの各実装に加え、ragspine.chunkers エントリポイントグループをサポートします。 実装は doc_idsource_locator を保持しなければなりません。階層/ウィンドウのデータは追加的な ものであり、系譜の代替ではありません。

LibraryRouter は 1 つ以上の RoutableLibrary ID を選択します。MultiIndexRetriever は選択された 各 NarrativeRetriever を独立に呼び出し、その結果を RRF で融合します。ルーターの失敗時は全 ライブラリへフォールバックします。FilterExtractor はメタデータの述語を提案できますが、フィルタは あくまで検証済みの絞り込み操作にとどまります。

TemplateMatcher はマッチ用メタデータを含むカタログ参照を受け取ります。ワークフローのプロンプトや 認証情報は受け取りません。組み込みのレキシカルマッチャーおよび ONNX マッチャーはランク付けされた 候補を返し、ひな形生成ポリシーがスコア/マージンのしきい値を適用して、選択されたテンプレートを 検証します。カスタムマッチャーがファイル書き込み権限や実行権限を得ることはありません。

LLMProvider

corespine が所有し、 src/ragspine/agent/llm_provider.py から再エクスポートされます — エージェントのツールユース ループが駆動する唯一のメソッドです。OpenAI chat-completions 形式chat メソッド 1 つ)を 話します。AnthropicProvideranthropic SDK を遅延インポートし、この形式を Anthropic API に マッピングします。MockProvider はキーもネットワークも必要としません。

プロパティ

0.3.0 マイグレーション。 これは旧来の create_message(*, system, messages, tools) -> ProviderResponse を置き換えたものです。このシームは現在、ファミリー共有コアの corespine に 置かれており、ragspine とその兄弟パッケージが 1 つのプロバイダ契約を共有します — ADR 0012 を参照してください。

EmbeddingBackend

src/ragspine/retrieval/lexical/retrieval.py — ベクトルチャネルの依存性注入ポイントです。 デフォルトは none(純粋な BM25)で、これを注入するとベクトルチャネルが追加されます。

プロパティ

ListwiseJudge

src/ragspine/retrieval/rerank/listwise_rerank.py — オプションの LLM リストワイズリランカーの シームです。実際の実装は Claude(build_listwise_prompt / parse_listwise_response 経由)で、テストでは決定論的なフェイクを使います。存在しない場合は RRF の順序にフォールバックします。

プロパティ

OcrBackend

src/ragspine/extraction/extractors/pdf_scanned_extractor.py — スキャン PDF の OCR/VLM シームです。 実際のバックエンド(PaddleOCR)は Ubuntu + GPU 上で動作し、ロジックテストではフェイクを使うため、 レンダリング → マッピング → しきい値判定 → レビューのフローは GPU なしのマシンでも完全にテスト可能です。

プロパティ

NarrativeRetriever

src/ragspine/agent/agent.pyanswer_question に注入されるナラティブ検索の実装です。 ダックタイピングであり、省略された場合、ナラティブ経路は正直に劣化します。

プロパティ

TaskQueue

src/ragspine/service/tasks/task_queue.py — 非同期ジョブキューです。本番では RQQueue (RQ + Redis)、テストでは FakeQueue(同期インライン)を使います。rq / redisRQQueue の内部でのみ遅延インポートされます。

プロパティ

SourceConnector

src/ragspine/ingestion/source/connector.py — ナレッジベースのソースシームです。コネクタは、 KB がどこにあってもそこから生ドキュメントを yield します。デフォルトの FilesystemConnector は extra を必要とせず、HTTP / Notion コネクタは [connectors] extra の背後で httpx を遅延インポートします。

プロパティ

組み込みコネクタはモジュールレベルのテーブルに名前で登録され、サードパーティのコネクタは ragspine.source_connectors エントリポイントグループを通じて発見されます(名前が衝突した場合は 組み込み名が優先されます)。make_source_connector(spec=None, **kwargs) ファクトリ、または RAGSPINE_SOURCE_CONNECTOR 環境変数(none / NoneNone)で選択します:

プロパティ

RelationExtractor

src/ragspine/graph/extractor.pybuild_relation_graph(..., relation_extractor=None) が 消費するオプトインのナラティブ関係スロットです。デフォルトの None の場合、ベースグラフは バイト単位で同一です(追加のエッジなし)。ADR 0015 を参照してください。

プロパティ

make_relation_extractor(spec=None, *, provider=None, profile=None, **kwargs) または RAGSPINE_RELATION_EXTRACTOR で選択します(noneNonedeterministic / rule / cooccurrence → 決定論的デフォルト、llm / on → LLM 抽出器。プロバイダが利用できない場合は正直に None へ 劣化します)。

モデルが抽出したエッジは有用だが信頼されないものです。LLMRelationExtractorderived=model-derived および verified=unverified のマーカーをすべてのエッジのメタデータに 書き込み、系譜はモデルの自己申告ではなくチャンク(呼び出し側)から取得し、決定論的な SecurityGate が拒否したエンドポイントを持つエッジは破棄します。モデルが主張した関係が、 管理され検証済みの事実として読まれることは決してありません。

Protocol を実装して注入する

シームは構造的であるため、メソッドを実装してインスタンスを渡すだけです — 登録も基底クラスも 不要です。以下は OpenAI をバックエンドとする LLMProvider の例で、実際の chat シグネチャと ChatCompletion の形式に基づいています(データクラスは corespine に由来し、 ragspine.agent.llm_provider から再エクスポートされます):

my_openai_provider.py
from typing import Any

from openai import OpenAI  # lazy: only your file imports the SDK
from corespine import ChatCompletion, Choice, ResponseMessage, Usage


class OpenAIProvider:
    """A custom LLMProvider — no subclassing, just the chat method."""

    def __init__(self, model: str = "gpt-4o") -> None:
        self._client = OpenAI()
        self._model = model

    def chat(
        self,
        messages: list[dict[str, Any]],
        *,
        tools: list[dict[str, Any]] | None = None,
    ) -> ChatCompletion:
        # The messages are already in the OpenAI chat-completions shape, so they pass
        # through; the SDK response is the same shape, so the mapping back is direct.
        resp = self._client.chat.completions.create(
            model=self._model,
            messages=messages,
            tools=tools or [],  # adapt / omit as needed
        )
        choice = resp.choices[0]
        message = ResponseMessage(role="assistant", content=choice.message.content)
        u = resp.usage
        usage = (
            Usage(
                prompt_tokens=u.prompt_tokens,
                completion_tokens=u.completion_tokens,
                total_tokens=u.total_tokens,
            )
            if u is not None
            else None
        )
        return ChatCompletion(
            choices=(Choice(index=0, message=message, finish_reason=choice.finish_reason or "stop"),),
            usage=usage,
            model=resp.model,
            id=resp.id,
        )

MockProvider を渡す場所とまったく同じ場所に注入します:

from ragspine.agent.agent import answer_question
from ragspine.storage.fact_store import SqliteFactStore
from my_openai_provider import OpenAIProvider

store = SqliteFactStore("data/fact_metric.db")
store.init_schema()
result = answer_question("...", store, OpenAIProvider())

構造化チャネルの捏造防止ガードは、数値についてプロバイダの散文を信頼しません — 見つかった ファクトはファクト値から決定論的にレンダリングされ、ファクトが見つからなかった結果は、モデルの 出力にかかわらず「not found」に書き換えられます。プロバイダを差し替えてもこのガードを回避する ことはできません。

このページ