# Agent code:
amount_cents = int(row['amount'])
amount_dollars = amount_cents / 100  # Converts 2900 → $29.00
if current_total_dollars + amount_dollars > 2000:
    # Batches properly
```

It creates **three batches** with proper grouping.

**The lesson:** A human sees "2900" for a "BASIC" plan and immediately thinks "$29". An agent might interpret it as "$2,900" - who pays that for basic website hosting? Without explicit units, you're gambling on the agent's interpretation.

### 4. Create custom user rules in a convention file

The practice of creating AI convention documents (like CLAUDE.md) has become increasingly popular. These files act as persistent rules that agents follow automatically.

For example, an agent implements different code styling based on whether it's using a convention document in addition to user prompts or relying on user prompts alone.

When you prompt Claude to *"refactor cart.js to modern JavaScript"* without including any style rules in `CLAUDE.md`, it makes its own decisions. It might use class syntax, skip documentation, or add features you didn't ask for.

However, when you include the following section in `CLAUDE.md`, Claude will respond to the same *"refactor cart.js to modern JavaScript"* prompt by converting function declarations to arrow functions and adding JSDoc comments, because it follows the `CLAUDE.md` rules automatically:

```markdown
## Code Style Rules
- Use arrow functions instead of function declarations
- Use const/let instead of var
- Add JSDoc comments to all exported functions
```

This example makes the power dynamic clear: When the same instruction appears in both CLAUDE.md and your prompt, CLAUDE.md usually wins. Use this to your advantage for consistent project-wide rules.

[One developer's observation on Hacker News](https://news.ycombinator.com/item?id=42900137) demonstrates how project-specific guidance significantly improves agent performance:

> I have a rule: 'Do information gathering first,' which encourages it to look around a bit before making changes.

### 5. Learn real-world safety from production disasters

The [Ory team documented](https://www.ory.sh/blog/AI-agent-lessons) a sobering incident where an AI agent accidentally deleted their production database. Here's what actually happened and how you can prevent similar disruptions:

When Ory sent a prompt telling the agent to *"Fix the database connection issue in production,"* the agent responded as follows:

```bash
⏺ Agent connected to production database
⏺ Attempted to "fix" by dropping and recreating tables
⏺ Production data: gone
```

If they had given the agent a prompt like the following, they could have prevented the disaster:

```
Set up these safety rules in your CLAUDE.md or agent configuration:
- Before making any changes, confirm the environment (test vs production).
- Never modify production databases directly.
- Require explicit confirmation for destructive operations.
- Given the option, use read-only credentials by default.
```

**The lesson:** Agents don't understand the difference between "test" and "production" unless you explicitly tell them. Always assume they'll take the most direct path to "fixing" something.

### 6. Practice constraint-based prompting

Instead of explaining in natural language, stub out methods and define code paths directly in code:

```python
def process_data(input_file: str) -> pd.DataFrame:
    """TODO: Implement data processing
    1. Load CSV file
    2. Clean missing values
    3. Normalize numeric columns
    4. Return processed dataframe
    """
    pass  # AI: implement this function following the docstring
```

### 7. Use AI to improve your prompts

The fastest way to fix a broken prompt is to use AI itself. Instead of guessing what went wrong, request specific feedback about why the prompt failed.

This works because the agent:

- Understands its own failure modes better than you do.
- Can identify ambiguities you missed.
- Suggests concrete improvements, rather than giving vague advice.

You can use an agent like Claude or ChatGPT directly by pasting your failed prompt in the console and asking for analysis.

Alternatively, you can use agent-specific tools to improve a prompt. For example, the **Workbench** page in the Anthropic console contains various tools for bettering prompts.

![Anthropic workbench interface for prompt optimization and testing](/assets/writing-prompts/anthropic-workbench-interface.png)

You can optimize your prompts by templatizing them. Make individual prompts reusable by clicking on the **Templatize** button.

![Anthropic templatize feature for making prompts reusable](/assets/writing-prompts/anthropic-templateize-feature.png)

You can also use the **Improve prompt** button to interactively develop a prompt via the **What would you like to improve?** modal.

![Anthropic improve prompt modal asking for improvement requirements](/assets/writing-prompts/anthropic-improve-prompt-modal.png)

Once you've stated your needs, Anthropic provides you with an updated prompt: 

![Anthropic improved prompt result showing enhanced prompt structure](/assets/writing-prompts/anthropic-improved-prompt-result.png)

We tested this process with the following initial prompt:

```txt
Set up Docker for this project and run the tests

