DEV Community

David Ortinau
David Ortinau

Posted on

7

Boosting GitHub Copilot Accuracy

A key challenge when using any AI coding assistance is accuracy. If the results are not reliable, that creates additional work reviewing and correcting the output. It's still great to get 80% results, but how can I get closer to 100%?

During the March 7th .NET MAUI Community Standup, I did a demo and walkthrough on using both Copilot repository-level instructions and prompt instructions -- which I'll describe in more detail below.

Copilot Instructions

GitHub Copilot provides a couple of ways to steer it toward better results, starting with copilot-instructions.md. This little file is a place to put your preferences and workspace context so that they're included with every interaction you have with Copilot. Here's what I put in one for my language learning app Sentence Studio:

Please call me Captain and talk like a pirate.

This is a .NET MAUI project that targets mobile and desktop. 

It uses the MauiReactor (Reactor.Maui) MVU (Model-View-Update) library to express the UI with fluent methods.

When converting code from C# Markup to MauiReactor, keep these details in mind:
- use `VStart()` instead of `Top()`
- use `VEnd()` instead of `Bottom()`
- use `HStart()` and `HEnd()` instead of `Start()` and `End()`
Enter fullscreen mode Exit fullscreen mode

Image description

As I discover mistakes that Copilot makes, I add more instructions here.

This file resides at the root of my project folder in the .github directory. Read more about Copilot instructions in the GitHub documentation.

Copilot Prompt Instructions

Now this is where things start to get more fun. Building on the idea of repository-level instructions, you can add more specific and detailed context that is included as needed with your prompts.

For example, I noticed that I wasn't getting perfect results when generating async/await code, which resulted in a deadlock in my app. To provide the model with additional context ONLY when I asked it to do work on async/await, I created a prompt instruction file. This yielded better results.

Image description

Implementing Prompt Instructions

There isn't a prescribed format for these files, so I compiled several verified resources about async/await and had AI summarize them into a list of Do's and Don'ts.

### ✅ DOs

- **Always Await Your Tasks:**  
  Always use the `await` keyword on async operations to ensure exceptions are captured and to avoid blocking the calling thread.  

- **Use Async Task/Task<T> Methods:**  
  Prefer returning `Task` or `Task<T>` over `async void` so that exceptions can be observed, and your methods are easily composable and testable.  

- **Name Methods with the "Async" Suffix:**  
  Clearly differentiate asynchronous methods (e.g., `GetDataAsync()`) from synchronous ones.  

- **Pass Cancellation Tokens:**  
  Allow cancellation by accepting a `CancellationToken` in your async methods.  

- **Use ConfigureAwait(false) When Appropriate:**  
  In library code or server-side processes, use `ConfigureAwait(false)` to avoid unnecessary context switches and potential deadlocks.  

- **Keep Async Code “Async All the Way”:**  
  Propagate async all the way from the entry point (like event handlers or controller actions) rather than mixing sync and async code.  

- **Report Progress and Handle Exceptions Properly:**  
  Use tools like `IProgress<T>` to report progress and always catch exceptions at the appropriate level when awaiting tasks.  

---

### ❌ DON'Ts

- **Avoid async void Methods:**  
  Except for event handlers, never use `async void` because their exceptions are not observable and they’re difficult to test.  

- **Don’t Block on Async Code:**  
  Avoid using `.Wait()` or `.Result` as these can lead to deadlocks and wrap exceptions in `AggregateException`. If you must block, consider using `GetAwaiter().GetResult()`.  

- **Don’t Mix Blocking and Async Code:**  
  Blocking the calling thread in an otherwise async flow (e.g., by mixing synchronous calls with async ones) may cause deadlocks and performance issues.  

- **Avoid Wrapping Return Task in Try/Catch or Using Blocks:**  
  When a method returns a `Task`, wrapping it in a try/catch or using block may lead to unexpected behavior because the task completes outside those blocks.  

- **Don’t Overuse Fire-and-Forget Patterns:**  
  Unobserved tasks (fire-and-forget) can swallow exceptions and cause race conditions—if needed, use a “safe fire-and-forget” pattern with proper error handling.  
Enter fullscreen mode Exit fullscreen mode

Source

I can then, in the Copilot chat window, explicitly add this particular file or, better yet, simply use a keyword I’ve chosen and expect Copilot to include it. To setup keywords, I saw this pattern in another repository and it worked for me as well.

Set up a root prompt file in the workspace (named .github/prompts/prompts.prompt.md), and use the VS Code command "Chat: Use Prompt" to include this file in the chat session.

# Prompt Instructions

Include these prompt instructions if their link's name is used.

- [maui](dotnet/maui/maui.prompt.md)
- [async](dotnet/async.prompt.md)
Enter fullscreen mode Exit fullscreen mode

Now when I mention "async", I expect Copilot to include that file with the additional instructions and context.

To be even more granular I've been experimenting with nesting my keywords. For instance, if I mention "maui" and also "layout" I want to include the file maui-layouts.prompt.md. So for that purpose "maui" loads the maui.prompt.md which in turn lists the file maui-layouts.prompt.md for the keyword "layout".

I haven't found this to be 100% reliable, so some experimentation is warranted. For example, you'll notice in the screenshot above that ALL of my prompt files were not only seen initially, but read as a part of resolving my prompt. A few days ago that wasn't the case, and it does seem to differ depending on the AI model I choose.

Using all the files isn't ideal, especially as my repository grows. I've also tried prefixing my keywords with symbols, but that hasn't yet yielded the specificity I want. Nonetheless things are moving so quickly with GitHub Copilot and Visual Studio that I trust it will continue to improve, and I'm prepared to experiment and adapt along the way. It's a great ride!

Learn more about these prompt files in the GitHub documentation.

Contributions Welcome: Building a knowledge base of instructions

As I continue to uncover areas where AI models can benefit from additional instructions -- bringing the generated code closer to 100% accuracy -- I've begun adding more prompt files to a new repository.

To get started, clone the repository below and add or merge the .github folder into your workspace.

If you think this would be helpful for your workflow, please try it out and consider contributing.






AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

👋 Kindness is contagious

DEV shines when you're signed in, unlocking a customized experience with features like dark mode!

Okay