
In recent years, artificial intelligence has transformed the way developers interact with code and automate various tasks. Tools such as GitHub Copilot and Google’s Gemini have made it easier to generate code, debug issues, and even assist with documentation. However, the effectiveness of these tools depends greatly on how well prompts are crafted. This process, known as prompt engineering, is the art of designing inputs that guide AI to deliver accurate and relevant outputs.
While this blog will focus on Ruby on Rails (RoR) as an example language, the principles of prompt engineering can be applied to any programming language or AI-assisted task.
What is Prompt Engineering?
Prompt engineering refers to the practice of creating clear, detailed, and context-aware prompts that enable AI models to generate the most appropriate and useful responses. In the context of coding, this means asking AI to generate code, write documentation, or suggest improvements in a way that aligns with your project’s goals. A well-crafted prompt will help the AI produce more relevant, accurate, and efficient outputs. On the other hand, vague or poorly structured prompts can lead to results that require significant revisions.
Why Does Prompt Engineering Matter?
AI tools like GitHub Copilot and Gemini are incredibly powerful, but their responses are only as good as the prompts they are given. A well-designed prompt allows AI to leverage its full potential by understanding the task more clearly and narrowing the scope of the desired output. Without prompt engineering, developers might find themselves receiving responses that are not quite right, requiring additional manual work.
By mastering prompt engineering, the following benefits can be realised:
- Faster and more accurate results.
- Reduced time spent debugging or editing outputs.
- Improved productivity, as repetitive tasks can be automated more effectively.
- Greater control over the generated output.
The Impact of Good and Bad Prompts
To demonstrate the impact of prompt engineering, consider the example of generating a controller for managing users in a Ruby on Rails project. This task is straightforward but illustrates how different prompts can lead to vastly different results.
Bad Prompt:
Write a controller for managing users in a Ruby on Rails application.
This prompt is vague and lacks any context. The AI might generate a generic controller, but it could miss key details such as specific routes, input validation, or even a fully fleshed-out response structure.
Possible AI Output (Bad Prompt):
class UsersController < ApplicationController
def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
end
While this code works, it’s basic and lacks important functionality, such as handling errors, authentication, or strong parameters for user input.
Good Prompt:
Write a Ruby on Rails controller for managing users. Include actions for index, show, create, update, and destroy. Use strong parameters for input validation, and implement error handling for failed create or update actions.
This prompt is specific, includes key details like strong parameters and error handling, and provides context for what should be included in the controller.
Improved AI Output (Good Prompt):
class UsersController < ApplicationController
before_action :set_user, only: %i[show update destroy]
# GET /users
def index
@users = User.all
render json: @users
end
# GET /users/:id
def show
render json: @user
end
# POST /users
def create
@user = User.new(user_params)
if @user.save
render json: @user, status: :created
else
render json: @user.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /users/:id
def update
if @user.update(user_params)
render json: @user
else
render json: @user.errors, status: :unprocessable_entity
end
end
# DELETE /users/:id
def destroy
@user.destroy
end
private
def set_user
@user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:name, :email, :password)
end
end
This code includes all the necessary actions for managing users, uses strong parameters for security, and handles errors appropriately. The AI was able to generate a more complete and secure controller due to the clarity of the prompt.
How to Craft Effective Prompts
Creating effective prompts is key to getting the best results from AI tools. Here are some best practices for prompt engineering that will help guide the AI toward producing the most relevant and precise output:
- Be Specific: The more specific the prompt, the better the AI can understand what’s needed. For example, instead of asking for “a controller,” specify the actions you need (index, show, create, etc.), the language, and any security or validation concerns.
- Provide Context: Context helps AI understand the task in a broader sense. If you’re working with a particular Ruby on Rails version or using specific gems, mention them. Context can help the AI generate more appropriate and contextually accurate code.
- Ask for Examples or Details: If you’re unsure about how to phrase your request, ask the AI for examples. For instance, you could request that the AI generate code with comments, specific formats, or inline documentation.
- Refine and Iterate: If the first output isn’t quite right, adjust the prompt to make it clearer or more detailed. AI tools often improve with iteration.
- Clarify the Desired Output: Whether you need code, documentation, or test cases, specify the exact format and structure you expect from the AI. For instance, if you want unit tests generated alongside a method, mention that explicitly in your prompt.
AI Hallucinations: A Challenge in Prompt Engineering
One of the challenges developers face when working with AI tools is AI hallucinations. This term refers to situations where the AI generates responses that are factually incorrect, nonsensical, or completely made up. Hallucinations are often the result of vague or poorly defined prompts but can also occur due to the AI’s limitations in understanding context or drawing on accurate data.
For example, in Ruby on Rails, if a prompt is too vague, the AI might hallucinate by generating code that doesn’t fit well with the rest of your project or is outright incorrect. This can lead to issues where the generated code doesn’t work as expected or introduces bugs.
Example of AI Hallucination:
Bad Prompt:
Create a Ruby on Rails model that implements user authentication.
Possible AI Output (Hallucination):
class UserAuthentication < ApplicationRecord
has_secure_password
validates :email, presence: true, format: { with: /\A[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\z/ }
end
While the generated code seems reasonable at first glance, it misses essential parts of authentication logic, such as password hashing, and might confuse the developer into believing that this is a complete solution. The AI has “hallucinated” a solution that seems plausible but isn’t fully correct.
Avoiding Hallucinations:
Good Prompt:
Create a Ruby on Rails model for user authentication using bcrypt to hash passwords. Include email validation, password strength checks, and proper error handling.
Improved AI Output (No Hallucination):
class User < ApplicationRecord
has_secure_password
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
validates :password, length: { minimum: 6 }
has_many :sessions
end
In this example, the AI generates a more complete and correct solution by using clear and specific prompts. It ensures the model includes password hashing, email validation, and even a check for minimum password length.
Conclusion
Effective prompt engineering plays a critical role in getting the most out of AI tools like GitHub Copilot and Google’s Gemini. By crafting clear, specific, and contextually rich prompts, developers can ensure that the AI generates relevant, accurate, and efficient outputs. In the world of Ruby on Rails development, this means generating controllers, models, and other components with better practices, security, and readability.
However, developers should also be aware of the potential for AI hallucinations — incorrect or nonsensical responses generated by the AI. These can be minimised by carefully structuring prompts and ensuring that the AI has all the necessary context to generate accurate code.
Mastering prompt engineering can save time, reduce errors, and improve productivity, ultimately making it a valuable skill for anyone working with AI-powered development tools. By understanding the nuances of how AI interprets your requests, more precise and powerful results can be achieved, leading to more successful projects and streamlined development workflows.
References:
- https://dev.to/github/a-beginners-guide-to-prompt-engineering-with-github-copilot-3ibp?utm_source=chatgpt.com
- https://docs.github.com/en/copilot/using-github-copilot/copilot-chat/prompt-engineering-for-copilot-chat?utm_source=chatgpt.com
- https://cloud.google.com/gemini/docs/discover/write-prompts
Stay tuned for the next blog from us – https://engineering.rently.com/