The loop owns control flow; hooks observe at named moments
What You’ll Learn
- Why hooks are better than modifying the loop directly
- How to implement named lifecycle hooks
- How hooks can observe, block, or annotate agent behavior
The Problem
As your agent grows, you want to add logging, validation, notifications. Without hooks, you end up modifying the core loop for every new concern — creating a tangled mess.
The Solution
Named hooks that fire at specific moments. The loop stays clean; hooks plug in.
Agent loop Hooks
+------------------+ +------------------+
| | | pre_tool_use: |
| [Hook point 1] --|-------->| validate, log, |
| | | block if unsafe|
| execute tool | +------------------+
| | | post_tool_use: |
| [Hook point 2] --|-------->| log results, |
| | | notify on error|
+------------------+ +------------------+
How It Works
-
Define hook points with names like
pre_tool_use,post_tool_use,on_session_start. -
Hooks receive context (tool name, input, output) and return decisions:
continue,block, ormodify.
class HookSystem:
def __init__(self):
self.hooks = defaultdict(list)
def register(self, point: str, handler):
self.hooks[point].append(handler)
def fire(self, point: str, context: dict) -> str:
for handler in self.hooks[point]:
result = handler(context)
if result == "block":
return "block"
return "continue"
What Changed From s07
| Component | Before (s07) | After (s08) |
|---|---|---|
| Extensibility | Modify loop body | Named hook points |
| Lifecycle | Implicit | Explicit (pre/post/session) |
| Plugins | None | Register/unregister |
Try It
cd learn-claude-code
python agents/s08_hook_system.py
Write a file and check the hook logsTry to delete a protected file(hook should block it)Run several commands and review the hook audit trail
Key Takeaway
Hooks let the loop grow without being rewritten. Register observers at named moments and let the loop fire them.