LangChain · Lesson 2 of 5
Prompts, Parsers and Chains
Compose prompts, models and parsers with the pipe operator.
- Beginner
- 16 min read
- 3 objectives
Before this lessonLesson 1: LLM Apps and LangChain Basics
What you will learn
- Write prompt templates
- Get structured output
- Build a chain with LCEL
Hard-coding prompts as strings becomes messy fast. LangChain gives you reusable prompt templates, output parsers and a way to connect them into chains with the pipe operator, called LCEL (LangChain Expression Language).
Prompt templates
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful {role}. Answer in at most {words} words."),
("human", "{question}"),
])
messages = prompt.invoke({"role": "teacher", "words": 30, "question": "What is recursion?"})A first chain
The pipe | feeds the output of one step into the next: prompt, then model, then parser.
from langchain_core.output_parsers import StrOutputParser
chain = prompt | llm | StrOutputParser()
print(chain.invoke({"role": "teacher", "words": 30, "question": "What is recursion?"}))StrOutputParser turns the model's message object into a plain string. Every chain built this way automatically supports invoke, stream, batch and async versions.
Structured output
Free text is hard for programs to use. Ask the model for data that matches a schema, and LangChain returns a validated object.
from pydantic import BaseModel, Field
class Review(BaseModel):
sentiment: str = Field(description="positive, negative or neutral")
score: int = Field(ge=1, le=5)
summary: str
structured = llm.with_structured_output(Review)
result = structured.invoke("The battery is great but the screen scratches easily.")
print(result.sentiment, result.score)
print(result.model_dump())neutral 3
{'sentiment': 'neutral', 'score': 3, 'summary': 'Great battery but a screen that scratches easily.'}Composing bigger chains
from langchain_core.runnables import RunnablePassthrough, RunnableParallel
summarize = ChatPromptTemplate.from_template("Summarize in one line: {text}") | llm | StrOutputParser()
translate = ChatPromptTemplate.from_template("Translate to French: {text}") | llm | StrOutputParser()
both = RunnableParallel(summary=summarize, french=translate)
print(both.invoke({"text": "LangChain helps build LLM applications."}))RunnableParallel runs branches at the same time. Other useful runnables: RunnableLambda to wrap your own function, and RunnablePassthrough to carry inputs alongside results.
Prompt-writing tips
- Be specific about role, task, format and length.
- Give one or two examples (few-shot) when the format matters.
- Put untrusted user text in its own clearly labeled section to reduce prompt-injection risk.
- Version and test your prompts like code.
# Write your solution here
