LangChain fyller sina lådor med nya verktyg i rasande takt under 2026, och den 3 september landade version 1.4.0 av huvudpaketet med inbyggt stöd för Model Context Protocol (MCP). Samtidigt har fältet av modeller att koppla in i en agent aldrig varit bredare: Anthropic släppte Claude Fable 5.1 den 1 september, Google DeepMind följde två dagar senare med Gemini 3.8 Flash, och det öppna alternativet Qwen3.8-27B har redan hunnit bli ett av de mest omtalade open-weight-alternativen sedan lanseringen i slutet av augusti. För en svensk utvecklare som vill bygga en agent som faktiskt svarar på frågor om egna dokument, inte bara chattar allmänt, är verktygslådan mognare än den varit på länge.

Den här guiden går igenom hur du bygger en komplett RAG-agent (retrieval augmented generation) med LangChain, från tom mapp till en fungerande Python-fil du kan köra på din egen dator. Du får kod för varje steg, en modelljämförelse baserad på officiella priser och benchmarks, en lista på fallgropar de flesta fastnar i första gången, och en felsökningstabell med nio konkreta problem och lösningar.

Enligt Stack Overflows utvecklarundersökning för 2025 planerar eller använder redan 84 procent av utvecklarna AI-verktyg i sitt dagliga arbete, upp från 76 procent året innan. Samma undersökning visar att 51 procent av yrkesverksamma utvecklare använder AI-verktyg dagligen. En uppföljande genomgång från Stack Overflow pekar på att 31 procent av utvecklarna redan använder AI-agenter i sitt arbete, och att 69 procent av dem som gjort det upplever en tydlig produktivitetsökning. RAG-agenter, alltså agenter som hämtar information ur egna dokument innan de svarar, är en av de vanligaste formerna av det arbetet just nu.

För svenska och nordiska team finns dessutom en extra dimension i valet mellan molnmodell och lokal modell. Skickar agenten kunddata eller interna dokument till ett amerikanskt API-företag måste du ha koll på var datan faktiskt behandlas och vilket avtal som gäller, särskilt för personuppgifter enligt GDPR. Just därför bygger den här guiden in båda spåren från start: ett moln-spår med Claude Fable 5.1 för den som vill ha snabbast väg till ett svar, och ett helt lokalt spår med öppna vikter för den som hellre håller all data på egen hårdvara.

Vad är LangChain och varför RAG-agenter är hetare än någonsin

LangChain är ett Python- och JavaScript-ramverk som knyter ihop språkmodeller, dokumentkällor, vektordatabaser och verktygsanrop till en gemensam kedja. Istället för att skriva egen kod för varje API-leverantör ger ramverket ett enhetligt gränssnitt, så att du kan byta från OpenAI till Anthropic till en lokal Qwen-modell genom att ändra en enda rad kod. Det är den här utbytbarheten, snarare än någon enskild funktion, som gjort LangChain till standardvalet för agentbygge under 2026. Hela projektet är öppen källkod och dokumenterat i detalj på LangChains officiella dokumentationssajt, där varje integration mot en modell-leverantör eller datakälla listas separat.

Paketstrukturen kan kännas rörig första gången, med separata paket för langchain, langchain-core, langchain-community och en rad leverantörsspecifika paket som langchain-anthropic. Uppdelningen finns av en bra anledning: den håller kärnpaketet litet och snabbt att installera, medan tunga eller sällan använda integrationer bara dras in när du faktiskt behöver dem. När du väl har sett mönstret en gång blir det enkelt att gissa vilket paket en viss klass bor i.

RAG, retrieval augmented generation, löser ett grundläggande problem med språkmodeller: de vet bara det de tränats på, och de hittar på svar när de saknar fakta. Genom att hämta relevanta textstycken ur en egen dokumentsamling och lägga in dem i prompten innan modellen svarar, tvingar du fram svar som grundar sig i verkliga källor istället för gissningar. Mönstret kallas ofta “agentisk RAG” när modellen själv får bestämma om, när och var den ska söka, snarare än att sökningen sker i ett fast första steg.

Det som gör hösten 2026 till ett bra tillfälle att bygga det här är kombinationen av mogen tooling och billigare modeller. LangChain 1.4 är den första stabila utgåvan med ett förstapartsstöd för MCP i namnrymden langchain.mcp, vilket gör det enklare att koppla in externa datakällor som verktyg utan att skriva egna adaptrar. Samtidigt har priskonkurrensen mellan OpenAI, Anthropic, Google och kinesiska leverantörer som DeepSeek och Alibaba pressat ner kostnaden per miljon token rejält jämfört med för ett år sedan.

