Skip to content

Instantly share code, notes, and snippets.

@rstacruz
Last active May 26, 2025 08:09
Show Gist options
  • Save rstacruz/50513354af4e0ca9ec9adfc764411689 to your computer and use it in GitHub Desktop.
Save rstacruz/50513354af4e0ca9ec9adfc764411689 to your computer and use it in GitHub Desktop.
Stop letting Aider code blindly - try this first

Stop letting Aider code blindly - try this first

Using Aider's /ask and /architect commands to approach larger tasks.

Aider is one of the best AI coding tools available today (in my opinion!). It's a brilliant AI coding assistant that integrates with any LLM, in any code editor.

However, Aider can often feel very eager to make changes. It jumps right into coding after I type anything. I noticed a pattern:

  • I would describe what I wanted
  • Aider would start coding right away
  • We'd often end up confused or going down wrong paths

Solution: "planning" mode

For anything more complex, I've found you can ask Aider to plan work before starting. Aider doesn't come with a built-in planning mode, but Aider's built-in commands should be enough:

  • Step 1: Give Aider an idea with /ask. Give it hints for the most relevant files.
  • Step 2: Answer Aider's questions with /ask again.
  • Step 3: Make Aider write a plan. /ask for revisions if needed.
  • Step 4: Start coding with /architect proceed.

Step 1: Prepare a crude prompt

I'd give Aider a rough idea of what I want to happen.

  • Use the EDITOR (ctrl-x ctrl-e) for multi-line prompts.
  • Begin with the /ask <guidelines>...</guidelines> preamble below. I have this saved as a snippet in my editor.
  • Include filenames for reference files. I find :r!git grep -wl ThingHere (in Neovim) is useful for finding these.

me:

/ask <guidelines>
1. Step 1: Gather info
  - Request files
  - Ask questions
  - No coding yet
  - Do NOT go to step 2 until plan is ready to write
2. Step 2: Write plan
  - Short title for plan (10 words max, h2 heading, imperative like 'Add feature')
  - Original prompt (rewrite my original prompt and clarifying answers, optimise for minimum tokens while keeping meaning)
  - Relevant files (list files to modify or reference)
  - Background (bullet points)
  - Requirements
  - Actions (numbered steps)
  - Out of scope

Do not proceed to make code edits until I say 'proceed'.

Writing guidelines:
  - Use h2 headings, sentence fragments, concise, straight to the point
  - When writing code blocks, make it as simplified as possible
  - Follow coding principles: YAGNI, SOLID, KISS, DRY
</guidelines>

in ChatForm, i want the textbox placeholder to change depending on the action selected

if action = define, then placeholder = "Word to define"
if action = examples, then placeholder = "Phrase or word"
if action = chat/ask, then placeholder = same as it is now
if action = translate, then placeholder = "Phrase in target language"

see:

src/components/ChatApp/ChatApp.tsx
src/components/HomeForm.test.tsx
src/components/HomeForm.tsx
src/lib/ui.chatlog/ChatForm.stories.tsx
src/lib/ui.chatlog/ChatForm.test.tsx
src/lib/ui.chatlog/ChatForm.tsx
src/components/ChatApp/ChatApp.tsx

In this example, I want Aider to work on ChatForm. The git grep pulled in a few references to ChatForm (eg, ChatApp).

Step 2: Answer Aider's questions

Aider will likely ask to add the referenced files. Use a to add them.

> src/components/ChatApp/ChatApp.tsx
> Add file to the chat? (Y)es/(N)o/(A)ll/(S)kip all/(D)on't ask again [Yes]: a

Aider will start asking questions. Answer them in /ask mode (important!).

Aider:

1. **Action values:**
   - Are the possible values for `action` exactly: `define`, `examples`, `chat`, `ask`, `translate`?
   - Should `ask` and `chat` share the same placeholder as now ("Message #channel")?

2. **Where is the action value set?**
   - In `ChatForm`, the prop is called `command`. Is this always the same as the "action" you refer to?
   - Is the mapping from `command` to placeholder always 1:1, or are there aliases (e.g., `ask` and `chat` both mean "chat")?

3. **Custom placeholder support:**
   - Should the placeholder ever be overridden by a parent, or is it always determined by the selected action?
…

Me:

