LangChain / RAG / vectordatabases · Les

Query's verwerken en antwoorden genereren

Ontwikkel de logica voor het verwerken van gebruikersquery's, het ophalen van relevante context en het samenstellen van antwoorden met de LLM.

Les 2 van 411 stappen

Query's verwerken en antwoorden genereren is een gratis LangChain / RAG / vectordatabases-les op CoddyKit. Dit is les 2 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject LangChain / RAG / vectordatabases. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus LangChain / RAG / vectordatabases bevat in totaal 4 lessen.

RAG bevragen: de antwoordstroom

Nadat je de RAG-componenten hebt geïntegreerd, is de volgende stap ze te gebruiken om vragen van gebruikers te beantwoorden. In deze les behandelen we het volledige proces, van de vraag van een gebruiker tot een gegenereerd antwoord.

We richten ons op de logica tijdens het bevragen: hoe je systeem een vraag verwerkt, relevante context vindt en met een LLM een samenhangend antwoord samenstelt.

De vraag van de gebruiker begrijpen

Een RAG-systeem begint met een vraag van de gebruiker, net als een zoekmachine. Deze onbewerkte invoer zet het hele proces in gang.

  • De vraag bepaalt welke informatie moet worden opgehaald.
  • De vraag stuurt de LLM bij het bepalen van het soort antwoord dat moet worden gegenereerd.

In deze eerste fase is doorgaans geen speciale opmaak nodig; het is gewoon platte tekst.

Je zoeker instellen

Om relevante documenten te vinden, heb je een zoeker nodig. Deze component weet hoe je de vectoropslagplaats moet bevragen. Je haalt de zoeker doorgaans op uit je VectorStore-instantie.

De methode as_retriever() maakt deze component aan. Je kunt parameters instellen, zoals k (het aantal op te halen topdocumenten).

from langchain_community.vectorstores import InMemoryVectorStore
from langchain_core.documents import Document
from langchain_core.embeddings import Embeddings
from typing import List

# A simple mock for embeddings
class MockEmbeddings(Embeddings):
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return [[i * 0.1] * 10 for i in range(len(texts))]
    def embed_query(self, text: str) -> List[float]:
        return [0.5] * 10

def main():
    # Create a dummy vector store with some content
    embeddings = MockEmbeddings()
    docs = [
        Document(page_content="The capital of France is Paris.", metadata={"source": "wiki"}),
        Document(page_content="Eiffel Tower is in Paris, France.", metadata={"source": "travel"})
    ]
    vectorstore = InMemoryVectorStore.from_documents(docs, embeddings)

    # Create a retriever from the vector store
    retriever = vectorstore.as_retriever(search_kwargs={"k": 1})
    print("Retriever created successfully!")

if __name__ == "__main__":
    main()

Contextuele documenten ophalen

Zodra je een zoeker hebt, kun je deze aanroepen met de vraag van de gebruiker. De zoeker voert een overeenkomstzoekactie uit in je vectoropslagplaats en geeft de meest relevante Document-objecten terug.

Deze documenten vormen de context die aan de LLM wordt doorgegeven.

from langchain_community.vectorstores import InMemoryVectorStore
from langchain_core.documents import Document
from langchain_core.embeddings import Embeddings
from typing import List

class MockEmbeddings(Embeddings):
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return [[i * 0.1] * 10 for i in range(len(texts))]
    def embed_query(self, text: str) -> List[float]:
        return [0.5] * 10

def main():
    embeddings = MockEmbeddings()
    docs = [
        Document(page_content="The capital of France is Paris.", metadata={"source": "wiki"}),
        Document(page_content="Eiffel Tower is in Paris, France.", metadata={"source": "travel"}),
        Document(page_content="London is the capital of the UK.", metadata={"source": "wiki"})
    ]
    vectorstore = InMemoryVectorStore.from_documents(docs, embeddings)
    retriever = vectorstore.as_retriever(search_kwargs={"k": 2})

    user_query = "What is the capital of France?"
    retrieved_docs = retriever.invoke(user_query)

    print(f"Retrieved {len(retrieved_docs)} documents:")
    for doc in retrieved_docs:
        print(f"- {doc.page_content[:50]}...")

if __name__ == "__main__":
    main()

Context voorbereiden voor de LLM

LLM's hebben doorgaans liever één tekenreeks als context. De opgehaalde Document-objecten moeten worden samengevoegd tot een samenhangende indeling.

Een gebruikelijke aanpak is om hun velden page_content samen te voegen, eventueel met scheidingstekens, en desgewenst bronmetadata toe te voegen.

  • Zorgt ervoor dat alle context binnen het tokenvenster van de LLM past.
  • Levert een overzichtelijke invoer waarop de LLM kan redeneren.

De RAG-prompt opstellen

De promptsjabloon is cruciaal. Deze geeft de LLM instructies over het gebruik van de verstrekte context om de vraag van de gebruiker te beantwoorden. De sjabloon bevat doorgaans tijdelijke aanduidingen voor zowel context als question.

Een goed ontworpen prompt stuurt de LLM naar een feitelijk antwoord en helpt hallucinaties te voorkomen.