Förkunskaper och verktyg du behöver innan du börjar

Du behöver grundläggande Python-kunskap för att följa guiden, men du behöver inte ha jobbat med LangChain eller vektordatabaser tidigare. Räkna med cirka 90 minuter för att gå igenom samtliga steg om du kopierar kodblocken direkt, eller en förmiddag om du vill förstå varje rad innan du kör den. Se till att följande finns på plats innan du börjar med steg 1.

Verktyg / paketVersionSyfte i den här guiden
Python3.11 eller senareKörmiljö för hela projektet
langchain1.4.0 (stabil, släppt 3 september 2026)Huvudramverk för kedjor och agenter
langchain-core1.6.2Grundläggande abstraktioner som LCEL bygger på
langchain-communitysenaste versionenDokumentladdare och community-integrationer
langchain-anthropicsenaste versionenKoppling mot Claude Fable 5.1
chromadbsenaste versionenLokal vektordatabas för embeddings
sentence-transformerssenaste versionenGratis, lokala embeddings utan API-kostnad
fastapi + uvicornsenaste versionenValfritt webb-API för agenten i produktion

Du behöver också minst ett API-konto för en molnmodell om du vill följa avsnittet om Claude Fable 5.1, men hela grundguiden går att genomföra helt gratis med en lokal, öppen modell som Qwen3.8-27B via Ollama. Har du en dator med minst 16 GB RAM räcker det gott för den delen av guiden, även om en dedikerad GPU med minst 24 GB VRAM ger märkbart snabbare svar när modellen faktiskt genererar text.

Ett vanligt nybörjarmisstag är att blanda ihop kraven för embeddings med kraven för själva språkmodellen. Embeddingmodellen all-MiniLM-L6-v2 som används i den här guiden är liten nog att köra på i stort sett vilken bärbar dator som helst, även utan GPU. Det är bara när du växlar till en stor lokal chattmodell som Qwen3.8-27B som hårdvarukraven blir en faktor att räkna med på allvar.

Steg 1–2: Installera LangChain och sätt upp projektstrukturen

Börja med att skapa en isolerad Python-miljö. Det undviker att versionskonflikter mellan olika LangChain-paket stör andra projekt på din dator, vilket är en av de vanligaste källorna till konstiga felmeddelanden i det här ekosystemet.

mkdir langchain-rag-agent && cd langchain-rag-agent
python3 -m venv .venv
source .venv/bin/activate

pip install --upgrade pip
pip install langchain langchain-core langchain-community \
    langchain-anthropic chromadb sentence-transformers \
    python-dotenv fastapi uvicorn

mkdir data
echo "ANTHROPIC_API_KEY=din-nyckel-har" > .env

Lägg sedan dina egna dokument, till exempel PDF-filer, markdown-filer eller textexporter från en kunskapsbas, i mappen data. I exemplen nedan används ett par textfiler, men samma kod fungerar för PDF med paketet pypdf installerat separat. Byt då bara ut TextLoader mot PyPDFLoader och glob-mönstret från **/*.txt till **/*.pdf, resten av koden i guiden fungerar oförändrat eftersom alla laddare i LangChain returnerar samma typ av dokumentobjekt.

Steg 3–4: Ladda in dokument och dela upp dem i chunkar

Nästa steg är att läsa in dokumenten och dela upp dem i mindre bitar, chunkar, som är lagom stora för embeddings och sökning. För långa chunkar gör svaren diffusa, för korta chunkar tappar modellen sammanhang mellan meningar.

from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

loader = DirectoryLoader("data", glob="**/*.txt", loader_cls=TextLoader)
raw_documents = loader.load()

splitter = RecursiveCharacterTextSplitter(
    chunk_size=800,
    chunk_overlap=120,
    separators=["\n\n", "\n", ". ", " "],
)
chunks = splitter.split_documents(raw_documents)

print(f"Laddade {len(raw_documents)} dokument, delade upp i {len(chunks)} chunkar")

Värdet 800 tecken per chunk med 120 tecken överlapp är en rimlig startpunkt för svensk löptext. Överlappet gör att en mening som klipps av vid en chunkgräns ändå finns hel i nästa chunk, vilket minskar risken att retrieval-steget missar rätt information.

Steg 5–6: Bygg vektordatabasen med Chroma och embeddings

