廣告位招商中 歡迎洽談

基於 LangChain 與 LlamaIndex 整合百川 API 構建繁體與中文企業文件 RAG 系統

365Finds Editorial
已收錄 11,430 篇 Wiki 文章

讓你的 AI 用上 365 Wiki

複製下方的提示詞,貼給你常用的 AI,然後直接提問。

下載完整版 Skill

先用提示詞體驗;經常使用時,安裝完整版 365Wiki Skill,以後無需重複複製。沒有常用 AI?Gemini、Microsoft Copilot 等網頁版也可以。

365Wiki Skill

在針對中文企業內部文件構建檢索增強生成(RAG)管線時,後端工程師常常會面臨標準英文技術棧帶來的挑戰:中文語料缺乏自然空格作為詞界,法規合約、規章制度與工程規範中充斥著高度專業的術語及條文編號,而常規的多語言 Embedding 模型在處理中文時容易發生字詞破碎化(Token 膨脹與語意失真),導致檢索召回率顯著下降。

百川智能(Baichuan AI)基於海量中文高質量資料訓練了系列基礎模型,其中 Baichuan4 與 Baichuan3-Turbo 在複雜語境理解、長文本總結和邏輯推理上表現優異,而 Baichuan-Text-Embedding(1024 維稠密向量)則專為中文語意檢索量身優化。由於百川在 https://api.baichuan-ai.com/v1 提供了相容 OpenAI 規範的 RESTful 接口,後端工程師能夠在 LangChain 與 LlamaIndex 中無縫採用社群原生模組或標準相容配接器完成系統整合。

本文將針對中文企業知識庫情境,詳細介紹系統架構設計、文本分塊策略與生產級 Python 實作程式碼。


1. 事前準備與 API 接口規範

在建構檢索管線前,請先至百川智能開發者平台申請 API Key,並設定至後端伺服器的環境變數中:

export BAICHUAN_API_KEY="your-baichuan-api-key"

安裝所需的框架套件與向量資料庫驅動:

pip install langchain-community langchain-core langchain-openai \
            llama-index-core llama-index-llms-openai-like llama-index-embeddings-openai \
            chromadb pydantic

百川核心 API 端點與模型配置:


2. 中文企業文件的文本切分與 Token 邊界防禦

西方常見的文本分割策略通常依據空白與單詞進行切割,這極易在中文字詞、合約法條與財務數據中間產生截斷。中文文件切分必須優先依據段落換行與中文全形標點符號(。、!、?、;)。

特別需要注意:Baichuan-Text-Embedding 模型的單次輸入上限嚴格限制為 512 個 Token。為防止超長字串引發 400 Bad Request 錯誤,在分塊處理時應將每個 Chunk 的字符數控制在 350 至 400 字之間,重疊長度保留 40 至 50 字,在保障條款上下文完整性的同時確保不突破上限。

from langchain_text_splitters import RecursiveCharacterTextSplitter

def create_chinese_document_splitter(chunk_size: int = 400, chunk_overlap: int = 50):
    """
    針對中文企業合約、內控制度與作業規範優化的遞歸切分器
    """
    return RecursiveCharacterTextSplitter(
        chunk_size=chunk_size,
        chunk_overlap=chunk_overlap,
        separators=[
            "\n\n",      # 段落優先
            "\n",        # 換行
            "。",        # 句號
            "!",        # 驚嘆號
            "?",        # 問號
            ";",        # 分號(合約條款子項常見)
            " ",         # 空白
            ""           # 單字退避
        ]
    )

3. LangChain 整合方案(LCEL + 稠密檢索)

在 LangChain 生態中,開發者可以透過 langchain_community 中的專屬類別呼叫百川,或直接使用 langchain_openai 搭配百川的 openai_api_base。在企業生產環境中,推薦使用相容適配模式,以便獲得流式輸出(Streaming)、非同步調用及 LCEL(LangChain Expression Language)的完整支援。

完整 LangChain RAG 流程實作

import os
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_core.documents import Document

# 1. 初始化百川模型與向量化接口
BAICHUAN_BASE_URL = "https://api.baichuan-ai.com/v1"
api_key = os.environ.get("BAICHUAN_API_KEY")

embeddings = OpenAIEmbeddings(
    model="Baichuan-Text-Embedding",
    openai_api_base=BAICHUAN_BASE_URL,
    openai_api_key=api_key,
    check_embedding_ctx_length=False  # 關閉針對官方 OpenAI 模型的長度預先檢查
)

llm = ChatOpenAI(
    model="Baichuan4",
    openai_api_base=BAICHUAN_BASE_URL,
    openai_api_key=api_key,
    temperature=0.1,  # 嚴格控制隨機性,防止幻覺
    streaming=True
)

# 2. 模擬企業內部規範文件錄入
raw_docs = [
    Document(
        page_content="第十三條 採購付款管理規範:針對超過新台幣250萬元的設備採購合約,供應商必須提供全額統一發票後,財務部方可安排第二筆30%的進度款項支付。專案初驗合格前,累計付款比例不得超過合約總金額的80%。",
        metadata={"source": "採購管理制度2024.pdf", "department": "Finance"}
    ),
    Document(
        page_content="第二十四條 差旅報銷標準:研發部門同仁赴一級城市出差,住宿費上限為每人每天新台幣3000元,餐費補貼為每人每天新台幣600元,按實際出差天數核算。",
        metadata={"source": "員工差旅規範v3.pdf", "department": "HR"}
    )
]