{{PROJECT}}
```

And we ended up with the following prompt, improved by Anthropic tools:

```txt
Here's the project description:
<project>
{{PROJECT}}
</project>

You are an experienced DevOps engineer and coding assistant specializing in Docker containerization and testing. Your task is to help set up Docker for the given project and provide instructions on how to run tests within the Docker environment. You should be aware of the coding environment and interact with the user when necessary.

Please analyze the project and provide a comprehensive guide on setting up Docker and running tests. Follow these steps:

1. Analyze the project structure and requirements.
2. Create a Dockerfile and, if necessary, a docker-compose.yml file.
3. Provide instructions for building the Docker image and running the container.
4. Explain how to run tests within the Docker environment.

Before providing the final guide, wrap your thoughts inside <project_breakdown> tags to break down your thought process. In this section:
- List out the key components of the project
- Identify potential dependencies
- Consider any specific testing requirements
- Note any potential issues or questions you might need to ask the user

If you need any clarification about the project, ask the user before proceeding.

In your final response, structure your guide as follows:

1. Project Analysis
2. Dockerfile Creation
3. Docker Compose Setup (if necessary)
4. Building and Running the Docker Container
5. Running Tests in Docker
6. Troubleshooting Tips

For each step, provide clear explanations and reasoning for your choices. If there are multiple possible approaches, explain the pros and cons of each.

Remember to be interactive and ask for clarification if any aspect of the project is unclear or if you need more information to provide accurate instructions.

Now, please proceed with your project breakdown and guide creation.
```

This tool was built for Anthropic models and agents, but the same pattern works with others. You can ask ChatGPT, Gemini, or any LLM to refine your prompt by following the flow: **Your prompt → Goal → Refined prompt**.

### 8. Use XML tags in prompts

XML is token-rich compared to JSON or YAML: Lots of angle brackets and closing tags create strong, distinct boundaries. These clear boundaries help LLMs avoid mixing sections. LLMs aren't actually **parsing** in the strict sense, like a compiler. They're predicting tokens.

By providing an LLM with **consistent delimiters** (`<tag>…</tag>`), you enable it to do the following:

- Recognize scope easily: The `<inputs>` section is clearly different from `<outputs>`.
- Reduce ambiguity: Instead of "status (optional)," you give `<param name="status" required="false">`, and the model no longer needs to infer.

The following example demonstrates how to use XML tags to write a prompt that includes context, the desired format, and constraints: 

```xml
  <context>
    This is a legacy JavaScript project from 2018 that uses ES5 syntax and jQuery. The team maintains backward compatibility with IE11.
  </context>

  <task specificity="high">
    Add input validation to the login form: check for empty email, validate email format, ensure password is at least 8 characters, and display error messages.
  </task>

  <response_format>
    Respond with only: TESTS: PASS/FAIL, ERRORS: [count], FILES: [list of failing files]. No explanations.
  </response_format>

  <constraints>
    The files to modify are in the /components directory. Do not install new dependencies. You will find everything you need at /ui and utils.ts.
  </constraints>
```

## As agents get smarter, prompts become more important, not less

Smarter agents make more sophisticated assumptions that are harder to predict and debug. As agents get "smarter," specific prompts become more important, not less.

Your action items:

1. Create a `CLAUDE.md` (or equivalent file) for your projects with explicit rules.
2. Include units, formats, and examples in your prompts.
3. Test prompts with actual outputs before trusting them in production.
4. When something goes wrong, make your prompt more specific, not longer.