DEV Community

Cover image for Building RAG Applications with LangChain(Part-5)
Dharmendra Singh
Dharmendra Singh

Posted on

Building RAG Applications with LangChain(Part-5)

Prompting, Chaining & Parsing: Structuring Smart, Reliable LLM Workflows

Welcome back to the LangChain RAG Series. So far, we’ve walked through:

  • Part 1: Understanding RAG Architecture

  • Part 2: Document Loaders

  • Part 3: Text Splitters

  • Part 4: Embeddings & Vector Stores

Now it’s time to bring it all together using LangChain’s Prompt Templates, Chains, and Output Parsers — the heart of a well-structured LLM pipeline.

What This Part Covers

  • Writing reusable prompts using ChatPromptTemplate
  • Building logic flows with Runnable-based Chains
  • Parsing raw LLM output into structured results
  • Examples using Gemini, OpenAI, and LangChain Expressions
  • Best practices for scalable and debuggable apps

Prompt Engineering with LangChain

LangChain supports a modular approach to prompts.

Components:

  • SystemMessage — Set behavior and role of the model

  • HumanMessage — What the user asks

  • AIMessage — Model-generated replies (can be optional)

  • ChatPromptTemplate — Compose a full message list with placeholders

Example:

from langchain.prompts.chat import ChatPromptTemplate, SystemMessage, HumanMessage

prompt = ChatPromptTemplate.from_messages([
    SystemMessage(content="You are a helpful {domain} expert."),
    HumanMessage(content="Tell me about {topic}.")
])

formatted_prompt = prompt.invoke({"domain": "Cricket", "topic": "reverse swing"})
Enter fullscreen mode Exit fullscreen mode

This makes your prompts reusable and structured across different topics or domains.

Another example:

def  ask_query(query):

#get retriever
retriever = vectorstore.as_retriever(search_type='similarity', search_kwargs={'k': 2})
results = retriever.invoke(query)
context = "\n".join([document.page_content for document in results])

prompt = f"""
You are an FAQ assistant. Use the following content to answer the user's question accurately and concisely:
{context}
Q: {query}
A:
"""
response = model.invoke(prompt)
return response.content

Enter fullscreen mode Exit fullscreen mode

Chains: Connecting Components Using LangChain Expression Language (LCEL)

LangChain Chains combine multiple steps using runnables to manage logic and flow.

Runnable Types:

  • RunnableSequence: Run in sequence for example use case: Prompt → LLM → Parser
  • RunnableParallel: Run multiple branches in parallel for example use case: Fetch metadata + summary
  • RunnableLambda: Custom function as part of chain for example use case: Preprocessing inputs
  • RunnableBranch: If/else-style branching for example use case: Conditional routing
  • RunnablePassthrough: Pass input as-is for example use case: Default input/return identity

Example: RunnableSequence Chain

from langchain.schema.runnable import RunnableSequence
from langchain.output_parsers import StrOutputParser
from langchain.llms import OpenAI

chain = RunnableSequence([
    prompt,             # PromptTemplate
    OpenAI(),           # LLM
    StrOutputParser()   # Clean the output
])

result = chain.invoke({"domain": "Cricket", "topic": "swing bowling"})
print(result)
Enter fullscreen mode Exit fullscreen mode

This runs: Prompt → LLM → OutputParser, all in one clean pipeline.

You can use LCEL in place of RunnableSequence:

chain = prompt | OpenAI() | StrOutputParser()

Enter fullscreen mode Exit fullscreen mode

Output Parsers: Making Results Structured

By default, LLMs return plain text. LangChain supports parsers to transform this into structured data.

Common Parsers:

  • StrOutputParser: Clean text string
  • CommaSeparatedListOutputParser: List from CSV text
  • PydanticOutputParser: Typed structured objects
  • JsonOutputParser: JSON dictionaries

Example with Pydantic:

from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel

class Answer(BaseModel):
    topic: str
    summary: str

parser = PydanticOutputParser(pydantic_object=Answer)

Enter fullscreen mode Exit fullscreen mode

You can use this in your chain to enforce structure in the output (e.g., for APIs, UIs, or analytics).

Real-World Workflow Example

full_chain = prompt | OpenAI() | StrOutputParser()
Enter fullscreen mode Exit fullscreen mode

This structure works for:

  • Document-based QA
  • Summarizers
  • Entity extractors
  • Internal tools with LLM logic

Best Practices

  • Use ChatPromptTemplate for modularity
  • Parse everything — never trust raw LLM strings
  • Chain small functions using RunnableSequence
  • Test components independently
  • Branch with RunnableBranch to manage complex logic

Coming Up Next: Part 6

In Part 6, we’ll combine everything we’ve built so far into real-world, production-ready examples.

Think of this as your RAG Starter Toolkit in action.

Missed the Previous Parts?

👉 Part 1 – What is RAG

👉 Part 2 – Document Loaders

👉 Part 3 – Text Splitters

👉 Part 4 – Embeddings & Vectors

Top comments (0)