Med texten uppdelad är nästa steg att omvandla varje chunk till en vektor, ett embedding, och spara den i en lokal vektordatabas. Chroma är ett bra förstahandsval eftersom det körs helt lokalt utan extern tjänst, och sentence-transformers ger dig embeddings utan att betala per anrop.

Embeddings är i grunden bara listor av tal som representerar textens betydelse geometriskt, så att frågor och dokument som handlar om samma sak hamnar nära varandra i det matematiska rummet. Modellen all-MiniLM-L6-v2 är liten och snabb, vilket gör den till ett bra förstaval, men om dina dokument innehåller mycket teknisk svensk terminologi kan det löna sig att senare testa en flerspråkig embeddingmodell och jämföra träffsäkerheten innan du låser fast valet i produktion.

from langchain_huggingface import HuggingFaceEmbeddings
from langchain_chroma import Chroma

embeddings = HuggingFaceEmbeddings(
    model_name="sentence-transformers/all-MiniLM-L6-v2"
)

vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db",
)

retriever = vectorstore.as_retriever(search_kwargs={"k": 4})

Parametern k=4 styr hur många chunkar som hämtas per fråga. Fyra är en vanlig startpunkt, men höj den till 6-8 om dina dokument är korta och du märker att agenten missar relevant kontext, eller sänk den om svaren blir för långa och pratiga.

Steg 7–8: Skapa retrieval-kedjan med LCEL

LCEL, LangChain Expression Language, är sättet moderna LangChain-kedjor byggs på. Istället för klassernas gamla Chain-objekt kopplar du ihop komponenter med pipe-operatorn |, ungefär som ett Unix-kommando. Resultatet är lättare att läsa och enklare att streama.

from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

llm = ChatAnthropic(model="claude-fable-5-1", temperature=0)

prompt = ChatPromptTemplate.from_template(
    """Svara på frågan enbart utifrån kontexten nedan.
Om svaret inte finns i kontexten, säg att du inte vet.

Kontext:
{context}

Fråga: {question}"""
)

def format_docs(docs):
    return "\n\n".join(d.page_content for d in docs)

rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

print(rag_chain.invoke("Vad säger dokumenten om leveranstider?"))

Lägg märke till temperature=0. För RAG-svar vill du ha så deterministiska svar som möjligt, inte kreativa omskrivningar av fakta som redan finns i kontexten. Instruktionen i prompten om att säga “jag vet inte” när svaret saknas är minst lika viktig som modellvalet för att hålla nere hallucinationer.

LCEL-notationen ger dig samma kedja i tre former utan extra kod: invoke() för ett enskilt svar, stream() för token-för-token-utdata, och batch() för att köra flera frågor parallellt. Den sistnämnda är användbar när du till exempel vill testa kedjan mot ett helt frågebatteri under utveckling, istället för att loopa igenom frågorna en och en i egen kod.

Steg 9–10: Lägg till minne och streaming i konversationen

En enskild fråga och svar är sällan hela användningsfallet. De flesta vill ha en konversation där agenten kommer ihåg vad som sagts tidigare, och där svaret börjar synas medan modellen fortfarande genererar text, inte först när hela svaret är klart.

from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory

store = {}

def get_history(session_id: str):
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]

chain_with_memory = RunnableWithMessageHistory(
    rag_chain,
    get_history,
    input_messages_key="question",
    history_messages_key="history",
)

for chunk in rag_chain.stream("Sammanfatta huvudpunkterna i dokumenten"):
    print(chunk, end="", flush=True)

InMemoryChatMessageHistory räcker för utveckling och demo, men den försvinner när processen startas om. För en agent som ska köras i produktion, byt ut den mot en historik som sparas i Redis eller en databas, annars tappar användarna hela sin konversation vid varje omstart av tjänsten.

Streaming är särskilt viktigt för användarupplevelsen när du kör en tyngre modell eller skickar med mycket kontext. Ett anrop som tar fem sekunder känns trögt om användaren stirrar på en tom skärm, men känns snabbt om texten börjar rulla in efter några hundra millisekunder. Håller du dig till LCEL får du stream()-metoden på köpet utan extra kod, oavsett om du kör mot Claude Fable 5.1 eller en lokal Qwen-modell.

Steg 11: Bygg en agent med verktygsanrop och LangGraph

En ren RAG-kedja söker alltid i samma vektordatabas. En agent kan istället välja mellan flera verktyg beroende på frågan, till exempel söka i dokumenten, slå upp aktuell information på webben, eller köra en beräkning. LangGraph, som numera levereras tätt integrerat med LangChain, är standardsättet att bygga den typen av beslutslogik.

