CLAUDE.md and Hooks——Building Your Personalized AI Butler

Have you ever wondered how to make Claude Code “remember” your project’s special rules, like:
- “Our project uses tabs, not spaces”
- “Always run tests before committing”
- “Don’t touch that legacy code file”
Reminding AI every time is tedious. CLAUDE.md solves this—write a “house rules manual” for your butler so it automatically follows them.
Today we’re talking about building your personalized AI butler.
The diagram: CLAUDE.md is like a house rules manual for your AI butler
What Is CLAUDE.md
CLAUDE.md is a Markdown file in your project root directory—it’s the “project-level manual” for Claude Code.
When Claude Code starts, it automatically reads this file (if it exists) and merges the content into the system prompt.
Simply put: system prompts are “company rules and regulations,” CLAUDE.md is “department-specific regulations.”
What Can CLAUDE.md Contain
CLAUDE.md content is inserted verbatim into system prompts, so you can write:
Project Background:
# Project Description
This is the XXX backend service, using Go + Gin framework.
Database uses PostgreSQL, ORM uses GORM.
Coding Standards:
## Coding Standards
- Use Tab for indentation, not spaces
- Function names use camelCase
- Error handling must return error, don't panic
- All exported functions must have documentation comments
Special Rules:
## Notes
- Code in /legacy/ directory is legacy system—do not modify
- Must ask before modifying database schema
- Must run `make test` before committing
- Do not commit .env files
Common Commands:
## Common Commands
- Run tests: `make test`
- Build: `make build`
- Start service: `make run`
- Database migration: `make migrate`
Tool Preferences:
## Tool Usage Preferences
- Use GrepTool for code search, don't use Bash's grep
- Prefer FileReadTool for reading config files
- Confirm necessity before executing commands
The diagram: Typical CLAUDE.md structure
How CLAUDE.md Works
CLAUDE.md content position in system prompts:
[System Prompt - Identity Module]
[System Prompt - Tools Module]
[System Prompt - Format Module]
[CLAUDE.md Content] ← Inserted here
[System Prompt - Safety Module]
[Historical Conversation]
[Current Input]
Why inserted here? Because:
- After tools module: can reference tools, override tool descriptions
- Before safety module: CLAUDE.md safety rules can be reinforced by system safety module
- Before historical conversation: as part of “context”
CLAUDE.md content is cached (see article 8), so it doesn’t affect cache hit rates.
Hooks: Custom Interception Points
Hooks are another powerful feature of Claude Code—execute custom logic at specific moments.
Think of them as “automatic triggers”: when X happens, automatically do Y.
Hook lifecycle:
User Input → [beforeQuery] → Model Processing → [beforeTool] → Tool Execution → [afterTool] → Model Continues → [afterQuery] → Response to User
Hook Types
beforeQuery: After receiving user input, before model processes.
Uses:
- Preprocess input
- Check permissions
- Log records
// .claude/hooks/beforeQuery.js
export default function beforeQuery(input) {
// Log query
logQuery(input);
// Check for sensitive words
if (containsSensitiveWords(input)) {
return { action: 'warn', message: 'Input contains sensitive content' };
}
return { action: 'continue' };
}
beforeTool: After model decides to call a tool, before actual execution.
Uses:
- Check tool parameters
- Automatically modify parameters
- Intercept dangerous operations
export default function beforeTool(tool, input) {
// Bash command safety check
if (tool === 'BashTool') {
if (input.command.includes('rm -rf /')) {
return { action: 'block', reason: 'Prohibited from deleting root directory' };
}
// Auto-add confirmation flag
if (input.command.includes('git push')) {
return {
action: 'modify',
newInput: { ...input, confirm: true }
};
}
}
return { action: 'continue' };
}
afterTool: After tool execution completes, before results return to model.
Uses:
- Process tool results
- Format output
- Log execution history
export default function afterTool(tool, input, result) {
// Log tool execution
logToolExecution(tool, input, result);
// Format Bash output
if (tool === 'BashTool' && result.stdout) {
return {
action: 'modify',
newResult: { ...result, stdout: truncate(result.stdout, 1000) }
};
}
return { action: 'continue' };
}
afterQuery: After entire query processing completes, before returning to user.
Uses:
- Log complete dialogue
- Trigger follow-up operations
- Update state
The diagram: Hook lifecycle and trigger points
Practical: Custom Workflows
See how Hooks and CLAUDE.md build customized workflows.
Case 1: Automatic Code Formatting
CLAUDE.md:
## Code Standards
- Use gofmt to format Go code
- Use prettier to format JS code
beforeTool Hook:
export default function beforeTool(tool, input) {
// Auto-format before file write
if (tool === 'FileWriteTool' || tool === 'FileEditTool') {
if (input.path.endsWith('.go')) {
input.content = formatGo(input.content);
} else if (input.path.endsWith('.js')) {
input.content = formatJS(input.content);
}
}
return { action: 'continue' };
}
Case 2: Pre-commit Checks
afterTool Hook:
export default function afterTool(tool, input, result) {
// Auto-run tests after git commit
if (tool === 'BashTool' && input.command.includes('git commit')) {
// Run tests in background
runTests();
// Add to result
result.message += '\n[Tests triggered]';
}
return { action: 'continue' };
}
Case 3: Sensitive File Protection
beforeTool Hook:
const SENSITIVE_FILES = ['.env', '.ssh/id_rsa', 'secrets.yaml'];
export default function beforeTool(tool, input) {
if (tool === 'FileReadTool' || tool === 'FileEditTool') {
if (SENSITIVE_FILES.some(f => input.path.includes(f))) {
return {
action: 'block',
reason: 'This is a sensitive file, requires additional confirmation'
};
}
}
return { action: 'continue' };
}
The diagram: Custom workflows implemented with Hooks
CLAUDE.md vs Hooks: When to Use Which
Both can customize AI behavior, but serve different purposes:
| Scenario | CLAUDE.md | Hooks |
|---|---|---|
| Provide information/rules | Suitable | Not suitable |
| Modify AI behavior | Indirect | Direct |
| Automate operations | Not suitable | Suitable |
| Intercept/check | Not suitable | Suitable |
| Format/process | Not suitable | Suitable |
| Log/audit | Not suitable | Suitable |
Simply put:
- CLAUDE.md: Tell AI “how it should behave”
- Hooks: Force AI “must behave this way”
Best Practices
CLAUDE.md:
- Keep it concise, not too long (recommend <500 words)
- Focus on key points, don’t list all rules
- Update promptly, keep in sync with project
- Use Markdown format for readability
Hooks:
- Keep lightweight, don’t block for too long
- Handle errors, avoid Hook crashes affecting main flow
- Log records for debugging
- Version control, manage like code
Implications for Using Claude Code
Understanding CLAUDE.md and Hooks helps you:
Build Personalized AI: Customize AI behavior based on project characteristics.
Automate Repetitive Work: Formatting, checking, logging executed automatically.
Strengthen Safety Control: Sensitive operation interception, permission checks.
Team Collaboration: Share CLAUDE.md, unify AI usage standards.
Summary
CLAUDE.md and Hooks are Claude Code’s “customization layer”:
- CLAUDE.md is like a “house rules manual”—tells AI project special rules
- Hooks are like “automatic triggers”—execute custom logic at specific moments
Together, they build a truly personalized AI butler.
In the next article, we’ll talk about the Skills system—letting AI learn your “secret techniques.”
