2025年8月2日 星期六

LexRAG:運用 Python 打造企業級 AI 法律文件智慧問答系統

LexRAG:運用 Python 打造企業級 AI 法律文件智慧問答系統

前言:AI 與 Python 在知識檢索中的協同力量

隨著人工智慧技術的飛速發展,大型語言模型(LLM)已成為各行各業提升效率的關鍵工具。然而,當面對法律、金融等高度專業化且不斷更新的知識時,如何確保 AI 能夠提供準確、高可信度的資訊,便成為一個巨大的挑戰。

您可以透過以下 GitHub 連結檢閱本專案的原始碼:https://github.com/BpsEason/lexrag.git

LexRAG 專案正是為了解決這個痛點而生。它是一個以 Python 為核心,深度整合 AI 技術的 RAG (Retrieval-Augmented Generation) 範本。透過強大的 Python 程式庫生態系,LexRAG 能夠將散落於多種非結構化法律文件中的知識,轉化為可供 AI 快速檢索的智慧資產。本文將深入探討 LexRAG 如何運用 Python 及其 AI 相關工具,實現一個高效、可溯源的法律智慧問答系統。

核心亮點:Python 賦能的三大 AI 應用

  1. AI 知識庫的自動化建構:

    LexRAG 最大的優勢在於其自動化的文件攝取能力。我們運用 Python 的 LangChain 庫,實現了對 PDF、Markdown、DOCX 等多格式文件的智慧載入與分割。這使得我們可以將所有法律文件(無論其格式為何)無縫地轉化為可被 AI 理解的數據,從而快速建構和更新知識庫。

  2. 高可信度 AI 答案的生成機制:

    為了避免 LLM 的「幻覺」,LexRAG 採用了 RAG 技術的核心邏輯。當使用者提出問題時,專案會利用 Python 程式碼從向量資料庫中檢索出最相關的文件片段,並將這些真實的上下文與問題一併提交給 LLM。這種設計確保了 AI 的回答不僅精確,更帶有明確的文件來源出處,大幅提升了答案的可信度。

  3. 現代化 AI 服務的快速部署:

    LexRAG 專案全部基於 Python 框架,包括用於 API 服務的 FastAPI 和用於 AI 監控的 Prometheus 客戶端庫。這使得整個應用能夠以輕量級的方式運行。透過 Docker Compose 的容器化部署,我們可以一鍵啟動所有 AI 相關服務,包括 LLM 服務、向量庫和監控系統,極大地簡化了部署流程。

技術架構解析:Python 驅動的數據流與 AI 協作

LexRAG 的技術架構清晰地展示了 Python 如何協調各個 AI 元件之間的交互。



這個流程的核心是 Python 程式碼,它扮演了協調者和執行者的角色:

  1. 資料攝取:當使用者執行 Python 攝取腳本時,LangChain 會啟動文件處理流程,將內容向量化並寫入 ChromaDB

  2. AI 檢索與生成FastAPI 接收查詢後,其後端的 Python 程式碼會調用 RetrievalQA 鏈,從 ChromaDB 檢索相關數據,並將其與查詢一同送給 LLM 進行最終的生成。

  3. API 服務FastAPI 作為一個高效能的 Python Web 框架,提供了整個系統的 RESTful API 接口,讓前端或任何客戶端都能輕鬆與 AI 服務互動。

關鍵程式碼:Python 驅動的 AI 邏輯

以下是專案中兩個最重要的 Python 程式碼片段,它們分別負責資料攝取與 AI 問答的核心邏輯,並附上詳細的中文註解。

1. 資料攝取與向量化 (Ingestion)

這段 Python 程式碼展示了如何運用 LangChainChromaDB,將文件內容轉換為 AI 可理解的向量,並附帶可溯源的元數據。

Python
# app/main.py

# 引入 Python 函式庫,專注於 AI 和數據處理
from langchain.document_loaders import PyPDFLoader, UnstructuredMarkdownLoader, UnstructuredWordDocumentLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.embeddings import HuggingFaceEmbeddings
import os