from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent

@tool
def sok_i_dokument(fraga: str) -> str:
    """Sök efter relevant information i den lokala dokumentsamlingen."""
    docs = retriever.invoke(fraga)
    return format_docs(docs)

@tool
def rakna(uttryck: str) -> str:
    """Utvärdera ett enkelt matematiskt uttryck, till exempel '12 * 4'."""
    try:
        return str(eval(uttryck, {"__builtins__": {}}))
    except Exception as exc:
        return f"Kunde inte räkna ut uttrycket: {exc}"

agent = create_react_agent(llm, tools=[sok_i_dokument, rakna])

result = agent.invoke(
    {"messages": [("user", "Hur många enheter beställdes enligt dokumenten, och vad blir det gånger 1,25 i påslag?")]}
)
print(result["messages"][-1].content)

Notera att exemplet med eval är medvetet begränsat med en tom __builtins__-dict för att undvika att agenten kan köra godtycklig Python-kod. Ett riktigt räkneverktyg i produktion bör byggas med ett dedikerat matematikbibliotek istället för eval i någon form.

create_react_agent bygger på ReAct-mönstret (reason and act), där modellen växlar mellan att resonera i text och att anropa ett verktyg, tolka resultatet, och resonera vidare. Det är samma grundmönster som ligger bakom de flesta kommersiella agentprodukter idag, oavsett om de kallar det något annat i sin egen dokumentation. Fördelen med att bygga det själv med LangGraph är att du ser och kan styra varje steg i loopen, istället för att lita på en svart låda.

Steg 12–13: Koppla in Claude Fable 5.1 eller den öppna modellen Qwen3.8-27B

Ett av de starkaste argumenten för LangChain är att du kan byta modell utan att skriva om agentlogiken. Exemplen ovan använder Claude Fable 5.1, som Anthropic gjorde allmänt tillgänglig den 1 september 2026 till samma pris som föregångaren Fable 5: 10 dollar per miljon indata-token och 50 dollar per miljon utdata-token, enligt Anthropics egen dokumentation. Samma dag släppte Anthropic även Claude Mythos 5.1, en variant beskriven som en “trusted-access twin” med striktare åtkomstkontroll, tänkt för mer känsliga användningsfall.

Vill du köra samma agent helt lokalt och gratis är Qwen3.8-27B ett starkt alternativ. Modellen är öppen (open-weight), släpptes i slutet av augusti 2026, och nådde enligt oberoende mätningar samma poäng, 52, på “AA Intelligence Index” som OpenAI:s GPT-5.6 Luna, trots att den går att köra på egen hårdvara. Byt bara ut modellraden för att växla mellan de två.

Ett tredje alternativ värt att nämna är Gemini 3.8 Flash Cyber, en säkerhetsinriktad variant som Google DeepMind släppte samtidigt med huvudmodellen den 2-3 september 2026. Den är specialbyggd för uppgifter som logganalys och kodgranskning, vilket gör den till ett intressant val om din RAG-agent främst ska läsa säkerhetsdokumentation eller granska kod snarare än att svara på allmänna kunskapsfrågor.

# Molnalternativ: Claude Fable 5.1 (kräver ANTHROPIC_API_KEY)
llm = ChatAnthropic(model="claude-fable-5-1", temperature=0)

# Lokalt och gratis alternativ: Qwen3.8-27B via Ollama
# Kör "ollama pull qwen3.8:27b" i terminalen först
from langchain_ollama import ChatOllama
llm = ChatOllama(model="qwen3.8:27b", temperature=0)
ModellTypPris / 1M tokenKontextfönsterSläppt
Claude Fable 5.1Molnbaserad (API)10 dollar in / 50 dollar utStort kontextfönster (Anthropic)1 september 2026
Gemini 3.8 FlashMolnbaserad (API)Lägre än föregångaren, prissänkning vid lanseringOptimerad för snabba svar2-3 september 2026
GPT-5.6 SolMolnbaserad (API)20 procent billigare än tidigare OpenAI-generationerStandard för GPT-5.6-familjen23 augusti 2026
Qwen3.8-27BÖppen (self-host)Gratis, kräver egen hårdvaraKonkurrenskraftigt för sin storlekSlutet av augusti 2026
DeepSeek V4 Pro 0813Molnbaserad + öppna vikterKonkurrenskraftigt jämfört med GPT/ClaudeStort kontextfönster13 augusti 2026

