LangChain RAG

RAG (Retrieval-Augmented Generation) ermöglicht es KI, Fragen auf Grundlage Ihrer privaten Dokumente zu beantworten, ohne das Modell feinabzustimmen. Sie müssen die Dokumente nur vektorisieren und speichern, und der Agent kann relevante Inhalte abrufen, um zu antworten.


Was ist RAG

Herkömmliche große Modelle können nur Inhalte beantworten, die in ihren Trainingsdaten enthalten sind. Wenn Ihre Dokumente privat sind (unternehmensinterne Dokumente, persönliche Notizen), "kennt" das Modell sie nicht. RAG löst dieses Problem:

  • Offline-Phase: Dokumente in kleine Abschnitte aufteilen → Ein Embedding-Modell verwenden, um sie in Vektoren umzuwandeln → In einer Vektordatenbank speichern
  • Online-Phase: Benutzer stellt eine Frage → Frage in einen Vektor umwandeln → Nach dem ähnlichsten Inhalt in der Vektordatenbank suchen → Den abgerufenen Inhalt als Kontext an das Modell senden → Das Modell antwortet auf Grundlage des abgerufenen Inhalts

RAG-Workflow

┌──────────────────────────────────────────────────────┐
│                    离线阶段(索引)                     │
│                                                      │
│  文档 → DocumentLoader → TextSplitter → Embedding     │
│                                           ↓          │
│                                      VectorStore     │
└──────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────┐
│                    在线阶段(检索)                     │
│                                                      │
│  用户提问 → Embedding → 相似度搜索 → 检索结果          │
│                                          ↓           │
│                      检索结果 + 用户问题 → 模型 → 回答  │
└──────────────────────────────────────────────────────┘


Umgebungsvorbereitung

RAG-bezogene Abhängigkeiten installieren:

$ pip install langchain-deepseek langchain-chroma chromadb
PaketZweck
langchain-deepseekStellt das OpenAI Embedding-Modell bereit
langchain-chromaLangChain-Integration für die Chroma-Vektordatenbank
chromadbChroma-Vektordatenbank (leichtgewichtig, für Anfänger geeignet)

Initialisierung des Embedding-Modells

Beispiel

from dotenv import load_dotenv
load_dotenv()

from langchain_openai import OpenAIEmbeddings

# Text-Embedding-Modell von OpenAI
# Text in einen Vektor umwandeln (eine Menge von Gleitkommazahlen)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# Test: Einen Textabschnitt in einen Vektor umwandeln
text = "EXAMPLE ist eine Programmierlernplattform"
vector = embeddings.embed_query(text)

print(f"Text: {text}")
print(f"Vektordimension: {len(vector)}")   # text-embedding-3-small ist 1536-dimensional
print(f"Erste 5 Werte des Vektors: {vector[:5]}")

Run result:

Text: Example 是一个编程学习平台
Vector dimension: 1536
First 5 vector values: [0.0123, -0.0045, 0.0234, -0.0012, 0.0089]

Alternativ können Sie, wenn Sie keinen OpenAI-Schlüssel haben, den Embedding-Dienst von Alibaba Bailian verwenden..envSie müssen den Alibaba Bailian-Schlüssel zur Konfigurationsdatei hinzufügen:

DASHSCOPE_API_KEY="sk-xxx"

Code nach der Konfiguration:

Beispiel

import os
from dotenv import load_dotenv
load_dotenv()

from langchain_openai import OpenAIEmbeddings

# Text-Embedding-Modell von OpenAI
# Text in einen Vektor umwandeln (eine Menge von Gleitkommazahlen)

