Five Core Mechanisms of Coding Agents: A Deep Dive with Practical Implementation
Coding agents are shaped by two layers: the model that sets the reasoning ceiling, and the harness that decides how that reasoning is organized, constrained, and fed with context. This article breaks down the five mechanisms the industry has converged on — context management, rule files, lifecycle hooks, skills, and subagents — explaining what each one actually controls, how they interact, and where they fail. It includes the trade-off behind context compression, how to write rule files that are executable rather than comprehensive, why exit codes turn hooks into hard constraints, how progressive disclosure keeps skills cheap, and when delegation to a subagent pays off versus when it wastes budget. It closes with common pitfalls, a practical checklist, and notes on observability and model-agnostic deployment.
1. First, a distinction worth making: the Agent Harness is what sets the ceiling
Before getting into specific mechanisms, it helps to separate two layers: model capability and the Agent Harness.
The model determines the ceiling of reasoning. The harness determines how that reasoning is organized, how it is constrained, and how context is fed to it. The same base model can deliver wildly different engineering experiences under different harnesses. The reason is straightforward: coding work actually happens in an environment that is multi-turn, long-context, and full of frequent file reads and writes plus command execution. The harness has to solve three engineering problems:
- The context budget is finite. Even a large window is a limited resource, so something must decide what goes in and what gets dropped.
- Behavior needs constraints. The model should not decide on feel alone which files to modify and which commands to run.
- Capability needs to be extensible. You cannot stuff every tool, standard, and template into the system prompt.
The industry has gradually converged on a fairly consistent set of answers, which can be summarized as five mechanisms: context management, rule files, lifecycle hooks, skills, and subagents. These are not five independent features on a checklist. They are one context-control system with a clear division of labor. Here is each one, unpacked.
2. Mechanism one: what is actually inside the context window
A common misconception is that context equals the conversation history. In reality, conversation history is only one category of content in the window. Engineering practice usually reduces it to seven:
| Category | Content | Size profile | Value over time |
|---|---|---|---|
| System instructions | Harness runtime rules, tool definitions, call protocols | Fixed overhead | Required throughout |
| Rule files | Project-level persistent conventions (coding standards, directory layout, common commands) | Medium, fixed | Required throughout |
| Conversation history | Record of user–model exchanges | Grows linearly with turns | Declines early, low later |
| File content | Source code that has been read or edited | Large | High while editing |
| Command output | Results of builds, tests, and logs | Very large | Decays quickly |
| Automatic memory | Preferences and conclusions accumulated across sessions | Small | Effective long term |
| Loaded skills | Full instruction text injected after a skill is triggered | Large | High during the task |
2.1 Two-step reclamation as capacity runs low
Compression strategies across mainstream harnesses are largely the same. The essence is discarding by cost-effectiveness ranking:
Step one: clear out what is large and already stale. Prioritize dropping large chunks of early command output and file snapshots. A build log from thirty minutes ago will almost never affect the current decision, yet it keeps consuming budget.
Step two: summarize and compress conversation history. Condense specific wording, temporary values, and full code snippets into summary descriptions.
2.2 The real pain point: compression is irreversible information loss
The cost of summarization is routinely underestimated. A constraint established at step three, or an architecture decision settled at step five, is very likely to degrade after compression into vague phrasing like “discussed how to divide the modules.” This is not the model getting dumber. It is that constraint entries in the context have been structurally deleted. Most of the instruction forgetting, standards drift, and reinvented wheels seen in long sessions come from here.
So the criterion for deciding where a rule belongs comes down to a single question: does it need to stay in effect across multiple turns, or even across sessions?
- Needs to persist → put it in a rule file, which is re-injected every time context is assembled and does not participate in conversation summarization.
- Only meaningful for the current task → leave it in the conversation. Losing it to compression costs nothing.
2.3 Example: declaring compression-retention rules in a rule file
# Context Compression Retention RequirementsWhen generating a session summary, the following must be preserved item by item. Do not merge or generalize them:1. Confirmed interface signatures and data structure definitions2. Rejected technical approaches and the reasons for rejecting them3. Outstanding items not yet completed and the reasons they are blocked4. The list of file paths that must not be modified for this taskThe following may be generalized: raw command output, full file contents, and intermediate inferences from debugging.
The value of this declaration is that it turns “compression policy” from an implicit framework default into an explicit convention the project controls itself.
3. Mechanism two: rule files as project-level persistent instructions
Frameworks use different names for this kind of file. This article uses rules.md to refer to the rule file that carries project conventions in a repository.
3.1 The layering principle
Engineering practice suggests a three-level structure, where the file closer to the code takes higher priority:
- User level (home directory): personal preferences spanning projects, such as commit message style or comment language.
- Project level (repository root): tech stack, directory structure, build and test commands, domain constraints.
- Directory level (inside a submodule): locally specific conventions that take effect nearby, avoiding global pollution.
3.2 Write it to be executable, not to be comprehensive
The common failure mode for a rule file is writing it like a README: long, vague in tone, and unverifiable. There are three criteria for writing it effectively:
- Give commands, not descriptions. Write
npm run test:unit, not “remember to run the unit tests.” - Give boundaries, not aspirations. Write “do not modify any file under
src/legacy/“, not “be careful when refactoring legacy code.” - Control the size. A rule file lives permanently in context, so every added line consumes budget over the long term. Redundant entries dilute attention away from the critical constraints.
# Project Conventions## Tech stack- Runtime: Node.js 20+, package manager is pnpm across the board- Validation entry point: `pnpm lint && pnpm typecheck && pnpm test`## Directory conventions- Business code: src/modules/<domain>/- Do not modify: src/legacy/ (pending removal, read-only)## Commit conventions- Commit message format: `type(scope): summary`- lint and typecheck must pass locally before committing
4. Mechanism three: hooks push constraints into the execution path
Rule files are “soft constraints” — the model can still ignore them. Hooks are “hard constraints”: deterministic programs inserted at key points in the agent lifecycle, with code rather than the model doing the gating.
4.1 Common mount points
- Session start: inject environment information, load project credentials, warm up dependencies.
- Before a tool call: parameter validation, sensitive path interception, confirmation of high-risk commands.
- After a tool call: format the artifacts, append logs, trigger incremental checks.
- Session end / before commit: run full validation, generate a change summary.
4.2 Exit codes as control flow
The widely adopted convention is: the hook script returns 0 to allow the action, returns non-zero to block it, and passes the contents of stderr back to the model as the rejection reason so it can correct itself. This upgrades requirements like “do not delete files” or “do not commit code that fails tests” from the prompt level to the process level.
{"hooks": {"PreToolUse": [{"matcher": "Write|Edit","command": "./scripts/guard-protected-paths.sh"}],"PostToolUse": [{"matcher": "Edit","command": "./scripts/format-changed-files.sh"}]}}
#!/usr/bin/env bash# Block writes to protected directories: a non-zero exit blocks, and stderr is returned as the reasonTARGET="$(jq -r '.tool_input.file_path' 2>/dev/null)"case "$TARGET" insrc/legacy/*) echo "This directory is frozen and is read-only" >&2; exit 2 ;;esacexit 0
The field names and script above are illustrative only. Actual event names and configuration structures must follow the documentation of the framework you use.
4.3 When they fit and when they do not
Hooks fit constraints that must hold 100% of the time: path allowlists, command denylists, commit gates, and audit trails. They do not fit preference-style requirements. Turning “write clear comments” into a hook only adds maintenance cost without any real enforcement.
5. Mechanism four: skills as on-demand capability packs
If every domain standard, template, and internal API description were stuffed into the rule file, context would fill up fast. What skills solve is progressive disclosure.
5.1 Two-level loading
- Level one (always resident): only metadata enters the context — the skill name and a one-line trigger description, usually just a few dozen tokens.
- Level two (on trigger): only after the task scenario matches are the skill’s full instructions, scripts, and reference material loaded in.
The critical part is the quality of the trigger description. It should say “in what situation to use this,” not “what this skill is.” The former can be matched by the model; the latter cannot.
my-project/└── .agent/skills/├── db-migration/│ ├── SKILL.md # name + trigger description + steps│ ├── templates/ # migration script templates│ └── scripts/check.sh # executable validation└── api-doc/└── SKILL.md
---name: db-migrationdescription: Use when the task involves adding or changing database table structures, writing migration scripts, or planning rollbacks---## Steps1. First read templates/migration.sql.tpl as the format baseline2. Produce two artifacts: the forward migration and the rollback script3. Run scripts/check.sh to validate naming conventions and missing indexes4. Do not use nullable column changes without a default value in migration scripts
5.2 How it divides labor with rule files
| Dimension | Rule file | Skill pack |
|---|---|---|
| How it takes effect | Always injected | Loaded after trigger |
| Content nature | General constraints, project facts | Task-specific procedures |
| Quantity strategy | Fewer is better | Can grow with domains |
6. Mechanism five: subagents trade context isolation for scale
The point of a subagent is not “one more model.” It is context isolation: the main agent only receives a conclusive report, instead of pulling dozens of file reads and command outputs from the subtask into its own window.
6.1 Three direct benefits
- Protecting the main context budget. The intermediate artifacts of exploratory work (repo-wide search, dependency mapping, log analysis) stay inside the child session.
- Enabling parallelism. Multiple independent investigation tasks can be dispatched at the same time, significantly shortening end-to-end duration.
- Role specialization. Give “code review”, “test authoring”, and “documentation generation” their own system prompts and tool allowlists, which lowers the probability of out-of-scope operations.
6.2 Delegation boundaries
The cost of a subagent is startup overhead plus information loss in transmission. Therefore:
- Suitable to delegate: tasks with a well-defined scope, independently verifiable, requiring a lot of intermediate searching.
- Not suitable to delegate: requirement clarification that needs multiple rounds of back-and-forth, small changes tightly coupled to main-session context, edits where the result must be character-for-character exact.
When delegating, explicitly agree on a return structure so the child session does not send back large chunks of raw logs:
Return format (follow strictly, total length no more than 200 lines):- Conclusion: one paragraph- Key evidence: file path + line number + one sentence of explanation- Risks and unconfirmed items: listed one by one- Recommended next actions: concrete, executable steps
7. How the five mechanisms work together
The call chain in one complete task roughly looks like this:
- Session start. The harness injects system instructions and rule files; a session-start hook supplements environment and credential information.
- Task understanding. The model decides whether to load a skill, and the matching skill instructions are injected.
- Planning and execution. Source code is read and commands are run; writes pass through pre-hooks for validation, and post-hooks format and check the results afterward.
- Scaling out. When broad exploration is needed, a subagent is dispatched and only its conclusion is reclaimed.
- Approaching capacity. Large tool output is cleared first, then conversation history is compressed; rule files and current skill instructions stay resident.
- Wrap-up. An end hook runs full validation and emits the change summary plus an audit record.
Together, the five form a closed loop that runs from constraining the input, to extending capability, to reclaiming budget: rule files and hooks handle reliability, skills and subagents handle extensibility, and context management keeps the other four effectively present within a finite budget.
8. Common mistakes and a practical checklist
Mistake one: repeatedly reminding the model in conversation about long-term constraints. Write them into a rule file instead, backed by a hook for hard validation when necessary.
Mistake two: dumping all knowledge into skill packs. Skill packs only solve “task procedure,” not “whether it gets loaded.” With a vague description, a skill is dead code.
Mistake three: parallelizing subagents indiscriminately. Every child session consumes quota and time, and its returned information is lossy. Use it only when the task boundary is clear.
Mistake four: ignoring rule file size. Every line of always-resident context squeezes the usable budget. Trimming periodically matters more than appending continuously.
A practical checklist:
- Have long-term constraints been migrated from the conversation into a layered rule file?
- Are compression-retention items explicitly declared in the rule file?
- Do high-risk operations (deletion, force push, production changes) have a pre-hook to block them?
- Is there a commit gate hook before commit, and does failure actually block the flow?
- Is each skill’s trigger description written as “when to use it”?
- Are subagents constrained in return length and format?
- Is token consumption distribution recorded well enough to pinpoint which context category is inflating?
9. Two additional points for enterprise adoption
Observability. Even a complete mechanism set needs data to validate it. It is worth collecting, for every session, the context composition (token share by category), the number of compression triggers, the number of hook interceptions, and the distribution of subagent calls, then sending it all to a log service for trend analysis with monitoring alerts configured. Which category of content occupies the largest budget over the long term determines the next optimization direction.
Openness of model access. Engineering practice should treat the model endpoint as a replaceable configuration item rather than a hard-coded dependency, so the team can migrate and evaluate across model providers. If the whole agent service runs on Baidu AI Cloud, its general-purpose container platform, object storage, log service, and monitoring and alerting capabilities can handle runtime hosting and observability; on the model service side, integration should follow a general interface contract to keep it replaceable.
10. Closing
What these five mechanisms essentially do is turn “how to get a model to reliably complete engineering work” from something mystical into an engineering problem that can be designed, measured, and regression-tested: context management determines whether information survives, rule files and hooks determine whether behavior is controllable, and skills and subagents determine whether the capability boundary can expand. Mastering the judgment criteria behind them — does this piece of information need to stay in effect, does this constraint need to hold 100% of the time, does this task need context isolation — has more long-term value than memorizing any particular configuration syntax.