DeepSeek V4 Pro 0813 är värd att nämna särskilt för kodtunga agenter. Enligt öppna benchmarkresultat förbättrade uppdateringen resultatet på DeepSWE-testet till 62,7 poäng, en ökning med 49,9 poäng jämfört med förhandsversionen, vilket gör den till ett starkt val om din agent främst ska analysera eller skriva kod snarare än att svara på dokumentfrågor. Vill du läsa mer om hur du bygger agenter direkt mot DeepSeeks API finns en separat genomgång av DeepSeek V4-Flash för agentbygge här på sajten.

Ett komplett fungerande projekt: hela koden i en fil

Nedan är samtliga steg samlade i en enda körbar fil. Spara den som main.py i projektmappen och kör den med python main.py efter att du lagt textfiler i mappen data.

import os
from dotenv import load_dotenv
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_chroma import Chroma
from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

load_dotenv()

def build_agent(data_dir: str = "data"):
    loader = DirectoryLoader(data_dir, glob="**/*.txt", loader_cls=TextLoader)
    chunks = RecursiveCharacterTextSplitter(
        chunk_size=800, chunk_overlap=120
    ).split_documents(loader.load())

    embeddings = HuggingFaceEmbeddings(
        model_name="sentence-transformers/all-MiniLM-L6-v2"
    )
    retriever = Chroma.from_documents(
        chunks, embeddings, persist_directory="./chroma_db"
    ).as_retriever(search_kwargs={"k": 4})

    llm = ChatAnthropic(model="claude-fable-5-1", temperature=0)
    prompt = ChatPromptTemplate.from_template(
        "Svara enbart utifrån kontexten. Säg ifrån om svaret saknas.\n\n"
        "Kontext:\n{context}\n\nFråga: {question}"
    )

    def format_docs(docs):
        return "\n\n".join(d.page_content for d in docs)

    return (
        {"context": retriever | format_docs, "question": RunnablePassthrough()}
        | prompt
        | llm
        | StrOutputParser()
    )

if __name__ == "__main__":
    agent = build_agent()
    while True:
        question = input("\nFråga (eller 'exit'): ")
        if question.strip().lower() == "exit":
            break
        for chunk in agent.stream(question):
            print(chunk, end="", flush=True)

Exempel på hur en körning ser ut i terminalen:

Fråga (eller 'exit'): Vad säger dokumenten om leveranstider?
Enligt dokumenten är den normala leveranstiden 3-5 arbetsdagar
inom Sverige, med möjlighet till expressleverans nästa dag mot
en tilläggsavgift. Vid högsäsong i november-december kan
leveranstiden förlängas till 7-10 arbetsdagar.

Fråga (eller 'exit'): exit

Så räknar du ut vad din RAG-agent faktiskt kommer kosta

Innan du bygger vidare mot produktion lönar det sig att räkna på kostnaden i förväg, istället för att bli överraskad av första fakturan. Räkna med genomsnittligt antal token per fråga, inklusive den hämtade kontexten, multiplicerat med förväntad frågevolym per månad.

Säg att din agent hanterar 10 000 frågor i månaden, där varje fråga i snitt skickar med 2 000 token indata (frågan plus fyra hämtade chunkar) och genererar 500 token utdata. Med Claude Fable 5.1:s pris på 10 dollar per miljon indata-token och 50 dollar per miljon utdata-token blir uträkningen: 10 000 × 2 000 ÷ 1 000 000 × 10 dollar = 200 dollar för indata, plus 10 000 × 500 ÷ 1 000 000 × 50 dollar = 250 dollar för utdata. Totalt landar du på ungefär 450 dollar i månaden innan eventuell prompt-caching räknats av.

Kör du istället Qwen3.8-27B lokalt blir den löpande kostnaden i praktiken elförbrukningen och avskrivningen på hårdvaran, men du binder upp kapital i förväg istället för att betala per token. För ett litet till medelstort team med sporadisk användning är API-vägen oftast billigare totalt sett. Går volymen upp mot flera hundra tusen frågor i månaden börjar den egna hårdvaran istället löna sig, särskilt om du redan har en GPU-server för annat.

Räkna alltid om dollarbeloppen till kronor innan du presenterar en kostnadskalkyl för en beslutsfattare i Sverige. Växelkursen mellan dollar och krona rör sig tillräckligt mycket över ett år för att en budget som ser rimlig ut i september kan behöva justeras till våren. Bygg därför in en marginal på minst 15-20 procent i din kalkyl om agenten ska drivas löpande under en längre period, snarare än att räkna på dagens kurs som om den vore fast.

