RAGLight

Bessouat40MIT活跃维护

模块化 RAG 框架,能自由替换 LLM、嵌入模型和向量库,还支持 MCP 接入外部工具与数据源,省去重复搭建检索增强流程的功夫。

RAGLight is a modular framework for Retrieval-Augmented Generation (RAG). It makes it easy to plug in different LLMs, embeddings, and vector stores, and now includes seamless MCP integration to connect external tools and data sources.

3.4.7发布于 2026-03-24 15:38 UTC672star102fork同步于 2026-11-10 17:57 UTC

怎么上手

由 README 提炼,执行前请确认
pip install raglight
pip install "raglight[ollama,chroma,documents]"
硬件要求按 README 说明

README 未说明显存或 GPU 要求;仅要求 Python 3.11 或更高版本,使用内置提供商时需安装对应可选 extra。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

模块化 RAG 框架,通过依赖注入自由组合 LLM、嵌入模型和向量库

模块化 RAG 框架,能自由替换 LLM、嵌入模型和向量库,还支持 MCP 接入外部工具与数据源,省去重复搭建检索增强流程的功夫。

核心能力

  • 核心包零第三方依赖,组件通过结构化协议注入
  • 内置 OpenAI、Ollama、Gemini、Bedrock 等多家提供商集成
  • 支持经典 RAG 与独立的 Agentic RAG 双管线
  • 提供跨后端的 provider-neutral 检索过滤树
  • 可选接入 Langfuse 追踪各阶段执行事件

容易踩的坑

