Vocabulary for this course

The terms the chapters assume, in plain words. You can open this from any chapter.

callback
A function the library calls at fixed points in a run, such as when a step starts or ends.
chain
A series of steps where each one passes its result to the next, ending in the answer.
invoke
The method that runs a step once with one input and returns its result.
memory
Stored history from earlier turns, added back to a request so the model can refer to what was said.
message
One labelled turn in a chat request, marked as coming from the system, the user or the model.
model
The trained program that reads a message list and returns the next turn.
output parser
The step that turns a model's raw text into a value your program can use, or raises an error.
pipe
The operator that joins two steps into one new step, running the left side first.
prompt
The text a model receives for one request, built from fixed wording and the values filled into it.
prompt template
A reusable prompt with named blanks that are filled in for each request.
runnable
Any step with a standard way to run it, so steps can be joined without knowing each other's code.
streaming
Sending a reply in pieces as it is produced, rather than waiting for the whole text.
tool
A function exposed to a model, with a name, described inputs and a result.
tool call
A model's request to run a named tool with specific arguments, which your code may accept or refuse.

LangChain from the ground up

Capstone: a mini LangChain

Assemble the pieces the course has built — templates, a model step, parsing, a tool loop — into one small library, then compare it with what the real framework adds.

Part 10 of 10

Advanced20 min readBack to Courses

The whole shape in one file

Everything so far has been one idea at a time: a step is a callable, a template fills slots, a model takes messages, a parser turns text into data, a pipe joins steps. The capstone puts them together with no framework at all, so the seams are visible.

The point is not to replace LangChain. It is to make the framework legible: when you read its documentation, each class should map onto something you have already written once and can reason about.

In the mini version, each seam is a place you can print. The template is a function from a dictionary to a string; the model step is a function from messages to text; the parser is a function from text to a value. When the answer is wrong, you print the value at each seam and the fault is in the step that first produced something unexpected. That habit survives the move to the real framework.

What the real framework adds

Three things are genuinely hard to write yourself. Batching and streaming across a composition, so one stream() call yields tokens from the last step rather than the first. Tracing, so a failed production request shows every intermediate value. Integrations, so the same chain runs against a dozen providers without rewriting the steps.

Those are operational features, not conceptual ones. They matter in production and they do not change the model of computation: a chain is still steps, and a step is still one value in and one out.

The same program with the framework

chain = (
    ChatPromptTemplate.from_messages([
        ("system", "Answer with one sentence and a confidence from 0 to 1."),
        ("human", "{question}"),
    ])
    | ChatOpenAI(model="gpt-4o-mini", temperature=0)
    | JsonOutputParser()
)

result = chain.invoke({"question": "Is a vector store a database?"})
print(result["confidence"])

Template, model, parser — in forty lines

Run the chain, then change the fake model so it returns a fenced JSON block and confirm the parser still copes. That is the kind of variation the real world sends.

Output
Click "Run" to execute your code

Build the smallest thing that shows the seam

The mini version is deliberately small: four steps and a fake model. Its value is that you can replace any step with a print statement or a stub and see the whole pipeline move. When you move to the framework, keep that instinct — bind a fake model, invoke the chain, and check the value at each boundary before you blame the provider.

A common mistake is reimplementing the framework feature by feature. The exercise is to understand the shape, not to ship a competitor. Stop when the seams are visible; the real framework earns its place with streaming, batching and tracing, which are operational problems rather than conceptual ones.

Adding the loop

A chain answers once. An agent answers, acts, looks at the result and answers again. The difference is a loop with a stop condition: a maximum number of steps, a budget, or a signal from the model that it is finished.

The loop is also where validation belongs. Every tool request is checked before it runs, every result is returned with the call id, and every iteration is bounded. That is the whole of an agent, and it fits in forty lines.

The transcript is the state: the question, each tool request, each result. The loop appends and resends it, so the model sees the whole exchange on every iteration. A stop condition that returns the transcript is more useful than one that raises, because the partial work is still there. That is the same lesson as the agent course, applied to a smaller program: the loop is ordinary code, and ordinary code can be tested with a fake model. Start with the fake model and connect a provider only when the shape is right.

Read a framework’s source once you understand its concepts. RunnableSequence.invoke is a for-loop, and seeing that removes most of the mystery around debugging a chain.

Where to go next

The RAG course takes the retrieval half of this pipeline and builds it properly: chunking, embeddings, a vector store and a grounded prompt. The evaluation course is what tells you whether any of it improved.

The LangGraph course replaces the straight line with a state machine, for the workflows that need to loop, branch, pause for a human, or resume after a failure.

A bounded agent loop

The loop stops after three steps. Make the fake model ask for a tool twice, then answer, and watch the loop hand results back each time.

Output
Click "Run" to execute your code

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

Why build the chain without the framework first?