Building with Intelligence: Subagents, Hooks, and Output Styles
Building with Intelligence: Subagents, Hooks, and Output Styles
Section titled “Building with Intelligence: Subagents, Hooks, and Output Styles”Beyond simple chat, Claude Code offers a powerful toolkit for building robust, intelligent automations. This is where you graduate from being a user to a creator. In this chapter, we’ll explore the three fundamental building blocks that allow you to customize, extend, and control Claude Code’s behavior: Subagents, Hooks, and Output Styles.
Subagents: Your Specialized AI Team
Section titled “Subagents: Your Specialized AI Team”Imagine you’re managing a software project. You wouldn’t ask a single developer to be an expert in database administration, frontend design, and cybersecurity. Instead, you’d build a team of specialists. That’s exactly what ‘Subagents’ are for Claude Code.
A Subagent is a specialized AI agent you define for a specific task. It has its own system prompt, its own set of allowed tools, and its own context window. When the main Claude Code agent encounters a task that matches a subagent’s expertise, it can delegate the job to that specialist.
You can create subagents at the user level (~/.claude/agents/) to have them available everywhere, or at the project level (.claude/agents/) to share them with your team. They are defined as Markdown files with YAML frontmatter.
---description: A subagent that reviews code for quality, style, and potential bugs.allowedTools: - Read - Grep---
You are an expert code reviewer. Your task is to analyze the provided code files. Look for violations of the project's style guide (PEP8 for Python), identify potential bugs, and suggest improvements for clarity and performance. Do not suggest adding new features.With this file in your project, you can now invoke it. Claude Code might delegate automatically if your prompt is specific enough (> review my recent code for style issues), or you can request it explicitly (> use the code-reviewer subagent to check the auth module).
Hooks: Triggering Custom Actions
Section titled “Hooks: Triggering Custom Actions”If Subagents are your specialists, ‘Hooks’ are the automated processes that ensure rules are followed and workflows are consistent. Hooks are custom shell commands that you can configure to run at specific points during Claude Code’s execution lifecycle. They give you deterministic control over the agent’s behavior.
This is incredibly powerful for enforcing project standards, integrating with other tools, or adding custom validation steps. Hooks are configured in your settings.json file.
Here are some key events where you can insert a hook:
PreToolUse: Runs before a tool (likeWriteorBash) is used. A great place for a validation step. You can even block the tool use if your script returns a non-zero exit code.PostToolUse: Runs after a tool has been used. Perfect for logging actions or running a code formatter/linter after a file is written.UserPromptSubmit: Runs right after you submit a prompt, but before Claude sees it. You could use this to inject extra context or validate the prompt.Stop: Runs when the agent has finished its response.
{ "hooks": [ { "event": "PostToolUse", "tool": "Write", "pattern": "\\.py$", "hook": "black $CLAUDE_CODE_TOOL_ARG_PATH" } ]}In this example, we’ve set up a PostToolUse hook. Whenever Claude Code uses the Write tool on a file ending in .py, this hook will automatically run the black code formatter on that file. This ensures all generated Python code adheres to project standards without you or the AI needing to remember.
Output Styles: Controlling the Presentation
Section titled “Output Styles: Controlling the Presentation”How you receive information is just as important as the information itself. Claude Code provides different ‘Output Styles’, primarily for headless or scripted use, to ensure you can easily parse and utilize its responses.
You can specify the output format using the --output-format flag when running in non-interactive mode (-p or --print).
text(default): This provides a standard, human-readable text output, similar to what you see in interactive mode.json: This style formats the entire response as a single JSON object. This is ideal for programmatic use, as you can easily parse the result, cost, token counts, and other metadata with tools likejq.stream-json: For real-time applications, this style streams the conversation as a series of JSON objects, one for each message turn. This allows you to process the conversation as it happens.
# Get a standard text responseclaude -p "what is the capital of France?"
# Get the response as a single, parsable JSON objectclaude -p "write a python function to add two numbers" --output-format json
# Get a stream of JSON objects representing the conversationclaude -p "build a simple web server in node.js" --output-format stream-jsonBy mastering Subagents, Hooks, and Output Styles, you can transform Claude Code from a helpful assistant into a fully integrated and customized engine for intelligent automation in your development lifecycle.