v4 是破坏性版本,v3 的 builder、API server、CLI、UI 和旧 agentic 运行时均已移除;集成需显式导入,且使用内置提供商前必须安装对应 extra,否则导入 raglight 不会加载可选 SDK;MCP 支持需单独安装 raglight[agentic-mcp],且 MCPTool 依赖调用方自行管理并已连接的 MCP 客户端。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本3.4.7
  1. 3.4.7v3.4.7最新正式版2026-03-24 · 2026-03-24 15:38 UTC

    What's Changed

  2. 3.2.0v3.2.02026-03-12 · 2026-03-12 23:33 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/Bessouat40/RAGLight/compare/3.1.1...3.2.0

  3. 3.1.1v3.1.12026-03-05 · 2026-03-05 15:49 UTC
    查看更新说明

    Fix CLI bug

  4. 3.1.0v3.1.02026-03-05 · 2026-03-05 11:17 UTC
    查看更新说明

    Added

    • raglight serve --ui — launches a Streamlit chat interface alongside the REST API
      • --ui-port option to configure the Streamlit port (default: 8501)
      • Chat tab with full conversation history and markdown rendering
      • Upload tab to ingest files or a server-side directory directly from the browser
      • Both processes share the same configuration and shut down together on Ctrl+C
  5. 3.0.0v3.0.02026-03-04 · 2026-03-04 16:35 UTC
    查看更新说明

    New Features

    REST API Server (https://github.com/Bessouat40/RAGLight/pull/126)

    • New raglight serve CLI command to deploy a RAG pipeline as a REST API without writing any Python code
    • Built on FastAPI with automatic Swagger UI at /docs
    • Fully configurable via RAGLIGHT_* environment variables (LLM provider, embeddings, vector store, etc.)
    • Endpoints: GET /health, POST /generate, POST /ingest, POST /ingest/upload, GET /collections
    • File upload support via multipart form-data
    • Docker Compose example for one-command deployment

    Hybrid Search (https://github.com/Bessouat40/RAGLight/pull/127)

    • New hybrid retrieval combining BM25 (keyword search) and semantic (vector) search
    • Improves retrieval quality on sparse or technical documents where pure vector search falls short
    • Configurable via the Builder API and RAGConfig

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    RAGLight

    RAGLight 4 is a small, typed Python toolkit for composing classic and agentic retrieval-augmented generation pipelines. The core package has no third-party runtime dependency: applications inject an LLM, an embedding model, a vector store, and optional behavior through public structural protocols.

    RAGLight 4 is a breaking release. The v3 builder, global settings, API server, CLI, UI, and legacy agentic runtime were removed instead of being carried as compatibility layers. The v4 agentic API is a new implementation.

    Requirements

    • Python 3.11 or newer
    • One optional integration extra when using a built-in provider
    pip install raglight
    pip install "raglight[ollama,chroma,documents]"
    

    Available extras are openai, ollama, mistral, gemini, bedrock, huggingface, documents, chroma, qdrant, langfuse, and agentic-mcp.

    Copy-paste examples

    The examples index contains complete runnable workflows for classic RAG with Ollama, OpenAI, and OpenAI-compatible endpoints; recursive directory ingestion; Agentic RAG; MCP tools; custom agents; and custom components. Each provider example includes its exact installation and execution commands, while offline examples require no credentials or external services.

    Public API

    The stable core is deliberately narrow:

    from raglight import PipelineConfig, RAGPipeline
    from raglight.contracts import (
        DocumentProcessor,
        EmbeddingModel,
        IngestionVectorStore,
        LLM,
        Reranker,
        VectorStore,
    )
    from raglight.models import (
        And,
        Document,
        Eq,
        ExecutionEvent,
        FolderSource,
        In,
        MatchNone,
        Or,
        RAGResponse,
        RetrievalFilter,
    )
    

    The contracts are structural protocols. Custom components do not inherit from RAGLight classes and do not need registry entries.

    from raglight import PipelineConfig, RAGPipeline
    from raglight.models import Document, RetrievalFilter
    
    
    class MyLLM:
        def generate(self, input: dict[str, object]) -> str:
            return "RAGLight is extended through structural component contracts."
    
    
    class MyEmbeddings:
        def embed_documents(self, texts: list[str]) -> list[list[float]]:
            return [[float(len(text))] for text in texts]
    
        def embed_query(self, text: str) -> list[float]:
            return [float(len(text))]
    
    
    class MyVectorStore:
        def similarity_search(
            self,
            question: str,
            k: int = 5,
            *,
            retrieval_filter: RetrievalFilter | None = None,
        ) -> list[Document]:
            if retrieval_filter is not None:
                raise NotImplementedError("this store does not support filtering")
            return [Document(page_content="RAGLight uses dependency injection.")][:k]
    
        def add_documents(self, documents: list[Document]) -> None:
            pass
    
    
    pipeline = RAGPipeline(
        llm=MyLLM(),
        embeddings=MyEmbeddings(),
        vector_store=MyVectorStore(),
        config=PipelineConfig(top_k=3),
    )
    
    response = pipeline.generate("How is RAGLight extended?")
    print(response.answer)
    print(response.sources)
    print(response.events)
    

    generate() returns an immutable RAGResponse. Its answer, sources, structured execution events, per-stage timings, metadata, and trace_id can be consumed directly or converted into transport-friendly values with response.to_dict(). Streaming continues to yield text chunks through pipeline.stream(...).

    Use provider-neutral filters when retrieval must stay inside an application scope. Qdrant and Chroma translate the same filter tree at their integration boundaries:

    from raglight.models import And, Eq, In
    
    scope = And(
        Eq("workspace_id", "ws-123"),
        In("file_id", ["file-a", "file-b"]),
    )
    response = pipeline.generate("Summarize these files", retrieval_filter=scope)
    

    None keeps trusted standalone retrieval unrestricted. MatchNone() always returns no sources without querying a backend. Applications must calculate authorization scopes server-side; RAGLight does not implement users or ACLs.

    The pipeline itself is stateless and safe to share between users. Pass history explicitly for stateless requests, or create an isolated session when RAGLight should retain completed turns:

    response = pipeline.generate("One-off question", history=[])
    
    session = pipeline.create_session(session_id="user-123")
    first = session.generate("Remember this question")
    chunks = list(session.stream("What did I ask?"))
    
    print(session.history)
    session.clear()
    

    Conversational query reformulation is opt-in and uses the configured LLM only when history is present:

    pipeline = RAGPipeline(
        llm=llm,
        embeddings=embeddings,
        vector_store=vector_store,
        config=PipelineConfig(top_k=5, reformulate_queries=True),
    )
    

    The rewritten value is used for retrieval and reranking; generation still sees the original question and history. Successful responses expose the rewritten query in response.metadata["retrieval_query"] and add a reformulation event.

    A session commits a turn only after generation or streaming completes. Failed or abandoned streams do not leave partial conversation state behind. Separate sessions share configured components without sharing history.

    See examples/extending/custom_components.py for a complete executable example.

    Agentic RAG

    Agentic execution has a deliberately separate public namespace and does not change the deterministic RAGPipeline:

    from raglight.agentic import AgenticPipeline, FunctionTool
    
    pipeline = AgenticPipeline(
        llm=llm,
        embeddings=embeddings,
        vector_store=vector_store,
        tools=[
            FunctionTool(
                "weather",
                "Return weather for a city.",
                lambda arguments: weather_client.lookup(arguments["city"]),
                {"type": "object", "required": ["city"]},
            )
        ],
        max_steps=4,
    )
    
    response = pipeline.generate("Use the knowledge base and weather tool to answer")
    

    The built-in retrieve tool uses the injected vector store and optional reranker. The default planner asks the injected LLM for strict JSON decisions. Pass agent=my_agent to replace it with any object implementing the structural Agent.decide(context) contract; no inheritance or framework adapter is required. Tool failures become observations that the agent can recover from, while an unfinished loop raises AgentStepLimitError at the configured budget.

    Use pipeline.create_session(...) for isolated agentic history. Async tools are supported through await pipeline.agenerate(...). MCP is an optional adapter:

    pip install "raglight[agentic-mcp]"
    

    raglight.agentic.mcp.MCPTool wraps a tool on a caller-managed, connected MCP client. See the Agentic RAG examples and the public API guide for complete examples.

    Directory ingestion

    Directory ingestion belongs to the public pipeline, not to a vector-store adapter. Inject the lazy document-processor registry, then pass one or more folder sources:

    from raglight.integrations import default_registries
    from raglight.models import FolderSource
    
    pipeline = RAGPipeline(
        llm=llm,
        embeddings=embeddings,
        vector_store=vector_store,
        document_processors=default_registries.document_processors,
    )
    result = pipeline.ingest([FolderSource(path="./knowledge")])
    
    print(result.processed_count, result.indexed_count)
    print(result.skipped, result.failures)
    

    Traversal is recursive and deterministic by default. Common generated directories and symlinks are skipped, unsupported extensions are reported, and one failed file does not discard successful files. Use ignored_directories, recursive, chunk_size, and chunk_overlap on each FolderSource to customize discovery and processing. See examples/classic/directory_ingestion.py for a local Ollama and Chroma example.

    Built-in integrations

    Import integrations explicitly so importing raglight never loads an optional provider SDK:

    from raglight.integrations.ollama import OllamaEmbeddings, OllamaLLM
    from raglight.integrations.chroma import ChromaVectorStore
    from raglight.integrations import default_registries
    
    embeddings = OllamaEmbeddings(model_name="nomic-embed-text")
    vector_store = ChromaVectorStore(
        collection_name="knowledge",
        embeddings_model=embeddings,
        persist_directory="./raglight-db",
    )
    llm = OllamaLLM(model_name="llama3.1:8b")
    
    pipeline = RAGPipeline(
        llm=llm,
        embeddings=embeddings,
        vector_store=vector_store,
        document_processors=default_registries.document_processors,
    )
    

    Provider modules and public classes:

    ModuleClasses
    raglight.integrations.openaiOpenAILLM, OpenAIEmbeddings
    raglight.integrations.ollamaOllamaLLM, OllamaEmbeddings
    raglight.integrations.geminiGeminiLLM, GeminiEmbeddings
    raglight.integrations.bedrockBedrockLLM, BedrockEmbeddings
    raglight.integrations.mistralMistralLLM
    raglight.integrations.lmstudioLMStudioLLM
    raglight.integrations.huggingfaceHuggingFaceEmbeddings, HuggingFaceReranker
    raglight.integrations.chromaChromaVectorStore
    raglight.integrations.qdrantQdrantVectorStore
    raglight.integrations.documentsTextProcessor, CodeProcessor, PDFProcessor, VlmPDFProcessor
    raglight.integrations.langfuseLangfuseTracer

    Native Langfuse tracing

    pip install "raglight[langfuse]"
    
    from raglight.integrations.langfuse import LangfuseTracer
    
    tracer = LangfuseTracer()
    pipeline = RAGPipeline(
        llm=llm,
        embeddings=embeddings,
        vector_store=vector_store,
        tracer=tracer,
    )
    

    The SDK reads its standard LANGFUSE_* environment variables. Classic RAG creates nested reformulation, retrieval, reranking, and generation observations. Agentic RAG creates decision and tool observations through the same tracer= argument. Call tracer.flush() before a short-lived process exits.

    Registry-backed configuration

    Direct component injection remains the primary API. Registries provide an optional path for serializable JSON or TOML configuration without provider-specific branches in the pipeline:

    top_k = 3
    reformulate_queries = true
    
    [llm]
    name = "ollama"
    [llm.options]
    model_name = "llama3.1:8b"
    preload_model = false
    
    [embeddings]
    name = "ollama"
    [embeddings.options]
    model_name = "nomic-embed-text"
    
    [vector_store]
    name = "chroma"
    [vector_store.options]
    collection_name = "knowledge"
    persist_directory = "./raglight-db"
    
    from raglight import PipelineConfig, RAGPipeline
    from raglight.integrations import default_registries
    
    config = PipelineConfig.from_file("raglight.toml")
    pipeline = RAGPipeline.from_config(config, registries=default_registries)
    

    Custom factories may opt into named configuration:

    default_registries.llms.register("my-llm", MyLLM)
    

    Registration is never required when passing a component instance directly. See examples/extending/registry_configuration.py for an offline custom-registry example.

    Architecture

    Dependencies point inward:

    integrations -> registry/contracts/models <- pipeline
                                          ^---- agentic
    
    • registry primitives, contracts, and models are dependency-free.
    • pipeline and agentic are separate sibling application layers.
    • neither application layer imports concrete integrations or the other layer.
    • built-in integrations own their optional SDK dependencies.
    • agentic orchestration is intentionally separate from the classic RAG API.

    The detailed boundaries are documented in docs/architecture.md, and the v3 migration table is in docs/migration-v3-to-v4.md.

    Development

    The project follows test-driven development. Every behavior change starts with a failing test, then the smallest implementation, then refactoring while the suite remains green.

    make install-dev
    make check
    

    make check runs formatting, linting, type checking, architecture rules, unit tests, integration tests, end-to-end tests, and an isolated wheel validation. See docs/testing.md and docs/development.md for the contribution workflow.

    License

    RAGLight is distributed under the MIT License.