๐Ÿงฉ AI Engineering

LangChain Core Concepts โ€” Models, Prompts & Output Parsers

๐Ÿ“… Aug 5, 2026 โฑ 6 min read

Before chains, memory, or agents, three pieces do 80% of the work: the model, the prompt template, and the output parser. Master these and everything else is just composition.

1. Chat models and messages

Modern LLMs are chat models: they take a list of messages with roles โ€” system (instructions), user (the human), assistant (the AI). LangChain gives each a class.

from langchain.chat_models import init_chat_model
from langchain_core.messages import SystemMessage, HumanMessage

model = init_chat_model("claude-opus-5", model_provider="anthropic")

reply = model.invoke([
    SystemMessage("You are a concise tutor for Anna University students."),
    HumanMessage("What is a semaphore?"),
])
print(reply.content)

The system message is your app's "personality and rules" โ€” it's where you set tone, constraints, and role.

2. Prompt templates โ€” stop using f-strings

Hard-coding prompts with f-strings gets messy fast. A ChatPromptTemplate is a reusable prompt with {placeholders} you fill at call time.

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a tutor for {subject}. Answer in {tone} language."),
    ("user", "{question}"),
])

# .invoke fills the blanks and returns ready-to-send messages
messages = prompt.invoke({
    "subject": "operating systems",
    "tone": "simple",
    "question": "What is a deadlock?",
})
print(model.invoke(messages).content)

Now the same prompt serves every subject and question โ€” that reusability is the whole point.

3. Output parsers โ€” from reply object to clean data

A model returns a message object, but you usually want a plain string or structured data. Output parsers handle that last mile.

from langchain_core.output_parsers import StrOutputParser

parser = StrOutputParser()          # pulls out just the .content string
text = parser.invoke(model.invoke("Say hi"))
print(text)   # "Hi!" โ€” a clean string, not a message object

Need structured output (a dict with fixed fields)? Ask the model to fill a schema:

from pydantic import BaseModel, Field

class Flashcard(BaseModel):
    question: str = Field(description="the quiz question")
    answer: str = Field(description="the correct answer")

structured = model.with_structured_output(Flashcard)
card = structured.invoke("Make a flashcard about TCP three-way handshake.")
print(card.question, "->", card.answer)   # a real Python object

with_structured_output is a superpower โ€” it guarantees you get typed data instead of parsing free text by hand.

Putting the three together

Model + prompt + parser is a pipeline. In the next post we connect them with a single character โ€” the | pipe โ€” to form your first chain. That one operator is what makes LangChain feel elegant instead of verbose.

Related: what LangChain is ยท interview questions to test your OS/CN knowledge the tutor above quizzes you on.

โ† All Articles