spinny:~/writing $ less rag-langchain-deep-dive.md
12Store sprogmodeller (LLMs) som GPT-4 og Claude er ekstraordinært kraftfulde, men lider af en fundamental begrænsning: deres viden er frosset på træningstidspunktet. **Retrieval-Augmented Generation (RAG)** løser præcis dette problem ved at kombinere den generative kraft i LLMs med evnen til at hente information fra eksterne kilder.34## Problemet: LLM-begrænsninger561. **Statisk viden**: En LLM ved kun, hvad den så under træning.72. **Hallucinationer**: Når en LLM ikke kender svaret, har den tendens til at opfinde et.83. **Ingen adgang til private data**: En generisk LLM har ingen adgang til din virksomheds interne dokumentation.910## Hvad er RAG?1112```mermaid13graph LR14 User["User"] -- "Question" --> Retriever15 Retriever -- "Search relevant\ndocuments" --> VectorStore["Vector Store"]16 VectorStore -- "Relevant\ndocuments" --> Retriever17 Retriever -- "Context + Question" --> LLM18 LLM -- "Grounded\nresponse" --> User19```2021## Sådan fungerer RAG i detaljer2223### Fase 1: Indeksering (Dokumentindtagelse)2425```mermaid26graph TD27 A["Documents\n(PDF, HTML, MD, DB)"] --> B["Document Loader"]28 B --> C["Text Splitter"]29 C --> D["Text Chunks"]30 D --> E["Embedding Model"]31 E --> F["Numerical Vectors"]32 F --> G["Vector Store\n(ChromaDB, Pinecone, FAISS)"]33```3435#### 1. Dokumentindlæsning36Dokumenter kan komme fra enhver kilde: PDF-filer, websider, databaser, Markdown-filer, APIer.3738#### 2. Tekstopdeling (Chunking)39**Text Splitter** opdeler dokumenter i mindre fragmenter kaldet *chunks*.4041#### 3. Embedding42Hver chunk transformeres til en **numerisk vektor** (embedding) via en embedding-model.4344#### 4. Vector Store45Vektorerne gemmes i en **Vector Store**, optimeret til **lighedssøgning**.4647### Fase 2: Retrieval + Generation48491. Spørgsmålet transformeres til et embedding.502. Vector Store finder de mest lignende chunks.513. De hentede chunks indsættes i prompten som kontekst.524. LLM genererer et svar baseret på den givne kontekst.5354## Opbygning af en RAG-pipeline med LangChain5556### Installation5758```bash59pip install langchain langchain-openai langchain-community chromadb60```6162### Trin 1: Indlæs dokumenter6364```python65from langchain_community.document_loaders import (66 PyPDFLoader,67 WebBaseLoader,68 DirectoryLoader,69 TextLoader,70)7172# Load a PDF73pdf_loader = PyPDFLoader("docs/manual.pdf")74pdf_docs = pdf_loader.load()7576# Load a web page77web_loader = WebBaseLoader("https://docs.example.com/guide")78web_docs = web_loader.load()7980# Load all .md files from a directory81dir_loader = DirectoryLoader("./knowledge_base", glob="**/*.md", loader_cls=TextLoader)82md_docs = dir_loader.load()8384all_docs = pdf_docs + web_docs + md_docs85```8687### Trin 2: Opdel dokumenter i chunks8889```python90from langchain.text_splitter import RecursiveCharacterTextSplitter9192text_splitter = RecursiveCharacterTextSplitter(93 chunk_size=1000,94 chunk_overlap=200,95 separators=["\n\n", "\n", ". ", " ", ""],96)9798chunks = text_splitter.split_documents(all_docs)99print(f"Original documents: {len(all_docs)}, Chunks: {len(chunks)}")100```101102### Trin 3: Opret embeddings og Vector Store103104```python105from langchain_openai import OpenAIEmbeddings106from langchain_community.vectorstores import Chroma107108embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")109110vectorstore = Chroma.from_documents(111 documents=chunks,112 embedding=embedding_model,113 persist_directory="./chroma_db",114)115```116117### Trin 4: Opret Retriever118119```python120retriever = vectorstore.as_retriever(121 search_type="similarity",122 search_kwargs={"k": 4},123)124125relevant_docs = retriever.invoke("How does authentication work?")126for doc in relevant_docs:127 print(doc.page_content[:200])128 print("---")129```130131### Trin 5: Byg RAG-kæden132133```python134from langchain_openai import ChatOpenAI135from langchain_core.prompts import ChatPromptTemplate136from langchain_core.runnables import RunnablePassthrough137from langchain_core.output_parsers import StrOutputParser138139llm = ChatOpenAI(model="gpt-4o", temperature=0)140141prompt = ChatPromptTemplate.from_template("""142Answer the question based only on the provided context.143If the context does not contain enough information, say you don't know.144145Context:146{context}147148Question: {question}149150Answer:151""")152153def format_docs(docs):154 return "\n\n".join(doc.page_content for doc in docs)155156rag_chain = (157 {"context": retriever | format_docs, "question": RunnablePassthrough()}158 | prompt159 | llm160 | StrOutputParser()161)162163response = rag_chain.invoke("How does authentication work in the system?")164print(response)165```166167## Avancerede RAG-teknikker168169### Multi-Query Retrieval170171```python172from langchain.retrievers import MultiQueryRetriever173174multi_retriever = MultiQueryRetriever.from_llm(175 retriever=vectorstore.as_retriever(),176 llm=llm,177)178179docs = multi_retriever.invoke("What are the security best practices?")180```181182### Kontekstuel komprimering183184```python185from langchain.retrievers import ContextualCompressionRetriever186from langchain.retrievers.document_compressors import LLMChainExtractor187188compressor = LLMChainExtractor.from_llm(llm)189compression_retriever = ContextualCompressionRetriever(190 base_compressor=compressor,191 base_retriever=retriever,192)193```194195### Hybrid søgning196197```python198from langchain.retrievers import EnsembleRetriever199from langchain_community.retrievers import BM25Retriever200201bm25_retriever = BM25Retriever.from_documents(chunks)202bm25_retriever.k = 4203204semantic_retriever = vectorstore.as_retriever(search_kwargs={"k": 4})205206hybrid_retriever = EnsembleRetriever(207 retrievers=[bm25_retriever, semantic_retriever],208 weights=[0.4, 0.6],209)210```211212### Konversationel RAG (med hukommelse)213214```python215from langchain.chains import create_history_aware_retriever216from langchain_core.prompts import MessagesPlaceholder217218contextualize_prompt = ChatPromptTemplate.from_messages([219 ("system", "Given the chat history and the user's latest question, "220 "reformulate the question so it is understandable without the history."),221 MessagesPlaceholder("chat_history"),222 ("human", "{input}"),223])224225history_aware_retriever = create_history_aware_retriever(226 llm, retriever, contextualize_prompt227)228```229230## Bedste praksis2312321. **Vælg den rigtige chunk-størrelse**: Eksperimenter med forskellige størrelser (500-1500 tokens).2332. **Brug dokumentmetadata**: Tilføj kilde, dato og kategori som metadata.2343. **Evaluer kvalitet**: Brug frameworks som [RAGAS](https://docs.ragas.io/).2354. **Håndter dokumentopdateringer**: Implementer en re-ingestion pipeline.2365. **Tilføj en re-ranker**: Brug en re-ranking model efter initial retrieval.237238## Konklusion239240RAG er blevet standardarkitekturen for at bygge AI-applikationer, der har brug for adgang til specifik, opdateret viden. LangChain forenkler implementeringen enormt.241242**Næste trin:**243- **Eksperimenter lokalt**: Start med ChromaDB og et par dokumenter.244- **Udforsk LangSmith**: Brug [LangSmith](https://smith.langchain.com/) til at overvåge og fejlsøge dine kæder.245- **Prøv forskellige embedding-modeller**.246- **Tjek dokumentationen**: [LangChain-dokumentationen](https://python.langchain.com/docs/) er en fremragende ressource.247
:RAG og LangChain: En komplet guide til Retrieval-Augmented Generationlines 1-247 (END) — press q to close