iTranslated by AI
Controlling Codex via Decision Rules, Not Just Prompts
Introduction
When having Codex write code, you may encounter behaviors like these:
- Starting a massive refactor for a minor fix
- Ignoring existing design to create a new architecture
- Adding unnecessary dependencies on its own
- Omitting error handling
- Stopping with incomplete code
It is not a lack of knowledge.
The problem is "a lack of decision criteria."
The conclusion of this article is simple:
Codex is not something to be controlled by a "prompt."
It should be designed as an execution environment controlled by decision rules.
At the core of this is developer_instructions.
However, the method of specifying and the name of developer_instructions vary depending on the environment.
In this article, I will treat it as a design unit—a "decision rule that is always effective for the entire agent"—without assuming a specific configuration file name.
What This Article Covers
In this article, I will organize developer_instructions not as a "strong prompt," but as the decision layer of an AI agent.
I will cover the following four points:
- The difference between
developer_instructionsandAGENTS.md - Why decision rules stabilize Codex behavior
- Templates usable in professional settings
- Common anti-patterns
What is developer_instructions?
developer_instructions are decision rules for controlling Codex's behavior.
Roughly speaking, you can define the following for Codex:
- How to judge
- How to implement
- What to avoid
- What output format to use
- When to consider it complete
What is important is that this is not just supplementary information.
Since its role is different from project-local instructions like AGENTS.md, it has a strong influence on the behavior of the AI agent.
A Rough Design Model
It is impossible to definitively determine the exact priority of internal implementations from the outside.
Therefore, in this article, I will divide it as follows for practical purposes:
Top-level behavioral rules: developer_instructions
Project context: AGENTS.md
Current request: user prompt
In this article, I treat developer_instructions as the "top-level decision rules" in our practical design model.
Understand in a Nutshell
developer_instructions = Behavioral rules
AGENTS.md = Context
user prompt = Task
Codex is not just a "tool that executes commands."
It works more stably in professional settings if you treat it as an agent that makes decisions according to rules.
Difference from AGENTS.md
AGENTS.md and developer_instructions are easily confused, but their roles are quite different.
| Item | developer_instructions | AGENTS.md |
|---|---|---|
| Main Role | Definition of decision rules | Sharing project context |
| Scope | Behavior of the entire agent | Repository or directory unit |
| Content | Policies, constraints, completion conditions, safety rules | Configuration, commands, conventions, notes |
| Nature | Similar to a policy | Similar to a README |
| Example | Confirm before destructive operations | Execute tests via pnpm test
|
If I were to distinguish them in one phrase:
developer_instructions = How to decide
AGENTS.md = How to operate in this project
If you mix these two, decision rules and project context will end up in the same place, making it difficult to know which one should be updated.
Why developer_instructions Are Important
When having an AI agent write code, most failures arise not from a "lack of knowledge," but from "misjudgment."
For example, cases like these:
- Starting a massive refactor for a small fix
- Ignoring existing design to create a new architecture
- Adding unnecessary dependencies
- Completing without validation
- Omitting error handling
- Leaving placeholders behind
- Automatically executing migrations or deletions
You can warn the agent about these in individual prompts each time.
However, writing that every time is tedious, and omissions will occur.
Therefore, defining them as "decision rules" in developer_instructions makes it easier to stabilize the agent's behavior.
Why developer_instructions Work
LLMs basically possess the following characteristics:
- They try to create consistent behavior within the instructions given
- If explicit rules are provided, they prioritize acting according to them
- When decision criteria are ambiguous, they choose the most likely optimal solution
In other words, it works like this:
No rules -> Act on guesswork -> Behavior becomes inconsistent
Rules exist -> Decision criteria are fixed -> Behavior stabilizes
developer_instructions is the layer that fixes these "decision criteria."
Therefore, it acts more strongly than a one-off prompt.
From Prompt Engineering to Prompt Architecture
Traditional prompt engineering was mainly centered on "how to instruct on the spot."
Fix this code
Write tests too
Explain it concisely
On the other hand, the idea of using developer_instructions is slightly different.
What kind of agent should this be based on what principles?
Which rules should always be applied?
What conditions must be met to consider it complete?
In other words, it is closer to the feeling of designing the agent's execution environment rather than just writing a prompt.
In this article, I will call this approach Prompt Architecture for convenience.
Practical Templates for developer_instructions
Below is a template organized into a format that is easy to use directly in professional work.
| Section | Role |
|---|---|
| Core Behavior | Basic decision-making |
| Decision Rules | Change policy |
| Coding Standards | Code quality |
| Execution Strategy | How to proceed |
| Safety & Constraints | Controlling dangerous operations |
| Output Rules | Output format |
| When Done | Completion conditions |
Full Template
# === Core Behavior ===
- Always prioritize correctness over speed
- Do not guess; ask clarifying questions when uncertain
- Follow instructions strictly unless they conflict with higher-priority rules
# === Decision Rules ===
- Prefer minimal changes over large refactors
- Preserve existing architecture and conventions
- Avoid introducing new dependencies unless necessary
# === Coding Standards ===
- Write clear, readable, and maintainable code
- Use explicit naming; avoid vague variable names
- Handle errors explicitly; avoid silent failures
- Add comments only when necessary for clarity
# === Execution Strategy ===
- Understand the problem before writing code
- Break complex tasks into smaller steps
- Validate assumptions before implementation
- Ensure output is directly usable; avoid placeholders
# === Safety & Constraints ===
- Do not perform destructive operations without confirmation
- Avoid security risks such as injection, secrets exposure, and unsafe eval
- Respect environment limitations
# === Output Rules ===
- Return complete, runnable code
- Do not include unnecessary explanations unless requested
- Keep responses concise and structured
# === When Done ===
- The solution works as intended
- Edge cases are handled
- Code passes tests or is testable
Why This Structure?
This template does not simply list seemingly good rules. It is structured to stabilize the agent's judgment layer by layer.
1. Core Behavior
# === Core Behavior ===
- Always prioritize correctness over speed
- Do not guess; ask clarifying questions when uncertain
- Follow instructions strictly unless they conflict with higher-priority rules
Here, we define the agent's fundamental decision-making axis. This is not about "personality." What is important are criteria such as:
- Prioritize correctness over speed
- Do not guess when uncertain
- Adhere to the priority of instructions
One common failure for AI is proceeding as if it knows the answer even when in an ambiguous state. Therefore, it is valuable to include "Do not guess" and "Ask for clarification when uncertain" as the highest-level behavioral principles.
2. Decision Rules
# === Decision Rules ===
- Prefer minimal changes over large refactors
- Preserve existing architecture and conventions
- Avoid introducing new dependencies unless necessary
Here, we fix decisions that are prone to vacillation. For instance, AI agents often perform actions such as:
- Refactoring more than necessary
- Ignoring existing configurations
- Adding libraries that look convenient
- Touching peripheral files
In professional practice, this is quite risky. Especially in existing products, consistent alignment with existing design is more important than writing "correct" code. Thus, rules like the following are effective:
Prioritize minimal changes
Respect existing architecture
Do not add unnecessary dependencies
This is more concrete than telling the AI to "do it smartly."
3. Coding Standards
# === Coding Standards ===
- Write clear, readable, and maintainable code
- Use explicit naming; avoid vague variable names
- Handle errors explicitly; avoid silent failures
- Add comments only when necessary for clarity
Here, we define the minimum baseline for code quality. Even if AI code looks like it works at a glance, problems like the following tend to occur:
- Vague variable names
- Errors being swallowed
- Excessive comments
- Temporary implementation left behind
Error handling is particularly critical.
Handle errors explicitly; avoid silent failures
This is essential for production code. When having an AI write code, you must ensure it handles not just the happy path, but explicitly addresses exceptional cases.
4. Execution Strategy
# === Execution Strategy ===
- Understand the problem before writing code
- Break complex tasks into smaller steps
- Validate assumptions before implementation
- Ensure output is directly usable; avoid placeholders
Personally, I find this section quite important. AI agents sometimes jump straight into implementation. However, in practice, there are things to do before writing code:
- Understand the problem
- Confirm the scope of impact
- Validate assumptions
- Break it down into small tasks
- Verify after implementation
By including this in developer_instructions, you make it easier to suppress the tendency to "just start writing."
5. Safety & Constraints
# === Safety & Constraints ===
- Do not perform destructive operations without confirmation
- Avoid security risks such as injection, secrets exposure, and unsafe eval
- Respect environment limitations
This is a mandatory layer for production operation. Operations like the following are particularly dangerous:
- Deleting files
- DB migrations
- Changing production data
- Outputting secrets
- Implementations leading to
evalor command injection - Destroying existing settings
The more powerful an AI agent becomes, the greater the impact of any accident. Therefore, you should establish rules for destructive operations and security risks in advance.
6. Output Rules
# === Output Rules ===
- Return complete, runnable code
- Do not include unnecessary explanations unless requested
- Keep responses concise and structured
This section is subtle but significantly changes the practical user experience. Without this, AI output tends to become:
- Too much explanation
- Code that is incomplete
- Leftover placeholders
- Returning fragmented, unexecutable code
- Hiding important changes
In particular, I strongly recommend including the following:
Return complete, runnable code
AI output should not just be readable; it must be usable as-is.
7. When Done
# === When Done ===
- The solution works as intended
- Edge cases are handled
- Code passes tests or is testable
This is the definition of "Done." When making an AI agent work, if the completion criteria are ambiguous, it will stop at a half-finished state. For example, it might exhibit behaviors such as:
- Implementing without testing
- Ignoring edge cases
- Failing to check for type errors
- Lacking a perspective on verification
- Leaving TODOs behind
Just as the Definition of Done is important for human development, AI agents also require Done criteria.
Enhanced Template
To make it more suitable for professional use, adding the following will improve precision:
# === Reasoning Control ===
- Think step-by-step for complex tasks
- Double-check critical logic before output
- Consider edge cases explicitly
# === Diff Discipline ===
- Minimize changes to existing code
- Avoid touching unrelated files
- Maintain backward compatibility
# === Review Mode ===
- After generating code, review it for:
- bugs
- edge cases
- readability
Reasoning Control
For complex tasks, it is more stable to have the AI think step-by-step rather than outputting an answer immediately. However, the key is not just to write "think long," but to concretize the perspectives it should consider.
- critical logic
- edge cases
- assumptions
By clarifying the targets in this way, output quality is more likely to improve.
Diff Discipline
In existing products, the size of the diff is crucial.
# === Diff Discipline ===
- Minimize changes to existing code
- Avoid touching unrelated files
- Maintain backward compatibility
AI may sometimes attempt to modify surrounding code to solve a problem. However, in team development, this increases the review burden. Therefore, you should explicitly communicate the following to the AI:
Do not touch unrelated files
Do not break existing compatibility
Keep diffs small
This is highly effective.
Review Mode
This is a rule to make the AI review its own work again after generating code.
# === Review Mode ===
- After generating code, review it for:
- bugs
- edge cases
- readability
This is similar to a human self-review. The following perspectives are particularly effective:
- Are there bugs?
- Are edge cases covered?
- Is it readable?
- Does it align with existing design?
- Are there unnecessary changes?
AI output is sometimes more stable after a review than in the initial pass.
Practical Usage
Small-scale Development
For small-scale personal development, the simple version is sufficient.
Core Behavior
Decision Rules
Coding Standards
Output Rules
When Done
Adding too many rules can actually make it sluggish.
Team Development
In team development, it is better to include up to the enhanced version.
Core Behavior
Decision Rules
Coding Standards
Execution Strategy
Safety
Output Rules
When Done
Diff Discipline
Review Mode
Following points are particularly important:
- Respect existing design
- Do not touch unrelated files
- Do not break compatibility
- Do not perform destructive operations
- Keep it in a testable state
Production Products
For production products, the following three are essential:
Safety
Diff Discipline
When Done
The reasons are simple:
- Prevent accidents
- Reduce review burden
- Prevent half-baked implementations
If you incorporate AI into production development, control design becomes more important than generation capability.
Common Anti-patterns
1. Too Long
Packing in too many rules can make them less effective. Here is a bad example:
- Always write beautiful, excellent, modern, robust, scalable, secure, performant, readable, elegant code...
The more abstract adjectives you add, the lower the actual effectiveness.
2. Too Abstract
Here is a bad example:
- Follow best practices
- Write good code
- Be professional
This is ambiguous regarding what exactly should be done. A good example looks like this:
- Avoid introducing new dependencies unless necessary
- Handle errors explicitly
- Avoid touching unrelated files
Breaking things down into concrete actions is important.
3. Mixing with AGENTS.md
Writing too much of the same content in both developer_instructions and AGENTS.md makes their roles ambiguous. It is recommended to separate them.
developer_instructions:
- Decision principles
- Safety constraints
- Output rules
- Completion criteria
AGENTS.md:
- Project structure
- Setup instructions
- Test commands
- Directory-specific conventions
- Technologies used
4. Writing Contradictory Rules
For example, these are likely to conflict:
- Always keep responses short
- Explain all reasoning in detail
Also, the following is dangerous:
- Never ask questions
- Ask clarifying questions when uncertain
Conflicting rules make the agent's behavior unstable.
Conditions for Good developer_instructions
Good developer_instructions are not requests; they are rules of conduct.
Bad example:
- Please implement carefully
- Make it look good
- Please ensure high quality
Good example:
- Prefer minimal changes over large refactors
- Handle errors explicitly
- Do not perform destructive operations without confirmation
- Return complete, runnable code
The point is to narrow it down to a granularity where the AI can decide its next action.
Summary
developer_instructions is not a strong prompt. It is a layer for fixing decision-making.
A good template is designed as follows:
- Do not just instruct "how to write"
- Define "how to judge"
- Clearly state completion criteria
In conclusion:
Good template = Rule of conduct
Bad template = Just a request
Depending on whether you can design this, the AI will transition from a "handy tool" to a stable development partner.
Discussion