Så utvärderar du om din RAG-agent faktiskt svarar rätt

Att agenten svarar snabbt och låter säker på sig själv säger ingenting om svaret faktiskt stämmer. Bygg därför ett litet facit tidigt: en lista med 20-30 typiska frågor och deras korrekta svar, hämtade direkt ur dina egna dokument. Kör den listan igenom agenten varje gång du ändrar chunkstorlek, k-värde eller modell, och jämför resultatet manuellt eller med ett automatiserat kontrollskript.

Två mått är särskilt användbara i praktiken. Det första är “retrieval hit rate”: hur ofta rätt chunk faktiskt finns bland de som hämtas, oavsett vad modellen sedan svarar. Det andra är “faithfulness”, alltså om modellens svar håller sig till den hämtade kontexten eller om den lägger till egen information som inte finns där. LangSmith kan logga båda måtten automatiskt om du kopplar in det enligt avsnittet om observability längre ner, men du kan lika gärna börja med ett enkelt Python-skript som jämför nyckelord i facit mot agentens svar.

Gör du den här utvärderingen en gång per sprint istället för en gång vid lansering fångar du regressionsfel tidigt, till exempel när en ny embeddingmodell av misstag försämrar träffsäkerheten för vissa frågetyper trots att den presterar bättre i genomsnitt.

Vanliga fallgropar när du bygger RAG-agenter

De flesta som bygger sin första RAG-agent stöter på samma handfull misstag, oavsett om de använder LangChain, LlamaIndex eller ett eget hemsnickrat lager ovanpå ett API. Här är de som dyker upp oftast, och varför de gör svaren sämre än de borde vara.

  • Fast chunkstorlek utan överlapp. Klipper du dokumenten i exakt lika stora bitar utan överlapp riskerar du att en mening delas mitt itu, vilket gör att retrieval-steget missar sammanhanget.
  • Ingen metadata på chunkarna. Utan filnamn, sidnummer eller datum sparat som metadata blir det omöjligt för agenten att ange källa, och svårt att felsöka när svaret blir fel.
  • Glömd temperature=0. Standardvärdet på de flesta modeller ger kreativa, varierande svar. För fakta ur dokument vill du ha så förutsägbara svar som möjligt.
  • För högt k-värde i retrievern. Hämtar du 15-20 chunkar per fråga fyller du kontextfönstret med brus, vilket både höjer kostnaden och gör svaren mer diffusa.
  • Ingen felhantering vid API-timeout. Molnmodeller svarar inte alltid inom förväntad tid. Utan timeout och återförsök kraschar hela agenten på ett enda långsamt anrop.
  • Samma Chroma-databas i dev och produktion. Testdata blandas lätt in i produktionssvaren om du inte håller separata persist_directory-mappar för olika miljöer.
  • Ingen gräns på verktygsanrop i agent-loopen. En agent utan recursion_limit kan fastna i en loop där den anropar samma verktyg om och om igen utan att någonsin svara användaren.

Gemensamt för nästan alla dessa misstag är att de syns tydligast först när volymen ökar. En demo med tre testfrågor avslöjar sällan att k-värdet är för högt eller att minneshanteringen läcker, det gör en produktionsmiljö med hundratals användare desto snabbare. Bygg därför in loggning och den utvärderingsprocess som beskrivs ovan redan innan du lanserar, inte som en eftertanke när något redan gått fel.

Felsökning: nio vanliga problem och lösningar

Stöter du på något av följande fel är du långt ifrån ensam, de dyker upp i stort sett varenda LangChain-forum och GitHub-issue-tråd. Tabellen nedan går igenom de vanligaste felen, den troliga orsaken, och hur du löser dem, sorterat ungefär efter hur ofta de faktiskt inträffar i praktiken.

ProblemTrolig orsakLösning
ModuleNotFoundError: langchain_communityUnderpaketet är separat sedan LangChain delade upp sig i flera paketInstallera specifikt med pip install langchain-community
Chroma ger “no such column” eller schemafelGammal databasfil från en tidigare Chroma-versionRadera mappen chroma_db och bygg om vektordatabasen
429 Too Many Requests från API:etFör många anrop för snabbt mot leverantörens gränsLägg in exponentiell backoff och sänk samtidiga anrop
Embeddings tar väldigt lång tidKörs på CPU istället för GPU, eller för stora batcharMinska batchstorlek eller kör på maskin med GPU-stöd
Agenten loopar utan att svaraInget tak på antal verktygsanropSätt recursion_limit i konfigurationen för agenten
Svaret är fel trots att dokumentet finnsRetrievern hämtar fel chunkar, ofta för lågt k-värdeHöj k stegvis och granska vilka chunkar som faktiskt hämtas
UnicodeDecodeError vid inläsningTextfil sparad i annan teckenkodning än UTF-8Ange encoding="utf-8" explicit i TextLoader
SSL-certifikatfel bakom företagsproxyFöretagets brandvägg mellanhandsavlyssnar HTTPS-trafikPeka REQUESTS_CA_BUNDLE mot företagets certifikat
Minnet växer under en lång konversationHela historiken skickas med i varje anrop utan trimningTrimma historiken till senaste N meddelanden eller sammanfatta äldre delar

