AI Coding Agents: A Deep Dive into Five Core Mechanisms

    This article explains the mechanism layer of AI coding agents through five core building blocks: context engineering, project-level rule files, event hooks, skills, and subagents. It covers what consumes the context window, how context compaction causes loss of critical decisions, how deterministic rules and automated hooks improve reliability, how skills load domain-specific instructions on demand, and how subagents isolate work while enabling parallelism. It also includes practical anti-patterns and a layered adoption path.

    1. What the Mechanism Layer Solves

    Many users interact with AI coding tools in a simple question-and-answer loop: describe a requirement, wait for code changes. This is enough for small projects or short, well-defined tasks. But in medium-to-large codebases, multi-file refactors, and long iterative cycles, common problems appear:

    • The agent forgets an interface agreement made three turns ago.
    • It reimplements an approach that was already rejected.
    • It edits seven files in one place without running tests.
    • It starts making things up after the context is exhausted.

    These problems usually do not come from the model’s raw capability. They come from the mechanism design of the runtime framework, commonly called the agent harness in industry.

    A mature AI coding framework is usually composed of four parts:

    1. The reasoning model.
    2. Context orchestration strategy.
    3. Tool execution and sandbox.
    4. Behavior governance mechanisms.

    The first two determine what the agent can see and do. The last two determine whether its behavior is controllable, reproducible, and auditable.

    If we abstract this mechanism layer, it converges into five core concepts. Each solves a different class of problem:

    Mechanism Problem It Solves Key Properties
    Context engineering How to allocate a limited context budget Capacity constraints, priority ordering
    Project-level rule files Persistent conventions across sessions and compaction Always-on injection, not swallowed by summarization
    Event hooks Deterministic actions are unreliable if left to the model Executable code, interceptable, blockable
    Skills Too many domain-specific instructions to keep always resident On-demand loading, progressive disclosure
    Subagents Main context pollution and inability to parallelize work Context isolation, only conclusions returned

    Each mechanism is examined below. To avoid referring to specific products, configuration file names and command names in this article are illustrative. For actual fields and naming, refer to the documentation of the tool you use.

    2. What Is Actually Inside the Context Window

    A common misunderstanding is treating the context window as the “conversation history.” In reality, conversation history is only one type of content. It is often the smallest by volume and densest in information.

    A typical session may contain seven categories of content in the context window:

    1. Conversation history: the interaction record of user prompts and model responses.
    2. File content: source code snippets, configuration, or logs that the model has read or is editing.
    3. Tool or command output: terminal execution results, search results, build output, and test output.
    4. Project-level rule files: persistent convention text stored in the project root or relevant directories.
    5. Cross-session memory: user preferences and project facts saved across sessions.
    6. Loaded skill instructions: the full instruction text injected when a skill is triggered, sometimes with scripts or reference materials.
    7. System instructions and tool definitions: the framework’s runtime rules, safety policies, tool names, and parameter schemas.

    These seven categories have completely different volume characteristics and lifespan characteristics. This distinction is the foundation for context management strategy:

    • System instructions and tool definitions: large but fixed. They must be present every turn and count as an incompressible baseline cost.
    • Tool output, especially full file reads, test logs, and search results: largest volume and fastest decay. An 800-line grep result from three minutes ago may leave only one or two useful clues for the next decision.
    • Conversation history: medium volume, but it carries the evolution of user intent, rejected options, and settled architecture decisions. Its compression cost is the highest.
    • Rule files and skill instructions: small volume but extremely high value density. This is content that must remain present.

    The engineering conclusion is therefore basic but important:

    Context is not a passive container. It is a resource that requires active budget management.

    Which content occupies the window, which content can yield space, and whether yielded information can be recovered later must all be designed explicitly.

    3. Two-Level Context Recovery and the Real Causes of “Forgetting”

    When the context window approaches its limit, mainstream frameworks usually adopt a two-step recovery strategy. The order matters.

    Step 1: Remove Large, Regenerable Content

    Older tool call outputs, file reads, and command execution results are removed first. In most implementations, this step is approximately lossless: the removed content can usually be read again, at the cost of another tool call and additional tokens.

    The hidden problem is different: if the model does not know it can no longer see a file’s content, it may keep reasoning based on residual memory and produce factual errors.

    Therefore, the cleanup phase should include a companion action: leave a placeholder note.

    Example:

    1. This file was read earlier at path: src/user/service.ts.
    2. If it needs to be referenced again, read it again before making changes.

    Step 2: Summarize and Compress Conversation History

    This is a lossy operation. Compression condenses exact wording, numeric values, code snippets, and negative statements into summaries.

    Forgetting starts here. It can be broken down into three layers.

    Layer 1: Loss of Semantic Details

    Suppose in turn 3 you say:

    Use cursor instead of offset for pagination because offset degenerates into a full-table scan under deep pagination.

    After compression, it may become:

    Discussed the pagination approach.

    The premise and reasoning behind the rule are gone. The model can no longer follow the decision properly.

    Layer 2: Loss of Negative Information

    Summaries naturally favor recording what was done. Statements about what should not be done are easily lost during compression.

    This is the most dangerous type of loss. It does not necessarily cause an incorrect implementation; it can cause the agent to reimplement an approach that was already rejected.

    Layer 3: Broken Cross-Turn References

    A decision in turn 5 may depend on a constraint from turn 3. After compression, those two pieces may become separate summary sentences that are no longer adjacent. The causal chain disappears.

    There are four complementary countermeasures. They are ordered below by practical cost-effectiveness.

    Measure 1: Externalize Cross-Turn Rules into Project Rule Files

    Rule files are reinjected after every context compaction. Therefore, their content is not affected by summarization.

    This is the most thorough way to solve forgetting: move fragile information from the lossy “conversation” channel to the lossless “configuration file” channel.

    Measure 2: Declare a Compression Retention List in the Rule File

    Tell the agent which items must be preserved verbatim during compaction and must not be summarized. Examples include:

    • Interface field names.
    • Status code conventions.
    • IDs and reasons for rejected options.
    • Current branch migration progress.

    This is like adding an exception list to lossy compression.

    Measure 3: Trigger Compression Actively and Specify Retention Focus

    Many tools provide an explicit compaction entry point, often as a slash command that accepts a focus instruction.

    Instead of waiting for passive truncation, compress at natural task boundaries. For example:

    1. Compact this part of the conversation, preserving the API field changes from this round and the list of affected files.

    The value of active compression is that you choose the timing. If you compress right after a key conclusion and while the context is still relatively clean, the summary quality is usually better than when the system passively truncates in a messy state.

    Measure 4: Persist Key Facts in External Repository Artifacts

    Use design documents, spec files, issues, and architecture decision records.

    These artifacts do not occupy resident context. They can be read on demand. They are naturally versionable, reviewable, and transferable to the next contributor.

    This is the most reliable approach for long-term projects:

    The context window is volatile. Documents in the repository are durable.

    4. Project-Level Rule Files: Layering, Content, and Anti-Patterns

    Rule files provide the highest return among the five mechanisms. Their cost-effectiveness is usually much higher than switching models or adding more prompt text.

    There are three key design points.

    Point 1: Organize in Layers, Not as One Giant File

    A common structure is three layers:

    • User level: personal preferences that apply across projects, such as commit message style, response language, and code comment habits.
    • Project level: technology stack, build and test commands, directory responsibilities, coding standards, and prohibited actions.
    • Subdirectory level: conventions that apply only to a specific module, such as frontend component style in a frontend directory or layering constraints in a backend service.

    Subdirectory rules take effect only when reading or writing files under that directory. This can significantly reduce resident context size.

    Point 2: Only Include Information the Model Cannot Infer from the Code

    This is the only criterion for deciding whether something should go into the rule file.

    The model can infer the technology stack, framework version, directory structure, and existing code style after reading a few files. Writing those into the rule file wastes context budget.

    What is worth including:

    • Exact build, test, and lint commands.
    • Mandatory checks before committing.
    • Domain terminology and abbreviation meanings.
    • Calling conventions for external systems.
    • Explicitly prohibited operations, such as not editing generated files or not upgrading a dependency’s major version.

    An example skeleton:

    1. # Project Rules (Example)
    2. ## Build and Verification
    3. - Install dependencies: `make install`
    4. - Unit tests: `make test`, must pass before committing
    5. - Static checks: `make lint`, do not bypass warnings with comments
    6. ## Architecture Constraints
    7. - Layering: handler -> service -> repository, no cross-layer direct access
    8. - New external calls must go through wrappers under `client/`; do not inline HTTP requests
    9. ## Prohibited Actions
    10. - Do not modify the `generated/` directory; update the source definition and regenerate
    11. - Do not upgrade the major version of dependencies
    12. - Do not introduce a new logging library; use the existing project logging wrapper
    13. ## Compression Retention List
    14. When compacting the conversation, the following must be preserved verbatim and must not be summarized:
    15. - Interface field names and types
    16. - IDs and reasons for rejected options
    17. - Current database migration progress

    Point 3: Control Size and Prune Regularly

    Rule files are a resident cost. They consume budget every turn.

    Maintain them like code:

    • Remove outdated conventions.
    • Remove information that can be inferred from code.
    • Remove temporary notes that only apply to one task.

    As a practical guideline, project-level rule files are healthier when kept to a few dozen lines. If they grow to hundreds of lines, they have likely degraded into a document dump. At that point, split them into subdirectory rules or external documents.

    Anti-Patterns

    • Pasting an entire README into the rule file.
    • Copying API documentation into the rule file. It should be read on demand instead.
    • Adding volatile information such as the current sprint task. That belongs in conversation or external artifacts.
    • Stacking contradictory rules across layers. When upper-layer and lower-layer rules conflict, model behavior becomes unpredictable. Explicit priority declarations are needed.

    5. Event Hooks: Giving Deterministic Actions to Code

    This mechanism is often overlooked, but it provides one of the largest improvements in engineering reliability.

    The core logic is simple:

    If something must happen every time, do not depend on the model’s self-discipline.

    The model is a probabilistic system. If you say a hundred times, “run tests after changing code,” it will still miss it some percentage of the time. Hooks are code. When triggered, they execute deterministically.

    A hook is defined as a deterministic external command attached to a specific lifecycle event in the framework.

    Common lifecycle events include:

    • Before tool use: a command or tool is about to execute. Parameters can be checked, and dangerous operations can be blocked.
    • After tool use: a command has finished. Formatting, tests, or audit logging can run automatically.
    • Before user prompt submission: additional context can be injected, such as the current branch, uncommitted changes, or related issues.
    • Session start or end: prepare the environment, clean temporary files, or summarize changes.
    • Before compaction: persist required information so it can be restored after compression.
    • Notification or stop events: connect IM notifications or enforce final checks before ending.

    An example configuration is shown below. Field names should be adapted to the actual tool documentation.

    1. {
    2. "hooks": {
    3. "PreToolUse": [
    4. {
    5. "matcher": "Bash",
    6. "command": "scripts/guard-destructive.sh"
    7. }
    8. ],
    9. "PostToolUse": [
    10. {
    11. "matcher": "Edit|Write",
    12. "command": "make format && make test"
    13. }
    14. ]
    15. }
    16. }

    The corresponding blocking script can be very simple. It can express its decision through the exit code.

    1. #!/usr/bin/env bash
    2. # Read the JSON passed by the hook and check for dangerous patterns
    3. input=$(cat)
    4. cmd=$(echo "$input" | jq -r '.tool_input.command // empty')
    5. case "$cmd" in
    6. *"rm -rf"*|*"git push --force"*|*"DROP TABLE"*)
    7. echo "Blocked: irreversible operation requires manual confirmation" >&2
    8. exit 2 # Convention: non-zero exit blocks this tool call
    9. ;;
    10. esac
    11. exit 0

    Four High-Value Use Cases

    1. Guardrails for irreversible operations
      Force deletion, force-pushed branches, production writes, and database DDL can be blocked directly in hooks. This turns the safety boundary from “remind the model to be careful” into “technically impossible.”

    2. Automated quality gates
      After any file write, automatically run formatting and related tests. If they fail, prompt for rollback. This removes the reliance on model self-discipline for validation.

    3. Context pre-injection
      At the prompt submission event, inject the current branch, dirty file list, and the most recent CI failure reason. This reduces unnecessary exploratory tool calls by the model.

    4. Audit and observability
      Log all tool calls, durations, and exit codes. Send them to logging services and monitoring alerts. Build dashboards for metrics such as token consumption, failure rate, and block rate. In enterprise scenarios, this data can also be associated with code snapshots in object storage to trace the decision chain of a specific change after the fact.

    Usage Notes

    • Hooks must be idempotent and fast. Set explicit timeouts. Otherwise, a slow hook will directly slow down every interaction turn.
    • Decide in advance whether hook failure means blocking or allowing. A failed formatting hook should not block file writes, but a failed security-check hook should be treated as a block.
    • Hook output enters the context. Avoid printing large logs.

    6. Skills: On-Demand Domain Instructions

    Rule files solve conventions that must always apply. Skills solve another type of problem:

    A complete set of domain-specific instructions that are only needed for certain tasks.

    If you put all team standards, all framework best practices, and all internal processes into the rule file, the resident context will explode. Most of that content will be useless for a single task.

    The skill mechanism is designed for this problem through progressive disclosure, loaded in three layers:

    1. Layer 1: Metadata remains resident.
      Each skill keeps only its name and a one-line trigger description in context. The cost is very low.

    2. Layer 2: Instruction body is loaded on demand.
      When the task matches a skill description, the full instruction text of that skill is injected.

    3. Layer 3: Auxiliary resources are read on demand.
      Reference documents, templates, scripts, and example code are placed in the skill directory. They are retrieved with file-reading tools only when the instructions require them.

    A typical directory structure:

    1. skills/
    2. code-review/
    3. SKILL.md # Metadata + instruction body
    4. checklist.md # Review checklist, layer 3, read on demand
    5. report.tmpl # Output template
    6. scripts/
    7. diff-stat.sh # Executable script

    The header metadata of SKILL.md determines whether the skill is triggered. It should describe when to use it, not what it is.

    1. ---
    2. name: code-review
    3. description: Use when the user asks for code review, PR review, or quality checks; provides layered review checklists and structured report output
    4. ---
    5. # Code Review Process
    6. 1. Run `scripts/diff-stat.sh` to obtain the change scope.
    7. 2. Check layer by layer using `checklist.md`: correctness -> edge cases -> concurrency and resource release -> observability -> readability.
    8. 3. Use `report.tmpl` for output. Every issue must include file path, line number, reason, and suggested fix.
    9. 4. Only report issues that cause defects or significantly increase maintenance cost. Do not report pure style preferences.

    Division of Labor with Rule Files

    Rule files are like a constitution: resident, short, and applied without distinction.

    Skills are like work instructions: on demand, potentially long, and conditionally applicable.

    The criterion is whether the instruction is only valid for a specific task type:

    • If yes, make it a skill.
    • If no, write it into the rule file.

    When to Create a Skill

    Create a skill when:

    • The same type of workflow is triggered repeatedly.
    • It contains team-specific operational steps or external system interaction conventions.
    • It needs executable assets such as scripts or templates.
    • The instruction is long and has a clearly definable trigger condition.

    Anti-Patterns

    • Writing overly broad skill descriptions, such as “used for coding.” This can trigger on almost every task, degrade into resident overhead, and become worse than simply writing rules.
    • Creating overlapping skill responsibilities that compete when triggered.
    • Turning one-time instructions into skills.

    7. Subagents: Context Isolation and Task Parallelism

    The first four mechanisms mainly optimize how to use a single context window. Subagents solve a different dimension:

    The main context cannot expand indefinitely, so move part of the work into another window.

    Mechanically, a subagent is an executor with its own context window, its own system prompt, and its own tool permission scope.

    The parent agent delegates a task to the subagent. The subagent performs exploration, execution, and verification inside its own window. It returns only the final conclusion to the parent agent. Dozens of intermediate file reads and command outputs remain in the subagent’s window and disappear with it.

    This design provides three benefits:

    • Context isolation
      A task such as “find all places that call the old API and estimate the impact surface” may require reading twenty files and returning thousands of lines of intermediate output. If done in the main window, the main context is filled with noise. If delegated, the main window receives only a short conclusion.

    • Reduced pollution
      Exploration includes many failed attempts and rejected assumptions. In the main context, these continue to interfere with subsequent judgment. Isolation prevents them from affecting the main decision thread.

    • Parallelism
      Multiple independent subtasks can be delegated at the same time, significantly reducing wall-clock time.

    Delegation Criteria

    Suitable for Delegation

    • Breadth-first search tasks, such as “which modules use this configuration item?”
    • Implementation of independent submodules.
    • Exploration requiring many trial-and-error cycles.
    • Independent verification or review. Using a subagent that did not implement the code for review can provide a more objective perspective and avoid self-justification about why the code was written a certain way.

    Not Suitable for Delegation

    • Interactive design discussions that require continuous back-and-forth with the main thread.
    • Multiple subtasks modifying the same batch of files. This causes write conflicts and requires serialization or explicit file boundary partitioning first.
    • Outputs whose conclusions are inherently large and must return entirely to the main window. They would need to be compressed during return, which effectively creates a detour.

    Orchestration Mode Trade-offs

    This is a more upstream decision than “whether to use subagents.”

    Single-Loop ReAct Style

    The model runs in a loop: think -> call tool -> observe -> think again, until an answer is produced.

    Advantages:

    • Simple to implement.
    • Predictable behavior.
    • Suitable for tasks with clear boundaries.

    Disadvantages:

    • All intermediate information accumulates in the same window.
    • Long tasks will inevitably trigger compaction.

    Plan-and-Execute

    First produce an explicit plan, then execute step by step, with validation at each step.

    Advantages:

    • Much better controllability and recoverability for long tasks.
    • The plan can be manually reviewed.
    • Execution can be interrupted and resumed.

    Disadvantages:

    • Extra planning overhead at the beginning.
    • If the plan deviates from reality, replanning is required.

    Multi-Agent Collaboration

    Multiple specialized executors divide the work, while the parent agent only schedules and aggregates results.

    Advantages:

    • Highest parallelism.

    Disadvantages:

    • Higher coordination complexity.
    • Higher total token consumption.
    • Context inconsistencies between subagents can lead to conflicting conclusions, requiring arbitration rules.

    Selection Principle

    • The more uncertain the task, the more the plan should be made explicit first.
    • The more divisible the task, the more worth parallel delegation.
    • Only introduce full multi-agent orchestration when the task scale truly exceeds single-window capability.

    Introducing complex orchestration just to “look more advanced” usually increases both debugging cost and token cost.

    8. Combining the Five Mechanisms into a Practical Plan

    Using only one mechanism provides limited benefit. Real results come from layered combination.

    A practical adoption order is:

    Layer 1: Establish Rule Files First

    This is the highest-return step and often shows results within half an hour.

    Write down:

    • Build commands.
    • Verification commands.
    • Prohibited actions.
    • Domain terminology.

    Layer 2: Add Hooks for Determinism

    Prioritize two things:

    • Blocking irreversible operations.
    • Automatically running formatting and tests after file writes.

    These two steps eliminate the most severe class of accidents.

    Layer 3: Turn Repeated Workflows into Skills

    Observe for one or two weeks. Turn repeatedly triggered task types into skills, such as:

    • Code review.
    • Writing tests.
    • Troubleshooting a specific class of failures.
    • Generating migration scripts.

    The main rule file can be slimmed down accordingly.

    Layer 4: Use Subagents for Breadth-First Tasks

    Move search, impact analysis, and independent review out of the main window.

    Layer 5: Establish Metrics

    Without metrics, it is impossible to judge whether optimization is effective.

    At minimum, track:

    • Token consumption per task.
    • Number and location of compaction triggers.
    • Number of hook blocks and false-block rate.
    • Tool call failure rate.
    • First-pass task success rate.

    Export these metrics to logging services and monitoring alerts. Only then can you tell whether rule files have become too long, whether skill descriptions need tighter scoping, or whether the orchestration mode needs adjustment.

    When deployed in the cloud, these supporting capabilities usually map to common cloud-service categories:

    • Model inference services provide the underlying capability.
    • Object storage stores code snapshots and distributes skill packages.
    • Message queues handle asynchronous subtask scheduling.
    • Container platforms host execution sandboxes.
    • Logging and monitoring handle metric collection and alerting.

    The exact integration approach depends on the official documentation of the selected platform.

    9. Common Anti-Pattern Checklist

    • Repeating rules in conversation instead of externalizing them.
      This is the most common waste. If a rule needs to persist across turns, put it in a rule file.

    • Letting rule files grow into a document dump.
      Resident cost scales with length. Prune regularly and keep only information the model cannot infer.

    • Using hooks to print large logs.
      Hook output enters context and increases window pressure.

    • Designing hooks without timeout and failure semantics.
      A stuck formatting hook can drag down the entire session.

    • Writing overly broad skill descriptions.
      The more generic the trigger condition, the higher the false-trigger rate. Skills eventually degrade into resident overhead.

    • Dispatching multiple subagents to modify the same files in parallel.
      Write conflicts will appear in harder-to-debug forms.

    • Waiting passively for compaction while context is messy.
      Proactively compress after key conclusions. The difference in summary quality is obvious.

    • Leaving key facts only in the conversation.
      The context window is volatile. Specs and design documents in the repository are durable.

    10. Conclusion

    These five mechanisms point to the same goal:

    Turn the coding agent from an uncontrollable black box into a governable engineering system.

    • Context engineering determines how resources are allocated.
    • Rule files ensure key conventions survive compaction.
    • Hooks turn mandatory actions into technical necessities.
    • Skills make specialized capabilities available on demand without occupying budget continuously.
    • Subagents trade isolation for a cleaner main window and parallel execution.

    The most immediately effective mechanisms are rule files and hooks. Rule files often show results within half an hour. Hooks can eliminate the most severe class of accidents in one step.

    Start in that order, observe token consumption and compaction frequency, and gradually tune the mechanisms to match the scale of your codebase.