惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
S
SegmentFault 最新的问题
Engineering at Meta
Engineering at Meta
量子位
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Google DeepMind News
Google DeepMind News
博客园_首页
云风的 BLOG
云风的 BLOG
月光博客
月光博客
I
InfoQ
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Vercel News
Vercel News
美团技术团队
Microsoft Security Blog
Microsoft Security Blog
P
Proofpoint News Feed
D
Docker
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
博客园 - 叶小钗
Martin Fowler
Martin Fowler
雷峰网
雷峰网
酷 壳 – CoolShell
酷 壳 – CoolShell
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog

Stories by HARSHA J S on Medium

Mastering LangChain 1.2: Part 13 — Agentic RAG: Why Your AI Needs to Decide When to Google Mastering LangChain 1.2: Part 12 — The Elephant’s Memory: Persistent AI Agents that Never Forget Mastering LangChain 1.2: Part 10 — Human-in-the-Loop: Adding an “Approval” Button to Your AI Agents Mastering LangChain 1.2: Part 9 — Structured Outputs: Turning Messy Chat into Clean Data Mastering LangChain 1.2: Mastering LangChain 1.2: Mastering LangChain 1.2: Part 6 — Dynamic Tool Security: The “Triple-Lock” Guardrail Mastering LangChain 1.2: Part 5 — Dynamic Model Routing: Escalating to Senior AI in Emergencies Mastering LangChain 1.2: Part 4 — Scaling with Middleware and Smart Summarization
Mastering LangChain 1.2: Part 11 — Custom Middleware Hook...
HARSHA J S · 2026-03-28 · via Stories by HARSHA J S on Medium

HARSHA J S

In Part 11 of our series, today we are focusing on Custom Middleware Hooks. This is the “internal plumbing” that allows you to control how your agent behaves at every stage of its lifecycle.

Press enter or click to view image in full size

In earlier parts of this series, we used pre-built middleware for things like summarization and human approval. But what if you need something truly custom?

Maybe you want to log every incident with a unique UUID, inject hidden instructions when a critical failure is detected, or append safety warnings to specific AI responses. To do this, you need to go “under the hood” and use Custom Middleware Hooks.

LangChain 1.2 provides four primary “Node-style” hooks that allow you to intercept the agent at specific execution points.

The Four Stages of an AI Request

Think of an agent’s execution as a timeline. Custom hooks let you “plug in” logic at any of these four points:

  1. before_agent: Runs once at the very start of the conversation. Perfect for generating IDs or starting timers.
  2. before_model: Runs every time the agent is about to call its LLM "Brain." Use this to inject extra rules or priority context.
  3. after_model: Runs immediately after the LLM responds, but before the user sees it. Ideal for safety filtering or formatting.
  4. after_agent: Runs once at the end of the entire loop. Perfect for cleanup or logging final resolutions.

1. Initializing the Incident (before_agent)

Let’s build an Incident Commander agent. Every time a user starts a chat, we want to generate a unique incident ticket ID. We use before_agent to "hack" this ID into the conversation state.

@before_agent
def init_incident(state: dict, runtime: Any) -> dict:
incident_id = str(uuid.uuid4())[:6]
print(f"🚨 INCIDENT #{incident_id} STARTED.")

# Inject a hidden SystemMessage with our ID
return {"messages": [SystemMessage(content=f"INCIDENT_ID: {incident_id}")]}

2. Dynamic Escalation (before_model)

If a user says “the server is CRASHED,” we don’t want the AI to give a generic, polite response. We want to force it into “Emergency Mode.” By using before_model, we can scan the user's input and inject a high-priority instruction right before the model processes it.

@before_model
def check_severity(state: dict, runtime: Any):
last_msg = state["messages"][-1].content.lower()

if "down" in last_msg or "crash" in last_msg:
# Force the model to be brief and stay focused on the outage
return {"messages": [SystemMessage(content="URGENT: This is a P1 OUTAGE. Be brief.")]}
return None

3. The Response Guardrail (after_model)

Finally, we want to ensure that if the AI suggests a dangerous command (like “restarting a database”), we add a safety label. This is done after the model has finished thinking, using after_model.

@after_model
def safety_check(state: dict, runtime: Any):
ai_reply = state["messages"][-1].content

if "restart" in ai_reply.lower():
new_content = ai_reply + "\n\n(⚠️ SAFETY WARNING: Obtain approval before executing.)"
return {"messages": [AIMessage(content=new_content)]}
return None

4. Tying It All Together

When you assemble these hooks into your agent, you get a system that follows a strict operational lifecycle:

agent = create_agent(
model=model,
middleware=[init_incident, check_severity, safety_check, close_ticket] # The lifecycle
)

The result in action:

  • User: “The database is DOWN!”
  • 1. before_agent: Ticket #a1b2c3 is created.
  • 2. before_model: AI is told this is a “P1 Outage.”
  • 3. after_model: AI suggests a restart, and the middleware automatically appends the Safety Warning.
  • 4. after_agent: The incident is logged as “Closed” in your backend.

Conclusion: Total Control

Custom hooks turn your AI from an unpredictable black box into a structured application. You can enforce security, track metrics, and modify behavior dynamically without ever hardcoding that logic into your tools or your prompts.

By mastering the agent lifecycle, you aren’t just building a bot — you’re building a reliable, auditable, and safe AI workflow.

💬 What do you think?
Drop your thoughts, questions, or suggestions in the comments below!

Check out my YouTube channel for more exciting content! [YouTube Channel Link — Harsha Selvi]

Disclaimer: This text has been rephrased using AI tools, and some parts are derived from various sources to provide a comprehensive overview.

#AI #LangChain #SoftwareDevelopment #Python #AIEngineering #DevOps #Observability #CleanCode #Automation