Instructing Devin Effectively
How to achieve optimal results
The most important thing to remember when instructing Devin is to be as specific as possible. Just as you would provide a detailed spec when asking a coworker to code something, you should do the same with Devin. This guide will help you structure your instructions/prompts to maximize Devin’s utility. For broader strategies on working with coding agents effectively, also check out our Coding Agents 101 guide.
Example Prompt
In the Devin repo, I want you to build a tool that monitors the RAM and CPU usage of the remote machines that Devin runs on. To do that, please perform the following tasks:
- Create a background task that launches automatically when devin.rs starts.
- The task should open a connection to all forked remote machines used in this Devin session and monitor their RAM and CPU usage.
- If usage exceeds 80% of the available resource, emit a new type of Devin event to signal this (check how we use Kafka).
- Architect this in a smart way that doesn’t block other operations. You should understand how all the containers for the Devin sub-agents interact with each other.
Why This Works Well
Provides Helpful Context
- Detail: Specifies the Devin repo and the broader purpose (monitoring resource usage).
- Benefit: Devin knows the scope and domain clearly.
Gives Step-by-Step Instructions
- Detail: Tasks like “create a background task” and “emit an event at 80% usage.”
- Benefit: Breaks down the work into logical parts.
Defines Clear Success Criteria
- Detail: Defines “success” as emitting a specific event upon 80% usage.
- Benefit: Devin knows exactly what to achieve.
References Existing Patterns and Code
- Detail: Mentions Kafka and container interactions.
- Benefit: Encourages reuse of established code or design approaches.
Try the Prompt Improvement Button when you create a session (click the yellow warning circle to see feedback)
Best Practices: Do’s and Don’ts
Be Opinionated and Specific
Be Opinionated and Specific
Do: Provide Clear Directives
- Why: Devin can get stuck without a clear path or when faced with too many interpretations.
- How:
- Make important decisions and judgment calls for Devin.
- Offer specific design choices and implementation strategies.
- Define clear scope, boundaries, and success criteria.
- Example: “Optimize the getOrderDetails query in orderService.js by adding a composite index on the order_id and product_id columns in the order_items table. Refactor the query to replace the existing correlated subquery with a JOIN to the products table for fetching product details.”
Don’t: Leave Decisions Open-Ended
- Why: Vague instructions can lead Devin to implement solutions that don’t align with your actual needs.
- How:
- Avoid statements that require Devin to make significant design or implementation decisions without guidance. This can lead to unexpected results.
- Example: Don’t: “Improve our database’s performance.”
Leverage Devin's Strengths
Leverage Devin's Strengths
Do: Pick tasks that Devin is good at
- Why:
- Maximize Results: By assigning tasks that align with Devin’s capabilities, you can get the best results for the least amount of effort and ACUs spent. Asking Devin to do tasks that are far outside its current capabilties can often lead to poor results.
- How:
- Read this guide: When to use Devin
- Especially for advanced tasks, provide examples, modules, resources, and templates that Devin can follow.
- Share direct links to docs sites so Devin can read about details like API request bodies and features it might not know about.
- Share specific filenames that you want Devin to look at and learn from
- Example: Do: “Refactor state management in the Header component to use React’s useReducer hook for better scalability and maintainability. Ensure that all existing functionality is preserved and add unit tests to cover the new state logic.”
- Example: Do: “Use authTemplate.rs as a reference to maintain consistency in error handling.”
- Example: Do: “Check out the official Sequelize docs at https://sequelize.org/docs/v6/getting-started/ for migration steps.”
Don’t: Assign Tasks Outside Devin’s Core Competencies
- Why: Assigning tasks that require advanced domain knowledge or heavy design decisions without adequate guidance can lead to inefficiency and wasted ACUs.
- How:
- Avoid tasks that demand significant creative or high-level strategic input without clear instructions or references.
- Avoid tasks that require strong visual abilities, e.g. implementing Figma designs, since while Devin can see web pages, Devin doesn’t have perfect eyesight.
- Avoid asking Devin to create mobile apps since it doesn’t have access to a phone and can’t easily test its work.
- Example: Don’t: “Create a new authentication system for my website from scratch.”
- Example: Don’t: “Turn this Figma mockup into a React component.”
- Example: Don’t: “Build an AI-powered shopping app.”
Take Over When Necessary
Take Over When Necessary
Do: Collaborate by Completing Partial Tasks
- Why: Sometimes it’s faster for you to finish the last 20% of a task.
- How:
- Let Devin handle most of the implementation, then refine.
- Use Devin to expedite the parts of the workflow that are repetitive, while you focus on more critical aspects.
- Example: Do: “Generate the initial boilerplate code for the new API endpoint, then I will integrate it with the existing authentication system.”
Don’t: Rely Solely on Devin for Entire Complex Projects
- Why: Over-reliance on Devin for tasks that require nuanced understanding or creative problem-solving can cause delays and suboptimal results.
- How:
- Avoid assigning Devin tasks that you know will require significant human intervention to complete effectively.
- Example: Don’t: “Develop the entire backend infrastructure for our new gen AI feature”
Use Feedback Loops
Use Feedback Loops
Do: Establish Clear and Frequent Checks
- Why: Frequent feedback (both from you and from tests/checks/linters) ensures Devin corrects mistakes effectively.
- How:
- Use tests (unit/integration) to confirm correctness.
- Maintain build validations, lint checks, and static analysis for code quality.
- Example: Do: “Run npm test after each iteration.”
- Example: Do: “Ensure the pipeline on CircleCI doesn’t fail.”
- Example: Do: “Pass ESLint/Prettier checks before pushing any commits.”
Don’t: Neglect Providing Feedback
- Why: Without feedback, Devin won’t know if its solutions meet your standards.
- How:
- Avoid assigning tasks without defining how you’ll evaluate them.
Set Checkpoints
Set Checkpoints
Do: Set Clear Checkpoints and Sub-Tasks
- Why: Breaking down complex tasks into smaller checkpoints helps Devin stay focused and reduces errors.
- How:
- Split tasks into verifiable sub-tasks, and start one Devin session for each sub-task.
- Define what success looks like for each sub-task and optionally set checkpoints within each sub-task.
- Ask Devin to report back after completing each checkpoint or sub-task.
Examples:
- Example: Do: “When working with the dataset, verify that it has at least 500 rows and contains columns X, Y, Z.”
- Example: Do: “When modifying the API, confirm the endpoint returns status 200 and includes all required fields.”
- Example: Do: “When updating UI, check that the component renders without console errors and matches the design spec.”
Don’t: Skip Specific Validation Requirements
- Why: Without defined validation steps, Devin cannot confidently complete tasks.
- How:
- Avoid vague success criteria.
- Don’t leave verification steps implicit or undefined.
- Example: Don’t: “Make sure it works.”
Use Playbooks
Use Playbooks
For repetitive or complex tasks, we suggest using and iterating on Playbooks. Learn more about using playbooks effectively. Playbooks are reusable and shareable prompts that streamline task delegation. For example, if you want Devin to address ongoing CI build failures, create a playbook that includes the general steps Devin should follow each time.
Conclusion
Frame tasks with enough structure and clarity to to get reliable, satisfying outcomes.