from langchain_core.prompts import ChatPromptTemplate

def main():
    # Define a RAG-specific prompt template
    rag_prompt = ChatPromptTemplate.from_messages([
        ("system", "You are an AI assistant for Q&A. Use the context to answer. If you don't know, say that you don't know."),
        ("human", "Context: {context}\nQuestion: {question}")
    ])

    print("RAG Prompt Template created!")
    # Example of how it formats:
    # print(rag_prompt.format(context="some info", question="a query"))

if __name__ == "__main__":
    main()

De generatiemotor verbinden

De laatste stap bij het genereren van een antwoord is de voorbereide context en de vraag van de gebruiker doorgeven aan een Large Language Model. Met LangChain kun je eenvoudig verschillende LLM-providers aansluiten.

Voor dit voorbeeld gebruiken we een nagebootste LLM om de integratie te demonstreren zonder dat je een API-sleutel nodig hebt.

from langchain_core.language_models import BaseChatModel
from langchain_core.messages import BaseMessage, AIMessage
from typing import List, Any

# A simple mock LLM
class MockChatLLM(BaseChatModel):
    def invoke(self, input: Any, config: Any = None) -> BaseMessage:
        # Simulate LLM response based on input
        if "Paris" in str(input):
            return AIMessage(content="Paris is the capital of France.")
        elif "London" in str(input):
            return AIMessage(content="London is the capital of the UK.")
        else:
            return AIMessage(content="I don't have enough info to answer.")

    async def ainvoke(self, input: Any, config: Any = None) -> BaseMessage:
        return self.invoke(input, config) # Simple async pass-through

    @property
    def _llm_type(self) -> str:
        return "mock-chat-llm"

def main():
    llm = MockChatLLM()
    print("Mock LLM initialized!")

    # Example invocation (not part of the RAG chain yet)
    response = llm.invoke("Tell me about Paris.")
    print(f"LLM Response: {response.content}")

if __name__ == "__main__":
    main()

De volledige RAG-keten samenstellen

Nu combineren we de zoeker, promptsjabloon en LLM met LangChain Expression Language (LCEL) om een krachtige, flexibele RAG-keten te maken. Deze keten verwerkt de volledige stroom.

We gebruiken RunnablePassthrough om invoer te beheren en StrOutputParser om het uiteindelijke tekstantwoord te extraheren.

from langchain_core.runnables import RunnablePassthrough, RunnableLambda
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.documents import Document
from langchain_community.vectorstores import InMemoryVectorStore
from langchain_core.embeddings import Embeddings
from langchain_core.language_models import BaseChatModel
from langchain_core.messages import BaseMessage, AIMessage
from typing import List, Any

# Mock Embeddings
class MockEmbeddings(Embeddings):
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return [[i * 0.1] * 10 for i in range(len(texts))]
    def embed_query(self, text: str) -> List[float]:
        return [0.5] * 10

# Mock LLM
class MockChatLLM(BaseChatModel):
    def invoke(self, input: Any, config: Any = None) -> BaseMessage:
        input_str = str(input)
        if "Paris" in input_str and "capital of France" in input_str:
            return AIMessage(content="Based on context, Paris is the capital of France.")
        elif "Eiffel Tower" in input_str and "Paris" in input_str:
            return AIMessage(content="The Eiffel Tower is in Paris, France.")
        else:
            return AIMessage(content="I don't have enough info in the context.")
    async def ainvoke(self, input: Any, config: Any = None) -> BaseMessage:
        return self.invoke(input, config)
    @property
    def _llm_type(self) -> str:
        return "mock-chat-llm"

def main():
    # 1. Setup Retriever
    embeddings = MockEmbeddings()
    docs = [
        Document(page_content="The capital of France is Paris.", metadata={"source": "wiki"}),
        Document(page_content="Eiffel Tower is in Paris, France.", metadata={"source": "travel"})
    ]
    vectorstore = InMemoryVectorStore.from_documents(docs, embeddings)
    retriever = vectorstore.as_retriever(search_kwargs={"k": 1})

    # 2. Setup Prompt
    rag_prompt = ChatPromptTemplate.from_messages([
        ("system", "You are an AI assistant. Use the following context to answer: {context}. If you don't know, say 'I don't know.'"),
        ("human", "Question: {question}")
    ])

    # 3. Setup LLM
    llm = MockChatLLM()

    # 4. Define how to format retrieved documents
    def format_docs(docs: List[Document]) -> str:
        return "\n\n".join(doc.page_content for doc in docs)

    # 5. Build the RAG chain
    rag_chain = (
        {"context": retriever | RunnableLambda(format_docs),
         "question": RunnablePassthrough()}
        | rag_prompt
        | llm
        | StrOutputParser()
    )

    print("RAG chain assembled!")

if __name__ == "__main__":
    main()

Je RAG-toepassing bevragen

Nu de RAG-keten volledig is opgebouwd, kun je deze aanroepen met een vraag van een gebruiker. De keten verwerkt intern het ophalen, opmaken van de context, opstellen van de prompt en genereren met de LLM, en geeft een rechtstreeks antwoord terug.