/ask 1. "chat" and "ask" are the same.
2. sorry, by "action" i meant "command".
3. placeholder is controlled by ChatForm.
…

Warning

Don't forget to prefix with /ask. When answering in any other mode (eg, the default mode, code, or architect), Aider will start coding prematurely.

Step 3: Review plan

Once Aider has enough information, it will provide a plan. Review this plan carefully. It might be high-level or detailed depending on the complexity and your initial prompt.

There may be code samples (this example doesn't).

Aider:

> # Update ChatForm Placeholder Based on Action

### Original prompt

Change the ChatForm textbox placeholder to match the selected action:

- "define" → "Word to define"
- "examples" → "Phrase or word"
- "chat" or "ask" → current placeholder
- "translate" → "Phrase in target language"

No localization. Fallback to current behavior for unknown actions. Update tests and Storybook to cover this.

### Relevant Files

- `src/lib/ui.chatlog/ChatForm.tsx`
- `src/lib/ui.chatlog/ChatForm.stories.tsx`
- `src/lib/ui.chatlog/ChatForm.test.tsx`
- `src/components/HomeForm.test.tsx`
- `src/components/HomeForm.tsx` (for context/reference)
- `src/components/ChatApp/ChatApp.tsx` (for context/reference)

### Background

- The `ChatForm` component displays an input box for user messages.
- The placeholder text should change based on the selected `command` (action).
- The possible commands are: `define`, `examples`, `chat`, `ask`, `translate`.
- `chat` and `ask` are equivalent and should use the default placeholder ("Message #channel").
- The placeholder logic is internal to `ChatForm` and does not need to be overridden by parents.
- Tests and stories should verify the correct placeholder for each command.

### Requirements

- Dynamically set the input placeholder in `ChatForm` based on the current `command` prop.
- Use the following mapping:
  - `define` → "Word to define"
  - `examples` → "Phrase or word"
  - `translate` → "Phrase in target language"
  - `chat` or `ask` (or any other) → current default ("Message #channel")
- Update tests and stories to verify the correct placeholder for each command.

### Actions

1. **Update `ChatForm` component:**
   - Add logic to determine the placeholder string based on the `command` prop.
   - Use the mapping above.
   - Pass the computed placeholder to the input element.

2. **Update stories in `ChatForm.stories.tsx`:**
   - Add or modify stories to show the placeholder for each command.
   - Visually verify in Storybook.

3. **Update tests in `ChatForm.test.tsx`:**
   - Add/modify tests to check that the correct placeholder appears for each command value.

4. **Update `HomeForm.test.tsx` if needed:**
   - Ensure tests that render `ChatForm` with different commands check the placeholder.

5. **(Optional) Update `HomeForm.tsx` if needed:**
   - If `command` is set to something other than `define`, ensure the placeholder logic works as expected.

### Out of Scope

- Internationalization (i18n) of placeholder text.
- Allowing parent components to override the placeholder.
- Adding new commands or changing command values.
- Any changes to backend or unrelated UI.

Step 3: Go!

There are a few things we can do from here:

  • Ask for revisions: If anything in the plan is wrong, tell Aider with /ask change X to Y.
  • Gather more context: Use /context to ask Aider to look for more files that may be relevant.
  • Use Aider: Use /architect proceed to make Aider start coding.
  • Save for later: Copy it to the clipboard with /copy. The plan can be used as a prompt later - either in Aider or another tool.

Key takeaways

  • The code mode (default) and architect mode will make edits right away.
  • The ask mode doesn't. Use /ask to trigger it. Use this to have a conversation about making a plan first.
  • Add filenames to the prompts to give hints of where to start looking first. Aider will automatically add them (with a prompt).

Reflections

After doing this for a while, I realised a few things:

Context is king. LLM's are simply functions that take some text and produce more text (fn(prompt) → answer). The trick to getting the most out of them is getting the input right: prompt and context. The "planning mode" here is merely a way to ask an LLM to help prepare both prompt and context for you.

Using LLM's is a skill. Working effectively with LLMs is a learnable skill. This planning approach isn't unique to Aider - I've successfully applied similar methods with GitHub Copilot and even LLM webchats. As LLM AI assistants become more prevalent, I expect that knowing how to to get productive interactions with them will be increasingly important.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment