Dynamic Prompting with LangChain
Writing one prompt by hand is easy. Building an app that fills prompts with live data, calls a model, cleans the reply and passes it to the next step is harder. LangChain gives you small building blocks that snap together with a simple | pipe, like Lego.
In this session
- Prompt templates and output parsers
- LCEL: joining steps with the
|operator - Runnables:
invoke,batchandstream - Sequential chains and parallel chains
01Prompt templates
A prompt template is a prompt with blanks to fill at run time. It keeps your prompt text in one place and makes it reusable.
# pip install langchain-core langchain-openai
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful banking tutor."),
("user", "Explain {topic} in one line."),
])
print(prompt.invoke({"topic": "UPI"}).to_messages())Like a printed bank form. The text is fixed; you only fill in the blanks (name, account number). One form, used thousands of times.
02Output parsers
A chat model returns a message object. An output parser turns it into what your code needs:
StrOutputParser: just the text.JsonOutputParser: a Python dict.PydanticOutputParserorllm.with_structured_output(Model): a validated object (Session 28).
03LCEL: the pipe operator
The LangChain Expression Language joins steps with |. The output of each step becomes the input of the next:
chain = prompt | llm | StrOutputParser()from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
chain = prompt | llm | StrOutputParser()
print(chain.invoke({"topic": "UPI"}))from langchain_core.language_models.fake_chat_models import FakeListChatModel then llm = FakeListChatModel(responses=["UPI lets you send money instantly using a phone number or QR code."]). The chain works exactly the same.04Runnables: one interface for everything
Prompts, models, parsers and whole chains are all Runnables, so they share the same methods:
| Method | What it does | Use it for |
|---|---|---|
invoke(x) | Run once on one input | A single request |
batch([x1, x2, …]) | Run on many inputs, in parallel | Processing a file of 1,000 tickets |
stream(x) | Yield the answer piece by piece | Chat UIs that show text as it is typed |
ainvoke, abatch, astream | Async versions | Web servers (FastAPI) |
answers = chain.batch([{"topic": "UPI"}, {"topic": "NEFT"}, {"topic": "IMPS"}])
for piece in chain.stream({"topic": "RTGS"}):
print(piece, end="", flush=True)You can also turn any Python function into a Runnable with RunnableLambda, and pass input through unchanged with RunnablePassthrough.
05Sequential and parallel chains
Sequential: one step feeds the next
Example: summarise a customer complaint in English, then translate the summary into Hindi for the branch team.
summarise = ChatPromptTemplate.from_template("Summarise this complaint in one line:\n{complaint}") | llm | StrOutputParser()
translate = ChatPromptTemplate.from_template("Translate to Hindi:\n{summary}") | llm | StrOutputParser()
pipeline = {"summary": summarise} | translate # the dict maps the first output into {summary}
print(pipeline.invoke({"complaint": "I was charged twice for my electricity bill payment on 3 Oct…"}))Parallel: several jobs on the same input
RunnableParallel runs branches at the same time and returns a dict, which saves waiting time.
Three model calls (sentiment, keywords, summary), each taking about 1.2 seconds.
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
sentiment = ChatPromptTemplate.from_template("Sentiment (positive/negative/neutral) of: {text}") | llm | StrOutputParser()
keywords = ChatPromptTemplate.from_template("3 keywords from: {text}") | llm | StrOutputParser()
analyse = RunnableParallel(sentiment=sentiment, keywords=keywords, original=RunnablePassthrough())
print(analyse.invoke({"text": "Got my refund after a delay, thanks!"}))Output above from running with a fake model on langchain-core; a real model’s wording will differ.
create_agent, memory and middleware, with key-free runnable code.06Summary
- Prompt templates hold reusable prompts with blanks.
- Output parsers turn model messages into text, dicts or validated objects.
- LCEL joins steps with
|:prompt | llm | parser. - Every piece is a Runnable with
invoke,batchandstream. - Chain steps sequentially or run them in parallel with
RunnableParallel.
07Quick quiz
1. In prompt | llm | parser, what does | do?
2. Which method shows the answer word by word in a chat UI?
3. What does StrOutputParser return?
4. You need sentiment and keywords for the same review, fast. Use…
5. To process 1,000 tickets with one chain, use…