Ett generellt råd som täcker flera av dessa fel samtidigt: skriv ut mellanresultat, inte bara det slutgiltiga svaret, medan du felsöker. Se vilka chunkar som faktiskt hämtades, vilket verktyg agenten valde, och vilken prompt som till slut skickades till modellen. De flesta av felen ovan är i praktiken enkla att lösa, det tar bara onödigt lång tid att hitta dem om du bara har det slutgiltiga svaret att gå på.

Avancerade tips för produktion

Caching och kostnadsoptimering

Skickar din agent liknande frågor eller samma systemprompt om och om igen, aktivera prompt-caching hos modell-leverantören om det stöds. Det sänker kostnaden markant för de delar av prompten som återkommer mellan anrop, som systeminstruktioner och ofta återanvänd kontext. Kombinera det med att cacha embeddings lokalt så att samma dokument inte omvandlas till vektorer flera gånger. Vill du gå djupare på kostnadsoptimering mot en specifik leverantör finns en separat genomgång av Claude API som går igenom prissättning i detalj.

Observability med LangSmith och MCP

Koppla in LangSmith för att se exakt vilka chunkar som hämtades, vilket verktyg agenten valde, och hur lång tid varje steg tog. Utan den insynen blir felsökning i produktion gissningslek. Vill du experimentera med bredare integrationer, testa alfaversionen av langchain.mcp, tillgänglig sedan den 1 september 2026, som gör att externa MCP-servrar kan exponeras som vanliga LangChain-verktyg utan egen adapterkod. Samma protokoll används i grunden av den tidigare guiden om Kimi K3 och MCP här på sajten, om du vill jämföra två olika sätt att bygga MCP-kopplade agenter.

Skalning till flera samtidiga användare

Exemplen i den här guiden håller allt i en enda process, vilket räcker för utveckling men blir en flaskhals så fort fler än en person använder agenten samtidigt. Wrappa kedjan i en FastAPI-tjänst och kör den bakom flera arbetsprocesser med uvicorn --workers, så att inte alla förfrågningar köar bakom en enda Python-tråd. Håll också Chroma-instansen som en delad, långlivad process istället för att öppna om databasfilen för varje förfrågan, annars blir diskläsningen själv en flaskhals när trafiken ökar.

Säkerhet: skydda din agent mot prompt injection och dataläckage

En RAG-agent som hämtar text från dokument du inte fullt kontrollerar är sårbar för prompt injection, där ett dokument innehåller instruktioner riktade mot modellen snarare än mot en mänsklig läsare. OWASP:s topplista för LLM-applikationer rankar just den här risken som en av de allvarligaste för produktionssatta AI-system, tillsammans med okontrollerad dataexfiltrering och överdrivet agentbeteende.

RiskBeskrivningÅtgärd i din agent
Prompt injection via dokumentEtt inläst dokument innehåller dolda instruktioner till modellenBehandla hämtad text som data, inte som instruktioner, i systemprompten
DataexfiltreringAgenten luras att skicka känslig kontext till ett externt verktygBegränsa vilka verktyg som får nätverksåtkomst och logga alla anrop
Överdrivet agentbeteendeAgenten får för breda rättigheter, som filsystemåtkomst utan gränserGe varje verktyg minsta möjliga behörighet, principen om minsta privilegium
Osäker verktygsutdataUtdata från ett verktyg körs eller tolkas okritiskt av nästa stegValidera och sanera all verktygsutdata innan den återanvänds
Läckage av hemligheter i loggarAPI-nycklar eller interna dokument hamnar i loggar eller svarMaska hemligheter i loggning och granska svar innan de visas för användare