Dit is de laatste stap om een antwoord uit je RAG-systeem te krijgen.

from langchain_core.runnables import RunnablePassthrough, RunnableLambda
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.documents import Document
from langchain_community.vectorstores import InMemoryVectorStore
from langchain_core.embeddings import Embeddings
from langchain_core.language_models import BaseChatModel
from langchain_core.messages import BaseMessage, AIMessage
from typing import List, Any

# Mock Embeddings
class MockEmbeddings(Embeddings):
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        return [[i * 0.1] * 10 for i in range(len(texts))]
    def embed_query(self, text: str) -> List[float]:
        return [0.5] * 10

# Mock LLM
class MockChatLLM(BaseChatModel):
    def invoke(self, input: Any, config: Any = None) -> BaseMessage:
        input_str = str(input)
        if "Paris" in input_str and "capital of France" in input_str:
            return AIMessage(content="Based on context, Paris is the capital of France.")
        elif "Eiffel Tower" in input_str and "Paris" in input_str:
            return AIMessage(content="The Eiffel Tower is in Paris, France.")
        else:
            return AIMessage(content="I don't have enough info in the context.")
    async def ainvoke(self, input: Any, config: Any = None) -> BaseMessage:
        return self.invoke(input, config)
    @property
    def _llm_type(self) -> str:
        return "mock-chat-llm"

def main():
    # Setup Retriever
    embeddings = MockEmbeddings()
    docs = [
        Document(page_content="The capital of France is Paris.", metadata={"source": "wiki"}),
        Document(page_content="Eiffel Tower is in Paris, France.", metadata={"source": "travel"})
    ]
    vectorstore = InMemoryVectorStore.from_documents(docs, embeddings)
    retriever = vectorstore.as_retriever(search_kwargs={"k": 1})

    # Setup Prompt
    rag_prompt = ChatPromptTemplate.from_messages([
        ("system", "You are an AI assistant. Use the following context to answer: {context}. If you don't know, say 'I don't know.'"),
        ("human", "Question: {question}")
    ])

    # Setup LLM
    llm = MockChatLLM()

    def format_docs(docs: List[Document]) -> str:
        return "\n\n".join(doc.page_content for doc in docs)

    # Build the RAG chain
    rag_chain = (
        {"context": retriever | RunnableLambda(format_docs),
         "question": RunnablePassthrough()}
        | rag_prompt
        | llm
        | StrOutputParser()
    )

    # Invoke the RAG chain with a query
    query = "Where is the Eiffel Tower?"
    result = rag_chain.invoke(query)
    print(f"Query: {query}")
    print(f"Answer: {result}")

    query_no_context = "What is the capital of Japan?"
    result_no_context = rag_chain.invoke(query_no_context)
    print(f"\nQuery: {query_no_context}")
    print(f"Answer: {result_no_context}")

if __name__ == "__main__":
    main()

Test je kennis van de RAG-stroom

Denk na over een LangChain RAG-toepassing die is ontworpen om vragen uit een kennisbank te beantwoorden.

Samenvatting: RAG bevragen

In deze les heb je geleerd hoe je alle RAG-componenten samenbrengt om vragen van gebruikers te verwerken en antwoorden te genereren:

  • We hebben de vraag van een gebruiker omgezet in een vraag voor de zoeker.
  • We hebben een zoeker geïnstantieerd vanuit een vectoropslagplaats om relevante documenten op te halen.
  • We hebben een promptsjabloon opgesteld om de LLM te begeleiden.
  • We hebben een LLM geïntegreerd om het uiteindelijke antwoord samen te stellen.
  • Ten slotte hebben we met LangChain Expression Language (LCEL) een volledige RAG-keten samengesteld en aangeroepen.

Je kunt nu een functioneel RAG-systeem bouwen dat goed onderbouwde, feitelijke antwoorden geeft!

Gratis beginnen

Leer LangChain / RAG / vectordatabases met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
12
Lessen
48

Veelgestelde vragen

Is de les “Query's verwerken en antwoorden genereren” gratis?

Ja — de volledige tekst van “Query's verwerken en antwoorden genereren” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus LangChain / RAG / vectordatabases wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus LangChain / RAG / vectordatabases bevat in totaal 4 lessen.

Wat leer ik in “Query's verwerken en antwoorden genereren”?

Ontwikkel de logica voor het verwerken van gebruikersquery's, het ophalen van relevante context en het samenstellen van antwoorden met de LLM. Je oefent met LangChain / RAG / vectordatabases door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met LangChain / RAG / vectordatabases te beginnen?

Ervaring vooraf is niet nodig. LangChain / RAG / vectordatabases op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.

Hoe lang duurt de les “Query's verwerken en antwoorden genereren”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over LangChain / RAG / vectordatabases?

Ja. Elke les over LangChain / RAG / vectordatabases bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Alle RAG-componenten integreren
  2. Query's verwerken en antwoorden genereren
  3. Prestaties van RAG-systemen evalueren
  4. Een golden testset voor RAG bouwen
← Terug naar LangChain / RAG / vectordatabases