What is @wrap_model_call?
@wrap_model_call is a LangChain agent middleware decorator that intercepts the model call object before it is dispatched to the language model API. Unlike @before_model (which receives and can mutate the full agent state) and @after_model (which receives the full state post-response), @wrap_model_call receives the call object itself — the structured representation of the API request that is about to be sent, including the messages list, the model name, temperature, and any tool schemas. The decorated function must return the call object (modified or unchanged) or raise an exception to abort the call.
The primary use cases are cost tracking (count input tokens before the call, record the model name and parameters), rate limiting (check a token-bucket counter and raise if budget is exceeded), and model switching (inspect the call and replace call.model with a fallback model name if the primary is unavailable). Because the hook fires at the call object level rather than the state level, it is the right place to implement cross-cutting infrastructure concerns that should be invisible to the agent's business logic.
The call object structure mirrors the model's API parameters. Modifying call.messages directly affects what the model receives. Modifying call.model switches the model for this call only. Raising any exception inside the hook aborts the model call and propagates the exception into the agent loop — catch it in the @entrypoint or handle it with a try/except in the agent node.
Use Cases
- • Track costs
- • Rate limit
- • Monitor usage
- • Model fallback
- • Profile
- • Budget control
Key Features
- ✓ Intercept calls
- ✓ Full visibility
- ✓ Retry logic
- ✓ Cost tracking
- ✓ Fallback
- ✓ Transformation
When NOT to Use
For model selection—use .bind().
Notes
Must return the call object — returning None aborts with a TypeError
The middleware contract requires returning the call object. If your hook performs a pure side effect (logging, incrementing a counter) and returns None, the agent loop receives None instead of the call, raises TypeError, and the entire agent turn fails. Always end with return call.
Modifying call.model switches the model for this call only
Setting call.model = "gpt-4o-mini" within the hook affects only the current API request. The original model bound to the agent is unchanged for subsequent calls. This makes @wrap_model_call ideal for per-call fallback logic (route long prompts to a larger model, short ones to a cheaper model) without changing the agent configuration.
Raising an exception inside the hook aborts the model call
Any exception raised inside @wrap_model_call propagates into the agent loop. Use this to enforce budget limits: raise RuntimeError("Budget exceeded"). Handle it in the @entrypoint function with a try/except around the agent invocation, or implement retry logic in a @before_model hook that resets state before the next attempt.
Use alongside @after_model for complete request/response cycle tracking
Record the call start time in @wrap_model_call (e.g., store in a thread-local), then compute the elapsed time in @after_model. Together they give you input token count (pre-call), response latency, and output token count (post-call) — the three metrics needed for cost-per-call accounting.
Import
from langchain.agents import wrap_model_call
How to Apply
@wrap_model_call
def track(call):
cost = estimate_cost(call.messages)
log_cost(cost)
return call
What It Enables
- ✓ Cost tracking
- ✓ Rate limiting
- ✓ Usage monitoring
- ✓ Model switching
Code Examples
Track estimated cost before API call
from langchain.agents import wrap_model_call
@wrap_model_call
def track(call):
cost = estimate_cost(call.messages)
log(cost)
return call
Token budget rate limiter
from langchain.agents import wrap_model_call
import threading
_token_budget = threading.local()
@wrap_model_call
def rate_limit(call):
tokens = count_tokens(call.messages)
budget = getattr(_token_budget, "remaining", 100_000)
if tokens > budget:
raise RuntimeError("Token budget exceeded")
_token_budget.remaining = budget - tokens
return call
Automatic model fallback on overload
from langchain.agents import wrap_model_call
PRIMARY = "gpt-4o"
FALLBACK = "gpt-4o-mini"
@wrap_model_call
def model_fallback(call):
if is_overloaded(call.model):
call.model = FALLBACK
return call
Integration Patterns
agent = create_agent(model, middleware=[monitor])
Intercepts all calls
Common Mistakes
❌ @wrap_model_call def h(call): # Returns nothing
✅ @wrap_model_call def h(call): return call
Related LangChain References
Browse the full LangChain API reference index to explore more classes, methods, and decorators, or start with the LangChain introduction tutorial for end-to-end context on building with @wrap_model_call and the wider framework.
@wrap_model_call FAQ
What does @wrap_model_call do in LangChain?
Middleware wrapping model API calls. @wrap_model_call is a LangChain agent middleware decorator that intercepts the model call object before it is dispatched to the language model API. Unlike @before_model (which receives and can mutate the full agent state) and @after_model (which receives the full state post-response), @wrap_model_call receives the call object itself — the structured representation of the API request that is about to be sent, including the messages list, the model name, temperature, and any to…
Which package provides @wrap_model_call?
DevShelfHub documents @wrap_model_call from the langchain.agents package. Pin your installed LangChain version and match imports to the snippet on this page.
When should I use @wrap_model_call?
Use @wrap_model_call when your LangChain agents, workflows, or pipelines need the behavior described in this guide.
When should I avoid using @wrap_model_call?
For model selection—use .bind().
How do I apply @wrap_model_call in Python?
Apply @wrap_model_call as a decorator above your function definition. Import it from from langchain.agents import wrap_model_call and annotate the function you want to wrap. See the code examples on this page for a complete working snippet.
Where can I explore more LangChain API reference pages?
Open the LangChain API reference index on DevShelfHub to browse classes, methods, and decorators, each with runnable examples, parameters, common mistakes, and cross-links.