# Verwenden Sie den Qwen Embedding-Dienst von Alibaba Cloud Bailian (DashScope)
# Bailians Embedding-API ist kompatibel mit der OpenAI-API-Spezifikation, verwenden Sie daher direkt langchain-openai
# OpenAIEmbeddings, richten Sie einfach base_url auf den kompatiblen Endpunkt von Bailian,
# langchain-community / dashscope muss nicht installiert werden (dieses Paket wird nicht mehr gepflegt).
# text-embedding-v4 ist derzeit das empfohlene universelle Vektormodell und gibt standardmäßig 1024-dimensionale Vektoren aus.
#
# Zwei wichtige Parameter sind entscheidend:
# - check_embedding_ctx_length=False: OpenAIEmbeddings verwendet standardmäßig tiktoken
# um Text vor dem Senden in Token-ID-Arrays vorzukodieren (dies ist das Format, das die offizielle OpenAI-API erkennt),
# aber Bailians kompatible Schnittstelle akzeptiert nur Rohstrings. Wenn Sie diese Option nicht deaktivieren, wird sie einen Fehler melden
# ein Fehler "contents is neither str nor list of str" ausgelöst.
# - chunk_size=10: Bailians Embedding-Schnittstelle akzeptiert höchstens 10 Textstücke pro Anfrage.
# OpenAIEmbeddings packt standardmäßig 1000 Stücke auf einmal. Wenn die Wissensdatenbank etwas größer ist, wird das Limit überschritten und ein Fehler gemeldet.
embeddings = OpenAIEmbeddings(
    model="text-embedding-v4",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    check_embedding_ctx_length=False,
    chunk_size=10,
)
# Test: Einen Textabschnitt in einen Vektor umwandeln
text = "EXAMPLE ist eine Programmierlernplattform"
vector = embeddings.embed_query(text)

print(f"Text: {text}")
print(f"Vektordimension: {len(vector)}")   # text-embedding-3-small ist 1536-dimensional
print(f"Erste 5 Werte des Vektors: {vector[:5]}")

Vektorspeicher erstellen

Beispiel

from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma

# Embedding-Modell initialisieren
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# Einen Chroma-Vektorspeicher erstellen (Daten werden in einem lokalen Verzeichnis gespeichert)
vector_store = Chroma(
    collection_name="example_docs",
    embedding_function=embeddings,
    persist_directory="./chroma_db",  # Persistenzverzeichnis
)

# Dokumente hinzufügen (die einfachste Form: eine Liste von Texten)
texts = [
    "EXAMPLE ist eine kostenlose Website zum Programmierenlernen, die Tutorials zu HTML, CSS, JavaScript, Python usw. anbietet.",
    "Das Python3-Basistutorial hat 30 Kapitel, ist für Anfänger ohne Vorkenntnisse geeignet und behandelt Umgebungseinrichtung, grundlegende Syntax, objektorientierte Programmierung und mehr.",
    "Das HTML-Grundlagen-Tutorial hat 25 Kapitel und deckt Grundlagen wie HTML-Tags, Formulare und Multimedia ab.",
]

# add_texts wandelt Text automatisch in Vektoren um und speichert sie
vector_store.add_texts(texts)

print(f"{len(texts)} Dokumente zum Vektorspeicher hinzugefügt")

Semantische Suche

Beispiel

# Semantische Suche — beruht nicht auf Keyword-Matching, sondern auf semantischer Ähnlichkeit
results = vector_store.similarity_search(
    "Ich möchte Python lernen. Welche Tutorials empfehlen Sie?",
    k=2,  # Gibt die 2 ähnlichsten Ergebnisse zurück
)

print("Search results:")
for i, doc in enumerate(results):
    print(f"\n"Ergebnis {i+1}:")
    print(f" Inhalt: {doc.page_content}")
    print(f" Metadaten: {doc.metadata}")

Run result:

搜索结果:

Result 1:
  Content: Python3 基础教程共 30 章,适合零基础入门...
  Metadata: {}

Result 2:
  Content: Example是一个免费的编程学习网站...
  Metadata: {}

Beachten Sie, dass das erste Suchergebnis relevanter ist als das zweite — obwohl das erste das Schlüsselwort "Python" enthält, wird es nachsemantischer Ähnlichkeitstatt nach Schlüsselwortübereinstimmung eingestuft. Dies ist der Vorteil der Vektorsuche.


Einen Retriever erstellen

Retriever ist eine standardisierte Schnittstelle für Vector Store:

Beispiel

# Einen Retriever aus vector_store erstellen
retriever = vector_store.as_retriever(
    search_type="similarity",  # Ähnlichkeitssuche
    search_kwargs={"k": 3},    # Die obersten 3 Ergebnisse zurückgeben
)

# Den Retriever verwenden
docs = retriever.invoke("Python-Lernpfad")
for doc in docs:
    print(f"- {doc.page_content[:60]}...")
Andere Erweiterungen