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
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
.
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).
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.
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.
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.
- 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).
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.