Det enklaste konkreta skyddet är att aldrig låta text som hämtas från dokument tolkas som systeminstruktioner. Bygg prompten så att hämtad kontext alltid ligger tydligt avgränsad, gärna inom egna avgränsare i texten, och instruera modellen att endast behandla den som referensmaterial. Kombinerar du det med begränsade verktygsrättigheter enligt tabellen ovan minskar du risken avsevärt utan att komplicera koden nämnvärt. Fler mönster för att stoppa injektionsattacker mot en modells API finns i guiden om att köra öppna modeller lokalt med Ollama, där hela anropskedjan stannar på egen hårdvara.

Tänk också på källgranskning som en del av säkerhetsarbetet, inte bara som en trevlig funktion. Låter du agenten alltid ange vilket dokument och vilken chunk ett svar grundar sig på blir det lättare för en människa att upptäcka om modellen har blandat ihop eller hittat på något, innan svaret skickas vidare till en kund eller används i ett beslut.

Vill du hålla dig uppdaterad på vilka öppna modeller som är värda att testa i en agent, håll ett öga på den löpande genomgången av Qwen3.8 och andra kinesiska AI-modeller och den bredare bevakningen av AI och maskininlärning här på sajten.

Vanliga frågor

Måste jag använda Claude Fable 5.1, eller fungerar guiden med andra modeller?

Guiden fungerar med i stort sett vilken chattmodell som helst som har en LangChain-integration, inklusive GPT-5.6, Gemini 3.8 Flash och öppna alternativ som Qwen3.8-27B eller DeepSeek V4 Pro. Byt bara ut raden som skapar llm-objektet mot rätt klass och modellnamn för din leverantör.

Kan jag köra hela projektet utan att betala för något API?

Ja. Använd sentence-transformers för embeddings och en lokal modell som Qwen3.8-27B via Ollama istället för Claude Fable 5.1. Den enda kostnaden blir då elräkningen för att köra modellen lokalt, förutsatt att din dator har tillräckligt med RAM.

Vad är skillnaden mellan en RAG-kedja och en RAG-agent?

En kedja söker alltid på samma fasta sätt, oavsett fråga. En agent, byggd med till exempel LangGraph, kan själv avgöra om den ska söka i dokumenten, använda ett annat verktyg, eller svara direkt utan att söka alls. Agenter är mer flexibla men också svårare att göra helt förutsägbara.

Hur stor dokumentsamling klarar den här uppsättningen?

Chroma i sin lokala, filbaserade form hanterar utan problem tiotusentals chunkar på en vanlig utvecklingsdator. Växer samlingen till miljontals dokument bör du istället titta på en dedikerad vektordatabas med kluster-stöd, men för de flesta interna kunskapsbaser, som en supportavdelnings dokumentation eller ett mindre företags policydokument, räcker uppsättningen i den här guiden gott utan ändringar.

Varför får jag ibland “jag vet inte” trots att informationen finns i dokumenten?

Oftast beror det på att retrievern inte hämtade rätt chunk, inte att modellen missade informationen den fick. Höj k-värdet, granska chunkstorleken, och skriv ut vilka chunkar som faktiskt hämtas för en given fråga innan du felsöker vidare i prompten.

Är MCP-stödet i LangChain 1.4 stabilt att använda i produktion?

Nej, stödet i langchain.mcp är i skrivande stund en alfaversion, tillgänglig sedan 1 september 2026. Använd det gärna för att experimentera och utvärdera, men räkna med att gränssnittet kan ändras innan det når en stabil utgåva.

Hur skiljer sig kostnaden mellan Claude Fable 5.1 och Qwen3.8-27B i praktiken?

Claude Fable 5.1 kostar 10 dollar per miljon indata-token och 50 dollar per miljon utdata-token via API. Qwen3.8-27B är gratis att ladda ner och köra, men kräver egen hårdvara med tillräckligt med minne för att hålla en 27-miljarders modell i minnet. Vilket alternativ som är billigast beror helt på hur mycket du redan investerat i egen hårdvara jämfört med hur ofta agenten faktiskt används.

Behöver jag LangGraph, eller räcker en enkel LCEL-kedja?

Om agenten bara ska svara på frågor ur ett dokumentarkiv räcker en LCEL-kedja gott, och den är enklare att felsöka eftersom flödet alltid går samma väg. LangGraph blir värdefullt först när agenten behöver välja mellan flera verktyg, fatta flerstegsbeslut, eller hålla ett tillstånd som förändras under konversationens gång. Många team börjar med en ren LCEL-kedja i produktion och lägger till LangGraph först när ett konkret behov av grenande logik dyker upp, snarare än att bygga in komplexiteten från dag ett.