splitter = create_chinese_document_splitter(chunk_size=400, chunk_overlap=40)
chunked_docs = splitter.split_documents(raw_docs)

# 3. 建立 Chroma 向量資料庫
vectorstore = Chroma.from_documents(
    documents=chunked_docs,
    embedding=embeddings,
    collection_name="enterprise_knowledge"
)
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})

# 4. 設計符合企業合規要求的中文 Prompt Template
system_prompt = (
    "你是一個嚴謹的企業知識庫助理。請嚴格根據以下檢索到的參考文件回答使用者的問題。\n"
    "如果參考文件中未提供明確說明,請直接回覆「依據現行內部規章未查得相關資訊」,嚴禁憑空捏造或主觀揣測。\n\n"
    "【參考文件】:\n{context}"
)

prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    ("human", "{question}")
])

def format_docs(docs):
    return "\n\n".join(f"[{doc.metadata.get('source', '未知')}] {doc.page_content}" for doc in docs)

# 5. 組裝 LCEL 調用鏈
rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

# 6. 執行查詢
if __name__ == "__main__":
    query = "採購大型設備合約時,第二筆進度款支付的前提條件為何?"
    response = rag_chain.invoke(query)
    print("生成回答:\n", response)

4. LlamaIndex 整合方案(OpenAILike 與自訂切分)

在 LlamaIndex(v0.10+)架構中,由於核心套件拆分且原生 OpenAI 類別會驗證模型名稱白名單,連線至第三方相容服務應使用 llama-index-llms-openai-like 的 OpenAILike,向量模型則使用自訂 api_base 的 OpenAIEmbedding。

完整 LlamaIndex RAG 流程實作

import os
from llama_index.core import Settings, VectorStoreIndex, Document
from llama_index.core.node_parser import SentenceSplitter
from llama_index.llms.openai_like import OpenAILike
from llama_index.embeddings.openai import OpenAIEmbedding

# 1. 全域配置百川組件
BAICHUAN_BASE_URL = "https://api.baichuan-ai.com/v1"
api_key = os.environ.get("BAICHUAN_API_KEY")

Settings.llm = OpenAILike(
    model="Baichuan4",
    api_base=BAICHUAN_BASE_URL,
    api_key=api_key,
    is_chat_model=True,
    temperature=0.1
)

Settings.embed_model = OpenAIEmbedding(
    model="Baichuan-Text-Embedding",
    api_base=BAICHUAN_BASE_URL,
    api_key=api_key
)

# 2. 設定中文斷句 Node 解析器
Settings.node_parser = SentenceSplitter(
    chunk_size=400,
    chunk_overlap=40,
    separator="。"
)

# 3. 載入文件並建立索引
documents = [
    Document(
        text="第七章 核心資料安全管理:涉及生產資料庫匯出作業必須提前48小時提交申請單,經資安主管與業務主管雙重核准後方可在堡壘機中執行。匯出檔案必須啟用國密SM4演算法加密並於3天內自動銷毀。",
        metadata={"category": "SecOps", "author": "Security Committee"}
    )
]

index = VectorStoreIndex.from_documents(documents)

# 4. 建立檢索查詢引擎
query_engine = index.as_query_engine(
    similarity_top_k=2,
    system_prompt=(
        "你代表企業資訊安全委員會回答技術規範諮詢。"
        "請嚴格根據檢索到的規章回覆,條列具體簽核流程與加密規範。"
    )
)

if __name__ == "__main__":
    response = query_engine.query("匯出生產環境資料庫需要滿足哪些核准與安全條件?")
    print("查詢結果:\n", str(response))

5. 企業級後端工程落地實務

在生產環境中長期維運百川 API 支援的 RAG 服務,需特別考量以下架構層面:

1. 混合檢索(向量 + BM25)保證條文精準度

向量語意檢索擅長模糊意圖對齊,但面對合約精確條款(例如「第十四條第二項」)、料號編碼或法規代號時容易產生泛化干擾。後端可透過 LangChain 的 EnsembleRetriever 或 LlamaIndex 的 Hybrid Search,將 Baichuan-Text-Embedding 稠密向量與 BM25 稀疏檢索依權重整合。

2. 向量化前置長度攔截

由於 Baichuan-Text-Embedding 硬性限制 512 Token,在處理包含長表格、未格式化程式碼或 OCR 辨識結果的文件時,必須在進入向量資料庫前實施 Token 長度防禦檢查,超限資料自動觸發二次強制截斷,避免批次任務中斷。

3. API 頻率限制與容錯重試

企業在初期大量建置內部知識庫時,短時間內會引發大量 API 請求。百川開放平台設有 RPM/TPM 呼叫限制。後端服務應導入 tenacity 實作指數退避重試(Exponential Backoff),或透過非同步 Semaphore / 令牌桶進行請求節流。

4. 嚴防幻覺與來源溯源

在內部法務與行政知識庫中,給出錯誤指引的後果通常遠比坦承不知嚴重。提示詞應明確定義拒答邊界,並在回傳結果中附帶 metadata 資訊(如規章檔名、版本號與章節),供同仁快速調閱原文查證。


參考資料