Agentic Coding Agents: Core Commands, Hooks, Memory, and Skills
A practical guide to agentic coding command systems, covering authentication and billing, slash commands, lifecycle hooks, project memory, state rollback, skills, and a checklist for adopting them in engineering teams.
1. Why agentic coding needs a command system rather than a better chat box
Traditional code completion answers “how do I write this line,” while agentic coding answers “how do I complete this task.” The working loop is longer: read the repository, plan steps, edit across files, execute commands, observe errors, and revise again. When the loop becomes longer, two problems inevitably appear.
The first is stability of intent expression. The same request, such as “add authentication to this interface,” may produce completely different implementation styles in different sessions or contexts. Just as people turn repetitive work into scripts, recurring instructions should be turned into named and versioned commands.
The second is controllability of behavior boundaries. Once an agent has permission to execute terminal commands, write files, and call external capabilities, prompt-only constraints are not enough to protect engineering standards. Deterministic code checks should be inserted at key lifecycle points of tool calls, rather than relying on the model to behave well on its own.
Therefore, a mature agentic coding toolchain usually consists of six independently usable mechanisms: authentication and billing, slash commands, hooks, memory, state rollback, and skill extensions. The following sections break them down one by one.
2. Authentication determines the billing basis: understand cost before usage
Many people treat “choosing a plan” as the last step. In practice, it should be the first decision, because how you log in directly determines which account receives the token usage and which billing basis is used.
2.1 Two mainstream authentication paths
| Authentication method | Authorized entity | Billing model | Typical use cases |
|---|---|---|---|
| Account or subscription-level authorization (browser authorization or token login) | Personal account or team subscription seat | Usage quota issued per subscription cycle, commonly including session turns or usage limits within a rolling time window | Individual developers and small teams doing daily interactive coding |
| Direct API key access to model services (environment variable injection) | API credentials for a cloud-hosted model service | Pay-as-you-go by actual token consumption, or resource usage under a cloud account | Automation pipelines, scripted batch processing, and centrally managed enterprise use |
Three details are easy to get wrong:
- Credential source takes precedence over interface selection. If environment variables contain usable model-service credentials, most tools will prefer the pay-as-you-go channel. In that case, the “subscription quota” selected in the interface may not take effect.
- Mixing team and personal channels creates accounting confusion. It is best to explicitly declare the allowed credential source in project-level configuration, so personal quota is not silently consumed by CI tasks.
- Least privilege also affects billing attribution. Read-only credentials, model-scoped credentials, and quota-scoped credentials should be issued separately by project in the cloud, which makes cost attribution easier.
2.2 Four variables that affect actual spending
- Context length: Every request carries the system prompt, project convention files, snippets of currently open files, and conversation history. Longer context means higher input-side consumption.
- Cache hits: Model services commonly provide context caching. Stable repeated prefixes, such as fixed project conventions or long documents, can hit the cache and significantly reduce unit cost. Putting stable content near the beginning of the prompt is a low-cost optimization.
- Tool-call round trips: One “read file → modify code → run tests → fix errors” loop can generate multiple model requests. Coarser task decomposition means fewer round trips.
- Output length: Generated code, diffs, and explanation text are counted on the output side, and output pricing is usually higher than input pricing.
2.3 A practical cost self-check script
# Observe the usage composition of a single turn to identify where cost is coming fromecho "Input tokens this turn: $INPUT_TOKENS"echo "Cache read tokens: $CACHE_READ_TOKENS"echo "Output tokens this turn: $OUTPUT_TOKENS"echo "Tool calls: $TOOL_CALLS"# If cache reads stay below 30% over a long period, check whether convention files are being rewritten frequently
Pricing, quotas, and plan tiers change with provider policies. Capacity planning should be based on the cloud provider’s official pricing page and billing details, not on historical numbers in a document.
3. Slash commands: compile repeated instructions into team assets
3.1 Concept and two sources
A slash command is a predefined instruction triggered by / in the session input box. It comes in two forms:
- Built-in commands: Provided by the tool. They cover session management such as clearing context or compressing history, configuration viewing, context usage diagnosis, permission mode switching, configuration migration and upgrade checks, help and shortcut explanations. These commands act like a “console” and are used to observe and adjust the session state itself.
- Custom commands: Maintained by the team as Markdown files, placed in the repository’s agreed directory, and versioned with the code. These commands act like “workflows” and carry business actions.
The judgment is simple: use built-in commands when you do not need to change session state; use custom commands when the behavior needs to be reused by multiple people, reviewed, and evolved.
3.2 Directory structure for custom commands
<project>/├── agent/│ ├── project-context.md # Project-level memory and conventions│ ├── commands/ # Team-shared commands│ │ ├── review.md│ │ ├── verify.md│ │ └── perf-check.md│ └── commands.local/ # Personal commands (add to version control ignore)│ └── my-note.md├── hooks/│ ├── pre-tool.py│ └── post-write.sh└── skills/└── api-contract/
Naming supports hierarchy. For example, the file api/review.md can be recognized as /api:review, which keeps the structure clear as the number of commands grows.
3.3 A reusable command template
The command file header contains metadata, and the body is an instruction template for the model. ${1} and ${2} are positional parameters, and ${2:-default} supports a default value.
---description: Perform a structured code review on current changesargument-hint: "[module path] [strict|normal]"allowed-tools: Read, Grep, Globmodel: fast---Only review files included in `git diff --name-only`. Do not expand the scope of changes unless necessary.Review dimensions and order:1. Correctness: boundary conditions, exception paths, concurrency and idempotency assumptions2. Consistency: whether the changes conflict with conventions in `agent/project-context.md`3. Testability: whether new branches are covered by corresponding test cases4. Observability: whether failure paths include logs and metricsOutput format (up to 10 items, sorted by severity in descending order):`file:line | severity | issue | suggested fix`Target module: ${1}Strictness: ${2:-normal}
Three practical suggestions: writing what not to do in the command body is often more effective than writing what to do; use allowed-tools to tighten tool permissions and prevent review commands from modifying files by mistake; set model to a low-cost model for mechanical checks, which can significantly reduce daily spending.
4. Hooks: insert deterministic logic at lifecycle points
Slash commands constrain “this task,” while hooks constrain “every operation.” A hook is an external script triggered at fixed moments during tool execution. It is unrelated to the prompt, so its ability to persuade the model is zero. That is exactly its value.
4.1 Lifecycle event model
SessionStart --> UserPromptSubmit --> PreToolUse --> [Tool execution] --> PostToolUse --> Stop| |can block/rewrite can feedback/alert
The general conventions are as follows. Event names may differ slightly across implementations, but the semantics are consistent:
- Session start: Suitable for injecting environment information, such as the current branch, a list of files pending migration, or recently failing tests.
- Before the user submits a prompt: Suitable for context enhancement or policy interception. For example, when detecting an intent to commit directly to the main branch, append a reminder.
- Before tool call: Can validate parameters and reject high-risk operations. A script can abort by exiting with a non-zero exit code, commonly
2, and send standard error content back to the model as feedback so it can correct itself. - After tool call: Can execute formatting, type checking, or artifact registration, and feed the result back to the model.
- Session end: Suitable for cleaning up temporary files and reporting usage statistics.
4.2 Three common hook examples
#!/usr/bin/env python3# pre-tool.py: Block writes to protected pathsimport json, sysALLOW_WRITE_PREFIX = ("src/", "tests/", "docs/")PROTECTED = (".git/", "infra/prod/", "secrets/")payload = json.load(sys.stdin)tool = payload.get("tool", "")target = payload.get("tool_input", {}).get("path", "")if tool in ("Write", "Edit") and any(p in target for p in PROTECTED):print(f"Writing to protected path is forbidden: {target}. Submit a configuration change review instead.", file=sys.stderr)sys.exit(2)if tool in ("Write", "Edit") and not target.startswith(ALLOW_WRITE_PREFIX):print(f"Warning: {target} is outside the agreed change directories. Confirm whether it is necessary.", file=sys.stderr)sys.exit(0)
#!/usr/bin/env bash# post-write.sh: Format after every file write and report the resultset -euo pipefailpayload=$(cat)path=$(printf '%s' "$payload" | python3 -c 'import json,sys; print(json.load(sys.stdin)["tool_input"]["path"])')case "$path" in*.py) python3 -m black "$path" --quiet && python3 -m ruff check "$path" --fix ;;*.ts|*.js) npx prettier --write "$path" ;;*.md) npx prettier --write "$path" ;;esacecho "Formatted: $path"
#!/usr/bin/env python3# session-start.py: Inject current project state to reduce model trial and errorimport subprocess, sys, jsonbranch = subprocess.run(["git","rev-parse","--abbrev-ref","HEAD"],capture_output=True, text=True).stdout.strip()dirty = subprocess.run(["git","status","--porcelain"],capture_output=True, text=True).stdout.count("\n")ctx = {"hookSpecificOutput": {"hookEventName": "SessionStart","additionalContext": f"Current branch {branch}; uncommitted changes: {dirty}. "f"Run the full test suite under tests/ before committing."}}print(json.dumps(ctx, ensure_ascii=False))
There are four engineering constraints: hooks must be idempotent, meaning repeated execution with the same input produces the same result; hooks must have a timeout so they do not freeze the entire session; hooks must be observable, and all rejections should also be written to logs for later audit; hooks must be disableable locally, for example through an environment variable switch, otherwise debugging becomes very painful.
5. Memory: turn project knowledge into context assets
Memory solves the waste of re-explaining project background in every new session. Its essence is layered text conventions, not a database.
5.1 Three layers and loading timing
| Level | Typical location | Scope | Committed |
|---|---|---|---|
| User-level | Convention files in the user’s home directory | Personal preferences, general coding style, common command habits | No |
| Project-level | Convention files in the repository root | Team-shared architecture decisions, command lists, verification methods | Yes |
| Local override | Convention files inside the project that are ignored by version control | Personal paths, temporary debugging switches, local environment differences | No |
Project-level files should be concise because they are carried with every request and cost money each time. Write them as an onboarding note for a new colleague, not as a technical encyclopedia.
5.2 Content worth putting into memory
- The exact commands for build, test, and lint, along with their approximate duration;
- Directory responsibility boundaries, making clear which type of change should land in which directory;
- Non-negotiable constraints, such as database changes must go through migration scripts and plaintext credentials must not appear in production configuration;
- Known pitfalls and workarounds, such as explicit locking required in certain concurrency scenarios;
- Review conventions beyond code style, such as exceptions must carry context and logging must not use string concatenation.
5.3 Four common anti-patterns
- Pasting large sections of source code. The source code can be read directly. Putting it in memory only increases the cost of every turn.
- Recording information that expires quickly. Version numbers, temporary switches, and someone’s branch name can become misleading after a week.
- Duplicated and conflicting conventions. When multiple files contain contradictory instructions, model behavior becomes unpredictable.
- Treating memory as permissions. Memory is guidance at the prompt level. Any real security boundary must be enforced by hooks, permission configuration, or platform-side policies.
# Project Conventions (Example)## Common Commands- Install dependencies: `make bootstrap`- Full test suite: `make test` (about 4 minutes; must be green before committing)- Filter unit tests: `pytest tests/unit -k "auth and not slow"`## Directory Boundaries- `src/api/`: HTTP layer; only parameter validation and response packaging; no business logic- `src/core/`: Business logic; must not directly import HTTP-layer types- `migrations/`: Only generated through the migration tool; no manual changes except rollback## Hard Constraints- No plaintext credentials in code or configuration; read them from a secret management service- Any cross-service call must set timeouts and retry limits; unbounded retries are forbidden- `make test` and `make lint` must pass before committing
6. State rollback: make agent exploration cost controllable
The most unsettling thing about agents is that “I cannot tell exactly what it changed.” The state rollback mechanism, often called checkpoint or session rollback in the industry, is designed for this. It snapshots file state before each modification and allows you to roll back code changes and session history together to an earlier point.
6.1 What it can and cannot cover
What it can cover: Text changes in the file system, multi-turn conversation history, and the reasoning path derived from them. If the model misunderstands the requirement, you can return to the third message directly instead of manually running git checkout on a dozen files.
What it cannot cover: Any operation that has already produced side effects in the external world. Database writes, message delivery, object storage overwrites, image builds and pushes, production configuration changes, and ticket creation cannot be undone by a local snapshot. The team must be clear: rollback is a safety net for a local sandbox, not a change management system.
6.2 Division of labor with version control
# Recommended two-layer strategy# Layer 1: Session snapshots provided by the tool, for minute-level course correction# Layer 2: Git commits, for locking milestones at the hour level or above# Establish a clean starting point before a long taskgit switch -c feat/order-auth-agenticgit add -A && git commit -m "chore: freeze baseline before refactoring"# Commit once after each verifiable small goal to reduce loss from the next rollbackmake test && git commit -am "feat: add basic validation for order authentication"
Small commits and frequent rollbacks complement each other: the denser the commits, the safer rollbacks become; the safer rollbacks become, the more willing the model is to experiment.
7. Skills: pluggable extension of capability boundaries
When a domain-specific knowledge set needs to appear repeatedly, such as internal framework usage, field specifications for a protocol, or a fixed troubleshooting process, turning it into a “skill” is more reasonable than repeatedly pasting prompts.
7.1 Skill structure and progressive disclosure
skills/api-contract/├── SKILL.md # Name, applicability description, main instructions (keep under 1,000 lines)├── reference.md # Detailed field tables and edge cases (loaded on demand)└── scripts/└── validate.py # Executable validation script
The key design is progressive disclosure. At session start, only the skill’s name and purpose description are loaded into context. When the task is relevant to the skill, the full instructions are read. Scripts and reference material in the instructions are then loaded on demand. This way, dozens of skills can coexist without overwhelming the context.
---name: api-contractdescription: Use when adding or modifying external HTTP API contracts or generating SDKs---# API Contract Conventions1. All external interfaces must update contract files under `contracts/`.2. Field names use lowercase with underscores; timestamps use RFC 3339 strings.3. Pagination uses `cursor` + `limit`; offset pagination is forbidden.4. Error responses must include `code`, `message`, and `trace_id`.5. After changes, run `python3 scripts/validate.py` to validate contract consistency.
7.2 Division of labor among the four mechanisms
| Mechanism | Trigger | Primary purpose | Requires deterministic behavior? |
|---|---|---|---|
| Slash commands | Manual input /command |
Standardize repeatable task workflows | No, executed by the model |
| Hooks | Automatically triggered by lifecycle events | Enforce engineering standards and auditability | Yes, guaranteed by code |
| Memory | Automatically loaded each turn | Provide project background knowledge | No, understood by the model |
| Skills | Loaded on demand by relevance | Provide domain-specific capabilities | No, may include scripts |
A simple selection rule: “I need to do the same thing every time” uses commands; “this rule absolutely cannot be violated” uses hooks; “it needs to understand project background” uses memory; “it has a dedicated body of knowledge” uses skills.
8. A practical engineering workflow
Connecting these mechanisms gives a team-level workflow roughly like this:
- Prepare: Issue independent model-service credentials per project in the cloud, store them in CI secret management, and do not keep high-privilege keys on developer machines long term. Put code hosting, pipelines, and image repositories in cloud code hosting and container platform services.
- Establish a baseline: Put build and test commands, directory boundaries, and hard constraints into the project-level memory file, submit it for review, and let all members share the same context.
- Formalize management: Create custom commands for high-frequency actions, such as review, verification, release checks, and dependency upgrades, put them in the repository, and include them in the code review process.
- Add guardrails: Attach hooks before and after tool calls to implement path allowlists, automatic formatting, static checks, and dangerous-operation blocking. Write all rejection records to the cloud log service, and set alert thresholds for abnormal frequency with monitoring alerts.
- Extend capabilities: Turn internal framework usage, protocol specifications, and similar knowledge into skills. Evolve them with the repository and manage compatibility through version numbers.
- Control cost: Split usage statistics by project, observe cache hit rate and tool-call round trips. Route mechanical tasks to low-cost models and leave architecture decisions to stronger models.
- Establish metrics: Record adoption rate, rework count per task, review defect escape rate, and token consumption per person. Use data to decide the next optimization direction rather than adjusting prompts based on intuition.
9. Getting-started checklist
- Is the authentication channel clear, and are personal quotas being consumed by automation tasks?
- Is the billing basis consistent with the bill, and are usage alerts configured?
- Is the project-level convention file longer than one screen, and does it contain expired information?
- Are there “absolutely non-negotiable” rules written only in prompts without hooks as a fallback?
- Are custom commands committed, reviewed, and provided with default parameters and tool allowlists?
- Are skill descriptions kept to a reasonable length, and are detailed materials split into on-demand loading?
- Has the list of external side effects before rollback been completed, including databases, messaging, artifacts, and tickets?
- Do hooks have timeouts, logs, and local switches?
The maturity of agentic coding does not depend on how clever the prompts are. It depends on how many implicit conventions you turn into explicit assets: reusable commands, executable guardrails, versionable knowledge, and reversible exploration paths. Once these four types of assets are in place, choosing a different model or service becomes only a configuration issue.
