LangChainLangChain 1.4 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
43 small wins to finish your pathNext lesson

The order middleware runs in

With several middleware, before hooks run in list order and after hooks in reverse. Get it wrong and a hook sees the state before the change you expected.

A class gives middleware a name and room for more than one hook. Tag prints its label from both model hooks, so two of them show the order.

Exampletag.py
from langchain.agents.middleware import AgentMiddleware


class Tag(AgentMiddleware):
    def __init__(self, label):
        super().__init__()
        self.label = label

    @property
    def name(self):
        return self.label

    def before_model(self, state, runtime):
        print("before", self.label)

    def after_model(self, state, runtime):
        print("after ", self.label)

The name property matters here: LangChain names each middleware after its class unless told otherwise, and refuses two with the same name.

Example
from langchain.agents import create_agent
from shop_model import ShopModel
from tag import Tag

agent = create_agent(ShopModel(), tools=[], middleware=[Tag("first"), Tag("second")])
agent.invoke({"messages": [{"role": "user", "content": "Hello"}]})

Before hooks ran first to last, in the order of the list. After hooks ran last to first. Picture the list as layers around the model: the first entry is the outermost, the first in and the last out. Lesson 19 shows what this means for two middleware that handle the same error.

The order middleware runs in
middleware=[first, second]What runs, top to bottomfirstoutermost layersecondinside the firstfirst.before_modelsecond.before_modelthe model callsecond.after_modelfirst.after_modeltools, then round again
Hover or tap a piece to see what it is and which lesson built it.
Follow the order

Pick one to watch it run, step by step.

The argument has to be called runtime

Example
from langchain.agents import create_agent
from langchain.agents.middleware import AgentMiddleware
from shop_model import ShopModel


class Short(AgentMiddleware):
    def before_model(self, state, rt):
        print(len(state["messages"]))


agent = create_agent(ShopModel(), tools=[], middleware=[Short()])
agent.invoke({"messages": [{"role": "user", "content": "Hello"}]})

LangChain passes the runtime to a hook by the name runtime, so a hook that calls it rt fails the first time it runs. The documentation does not mention this; rename the argument and it works.

Try it yourself
  • Pass Tag("first") twice and read the error.
  • Add a third Tag in the middle of the list and predict the six lines before you run it.
  • Add a before_agent method to Tag and see where it prints.

You understood something today that you didn't yesterday.