Season two of GitHub for Beginners continues with a focus on large language models and the craft of prompt engineering. Building on earlier explorations of GitHub Copilot's capabilities, this installment examines how to interact with LLMs more effectively and extract the outputs you need.

The quality of your interaction with an LLM depends heavily on how you frame your requests. Vague or poorly structured prompts often lead to unsatisfactory results, while thoughtfully constructed ones can dramatically enhance productivity. This guide covers three core areas: how LLMs function and process prompts, techniques for engineering high-quality prompts, and methods for diagnosing and fixing prompts that miss the mark.

https://www.youtube.com/embed/LAF-lACf2QY?version=3&rel=1&showsearch=0&showinfo=1&iv_load_policy=1&fs=1&hl=en-US&autohide=2&wmode=transparent

Understanding Large Language Models

Large language models represent a category of artificial intelligence trained on vast quantities of text data to comprehend and produce language that resembles human communication. These systems operate by forecasting the subsequent word in a sequence based on preceding words, enabling responses that feel natural and appropriate—functioning much like an exceptionally sophisticated version of autocomplete.

Three foundational concepts shape how LLMs operate:

  • Context: The surrounding information that enables an LLM to grasp your meaning. Similar to human conversation, richer context produces more coherent exchanges.
  • Tokens: The units into which text is divided for processing—ranging from complete words to fragments or individual characters. The quantity of tokens influences response generation, with insufficient tokens creating information gaps and excessive tokens potentially exceeding model capacity or hitting built-in restrictions.
  • Limitations: While capable, LLMs operate through pattern recognition and statistical inference from training data rather than true language comprehension. Models can produce hallucinations, inaccurate information, or incoherent output, and their performance depends on the diversity and breadth of their training datasets.
This image shows the process of using an LLM: entering prompt text, LLM analysis, and then receiving a response.

What Constitutes a Prompt

A prompt is a natural language instruction that directs an LLM to execute a particular task. It supplies the model with context through tokens and accommodates the model's inherent constraints, enabling it to generate a suitable response. For instance, requesting "Write a JavaScript function to calculate the factorial of a number" instructs the model to draw on its training data and produce functional code.

This image shows a visual example of what it’s like to gain context within a text message thread between two friends, and then a flow chart showing how the conversation went from no context at all to achieving full context.

The behavior of LLMs varies based on their training methodology. Different models—such as OpenAI's GPT, Anthropic's Claude, and Google's Gemini—may interpret identical prompts differently and produce distinct outputs. Even a single model exhibits nondeterministic behavior, meaning the same prompt submitted three times can yield three separate results.

This image is a visual representation of how a rare word like “Supercalifragilisticexpialidocious” would be broken down into six smaller, more common tokens, or subword pieces.
This image depicts how common sense reasoning plays into prompting LLMs. It explores a prompt, shares how humans and LLMs would each understand the prompt, and shares a potential hallucination.

The Art and Science of Prompt Engineering

Providing clear instructions to an LLM mirrors the process of directing a colleague through a task. When specific outcomes are desired, precision in your instructions becomes essential. This practice of deliberately constructing prompts to achieve desired results is prompt engineering, and when executed skillfully, it substantially elevates the caliber and pertinence of LLM outputs.

This image shares four steps in which an LLM might process your prompt. The four steps are: input prompt, tokenization, processing, and response generation.

Effective prompts share several characteristics:

  • Clarity and specificity prevent ambiguity that could mislead the model
  • Sufficient context without excessive detail ensures the model grasps your intent without becoming overwhelmed
  • Willingness to refine and iterate when initial results disappoint

Refining Prompts Through Iteration

Consider a scenario where you ask GitHub Copilot: "Write a function that will square numbers in a list in a new file with no prior code to offer Copilot context." While seemingly straightforward, this request leaves critical details unspecified:

  • Which programming language should be used?
  • Should negative numbers be included?
  • Could the input contain non-numeric values?
  • Should the original list be modified or should a new list be returned?

A refined version reads: "Write a Python function that takes a list of integers and returns a new list where each number is squared, excluding any negative numbers." This revision explicitly specifies the language, function behavior, constraints, and input type. By furnishing GitHub Copilot with greater specificity, the generated output aligns more closely with your intentions.

Like programming itself, prompt engineering hinges on effective communication. Thoughtful prompt construction enables tools like GitHub Copilot to streamline workflows and boost efficiency. However, working with LLMs occasionally requires troubleshooting when results diverge from expectations.

Addressing Common Prompting Challenges

As you gain experience with GitHub Copilot and comparable LLM tools, you may encounter situations where outputs miss the mark. Frequently, the culprit is insufficient specificity in the initial prompt. Several recurring scenarios warrant attention:

This image consists of white text on a black background sharing that prompt engineering is the same thing as being a good communicator.

Prompt Confusion

Combining multiple requests or expressing them unclearly can perplex the model. Suppose you highlight code in Visual Studio Code and instruct Copilot to "fix the errors in this code and optimize it." The model faces ambiguity: should it prioritize error correction or optimization? And what optimization target matters most—speed, memory consumption, or code clarity?

Resolution requires decomposing your request into explicit, sequential steps with supporting context. Revise the prompt to: "First, fix the errors in the code snippet. Then, optimize the fixed code for better performance." Breaking requests into discrete components increases the likelihood of obtaining desired results because the model's required actions become unambiguous.

Token Limitations

This image depicts how to overcome prompt confusion, or mixing multiple requests or unclear instructions. First, you’d fix errors, then optimize code, and finally add tests.

Models operate within token capacity constraints, which vary across different models and the different versions available with GitHub Copilot. Excessively lengthy prompts or requests for extensive output may cause the LLM to hallucinate, deliver incomplete responses, or fail entirely.

The solution involves maintaining conciseness. While iterative refinement of smaller prompt sections proves valuable, supplying only essential context is equally critical. Does the model truly require an entire code file to deliver your desired result, or would a specific function's few lines suffice? Rather than requesting a complete application, can you request individual components sequentially?

This image depicts how to overcome token limitations, since LLMs have a maximum token limit for input and output. You would need to break down large inputs into smaller chunks.

Assumption Errors

It's tempting to overestimate an LLM's knowledge. A request like "add authentication to my app" assumes the model understands your application's purpose and preferred authentication technologies—assumptions that may not hold.

Crafting such prompts demands explicit requirement specification. Detail your particular needs, reference relevant best practices, and iterate by introducing edge cases and constraints. By articulating requirements clearly, you help ensure the LLM addresses all critical facets of your request.

This image depicts how to overcome assumption errors, or when you assume LLM has context it doesn’t have. You’d need to explicitly state requirements, outline specific needs, mention best practices if needed, and then iterate with edge cases and restraints.

Best Practices for Prompt Engineering

Mastering prompt engineering requires practice, but improvement comes with experience. Keep these principles in mind when working with GitHub Copilot or other LLMs:

  • Supply sufficient context while respecting the model's inherent limitations
  • Ensure prompts are clear, concise, and precise for optimal results
  • When multiple tasks are needed, segment prompts into smaller pieces and build from there
  • Be explicit about requirements and constraints so the model accurately interprets your intent

Moving Forward

This exploration of prompt engineering covered substantial ground: the mechanics of LLMs and the role of context, the definition and construction of effective prompts, and strategies for avoiding common pitfalls with large language models.

  • A YouTube tutorial demonstrates these concepts in practice
  • Questions can be posted in the GitHub Community thread for responses
  • GitHub Copilot is available to sign up for at no cost
  • The next installment in the series will address security best practices

Source: GitHub Blog