What is register_after_llm_call_hook()?
`register_after_llm_call_hook(fn)` mirrors `@after_llm_call_crew` but targets the imperative registration path: the callable still receives `LLMCallHookContext` after the provider returns, and may emit a string to replace the model output before guardrails or tasks consume it. That is the hook you want for structured telemetry (latency, token histograms), compliance redaction, or stripping chain-of-thought blocks that should never reach downstream tools.
Unlike read-only event listeners, after-LLM hooks participate in the mutation contract of the crew runtime — returning `None` preserves the original completion while returning text swaps it wholesale. Treat that power like middleware in a web framework: compose small functions, avoid double JSON parsing, and never raise bare exceptions unless you intend to fail the kickoff.
Operational teams usually register these hooks during application bootstrap alongside before-LLM hooks so ordering stays deterministic: redact → call model → redact again → log. Document the ordering for on-call engineers because implicit stacks are hard to introspect from logs alone. Propagate a stable correlation id from ctx into downstream spans so tickets map back to the exact completion.
Use Cases
- • Plugin hooks
- • Conditional logging
Key Features
- ✓ Runtime registration
When NOT to Use
Static hook code — use the decorator.
Notes
Downstream consumers see the mutated string
Tasks, tools, and memory features all observe the post-hook payload. Add integration tests when you rewrite JSON so parsers still succeed.
Stack depth and recursion
If a hook triggers auxiliary LLM calls, guard against re-entrancy with thread-locals or explicit depth counters so you do not recurse infinitely.
Sensitive payloads in logs
After hooks are a common place to accidentally print prompts. Route through your redaction helpers before shipping to third-party observability vendors.
Test teardown
Pair every programmatic registration with `clear_all_global_hooks()` in autouse fixtures; otherwise CI order flips will leak logging hooks between modules.
Parameters
| Parameter | Type | Required | Purpose |
|---|---|---|---|
| fn | Callable[[LLMCallHookContext], Any] | No | The hook callable. |
Code Examples
Register
register_after_llm_call_hook(log_response)
Structured logging without mutating output
import logging
from crewai.hooks import register_after_llm_call_hook
log = logging.getLogger("crew.llm")
def emit_metrics(ctx):
log.info("model=%s tokens=%s", ctx.model, getattr(ctx, "usage", None))
return None
register_after_llm_call_hook(emit_metrics)
Trim verbose reasoning traces
def strip_think(ctx):
text = ctx.response or ""
marker = "</think>"
if marker in text:
return text.split(marker, 1)[-1].strip()
return None
register_after_llm_call_hook(strip_think)
When to Use
Dynamic / plugin-based observability.
Common Mistakes
❌ Forgetting to clear hooks between tests
✅ Call clear_all_global_hooks() in test setup.
Related: @tool decorator reference, Agent class reference, and the first Crew tutorial.
register_after_llm_call_hook() FAQ
What is register_after_llm_call_hook() in CrewAI?
Registers an after-LLM-call hook programmatically. `register_after_llm_call_hook(fn)` mirrors `@after_llm_call_crew` but targets the imperative registration path: the callable still receives `LLMCallHookContext` after the provider returns, and may emit a string to replace the model output before guardrails or tasks consume it. That is the hook you want for structured telemetry (latency, token histograms), compliance redaction, or stripping chain-of-thought blocks that should never reach downstream tools. Unlike read-only eve…
Which CrewAI types expose the method register_after_llm_call_hook()?
DevShelfHub documents register_after_llm_call_hook() on Programmatic hook registration. The reference maps it to Python module crewai.hooks — pin your installed crewai version and match imports to the snippet on this page.
When should I use register_after_llm_call_hook()?
Dynamic / plugin-based observability.
When should I avoid register_after_llm_call_hook()?
Static hook code — use the decorator.
How do I call register_after_llm_call_hook() from Python?
register_after_llm_call_hook(fn)
Where can I explore more CrewAI API reference pages?
Open the CrewAI API reference index on DevShelfHub to search classes, methods, and decorators, each with runnable examples, parameters, common mistakes, and cross-links.