# 定義一個函數來載入、分割並儲存文件
def ingest_documents():
    """
    此函數負責將 'documents' 目錄下的所有文件載入、分割、
    並將其內容向量化後儲存到 ChromaDB 中。
    """
    documents = []
    
    # 遍歷文件並使用 LangChain 的 loader
    for file in os.listdir("documents"):
        file_path = os.path.join("documents", file)
        # 根據檔案類型選擇不同的載入器
        if file.endswith(".pdf"):
            loader = PyPDFLoader(file_path)
            documents.extend(loader.load())
        elif file.endswith(".md"):
            loader = UnstructuredMarkdownLoader(file_path)
            documents.extend(loader.load())
        elif file.endswith(".docx"):
            loader = UnstructuredWordDocumentLoader(file_path)
            documents.extend(loader.load())
    
    # 使用 Text Splitter 將文件分割成適當大小的區塊
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
    splits = text_splitter.split_documents(documents)
    
    # 使用 HuggingFace 的 AI 嵌入模型進行向量化
    embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
    
    # 建立 ChromaDB 實例,並將分割後的文本與其 metadata 一同儲存
    # metadata 包含 'source' (來源檔名) 和 'chunk' (區塊編號)
    vectorstore = Chroma.from_documents(
        documents=splits, 
        embedding=embeddings, 
        persist_directory="./chroma_db",
        metadatas=[{"source": doc.metadata.get("source"), "chunk": idx} for idx, doc in enumerate(splits)]
    )
    
    # 將向量資料庫持久化儲存到磁碟,方便後續重複使用
    vectorstore.persist()
    print("文件攝取完成並儲存到 ChromaDB。")
    return vectorstore, embeddings

2. RAG 檢索與生成 (Retrieval & Generation)

這段 Python 程式碼展示了如何利用 FastAPI 框架與 LangChain 庫,將 LLM 和向量檢索器串聯成一個完整的 AI 問答系統。

Python
# app/main.py

# 引入 Python 函式庫,專注於 API 和 AI 鏈
from fastapi import FastAPI
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
import os
import yaml

app = FastAPI()
retrieval_qa_chain = None

@app.on_event("startup")
async def startup_event():
    """
    在應用程式啟動時,初始化 AI RAG 管道。
    """
    global retrieval_qa_chain
    try:
        # 載入持久化儲存的 AI 向量庫
        vectorstore = # 載入持久化後的向量庫
        embeddings = # 載入 embedding 模型
    except Exception as e:
        print(f"啟動錯誤:未能載入向量庫。請先執行文件攝取。錯誤:{e}")
        return

    # 從 YAML 配置檔中讀取 LLM 參數
    llm_config = yaml.safe_load(open("./config/llm.yaml", "r"))
    llm_model_name = llm_config["model_name"]
    llm_api_base = llm_config["api_base"]
    llm_api_key = os.getenv("OPENAI_API_KEY", "sk-xxxx") 

    # 建立 LLM 實例,這裡使用 OpenAI 服務的相容 API
    llm = OpenAI(
        model_name=llm_model_name, 
        temperature=0.0, 
        openai_api_base=llm_api_base, 
        openai_api_key=llm_api_key
    )
    
    # 核心步驟:設計一個專業的 Prompt 模板,用於引導 LLM
    prompt_template = """你是一個專業的法律文件檢索助手,請根據提供的上下文來回答問題。
如果上下文沒有足夠資訊,請回答「根據現有文件,我無法回答這個問題。」
請在答案中註明相關的來源文件,格式為 [來源檔名]。

上下文:{context}
問題:{question}
答案:"""
    
    qa_prompt = PromptTemplate(template=prompt_template, input_variables=["context", "question"])

    # 建立 RetrievalQA 鏈,將 LLM 與檢索器結合,這是 RAG 的核心
    retrieval_qa_chain = RetrievalQA.from_chain_type(
        llm=llm, 
        chain_type="stuff",
        retriever=vectorstore.as_retriever(),
        return_source_documents=True, # 必須為 True 才能回傳來源文件
        chain_type_kwargs={"prompt": qa_prompt}
    )

# FastAPI 的 API 端點,處理使用者查詢
@app.post("/query")
async def query_documents(q: Query):
    if not retrieval_qa_chain:
        return {"error": "RAG pipeline未初始化。請確保文件已攝取。"}
    
    # 呼叫整個 Python RAG 鏈,接收包含答案和來源的結果
    result = retrieval_qa_chain.invoke({"query": q.query})
    
    answer = result["result"]
    sources = [doc.metadata.get("source") for doc in result["source_documents"]]
    
    # 將答案和不重複的來源文件名稱回傳給使用者
    return {
        "query": q.query, 
        "answer": answer, 
        "sources": list(set(sources))
    }

總結與未來展望

LexRAG 專案完美地展示了 Python 在 AI 應用開發中的強大潛力。透過其豐富的函式庫,我們能夠快速且靈活地建構複雜的 AI 系統,並確保其在專業領域中的穩定性與高可信度。

未來,此專案可以透過 Python 繼續擴展,例如:

  • 整合更多的 LangChain 工具,實現更複雜的 Agent-based 應用。

  • 運用 Python 的機器學習庫(如 Scikit-learn 或 TensorFlow)來優化檢索和生成模型。

  • 建立一個基於 StreamlitGradioPython 網頁前端,提供更直觀的使用者體驗。

LexRAG 不僅是一個功能完整的 RAG 範本,更是一個展示 AI 與 Python 協同工作以解決真實世界問題的絕佳案例。

沒有留言:

張貼留言

熱門文章