Course page: Lecture 2 of the 2026 Generative Software Engineering course at Nanjing University: prompt engineering

1. A prompt is more than the sentence in the chat box
A prompt is most easily understood as the user's input in a chat box: asking AI to write a piece of code, generate an image, or complete a game prototype. In an agent system, what the model actually sees is a whole stretch of context that keeps growing.
Context usually begins with the system prompt, passes through the operating rules injected by the agent harness, then layers on project instructions, tool definitions, environment information, and earlier tool calls with their results, and only then reaches the user's current task. Every token the model emits can send more content into this linear sequence, where it becomes material for later reasoning.
The context of an agent can be broken into several kinds of object:
| Context component | Role |
|---|---|
| System prompt | Sets basic behavior, language, permissions, and refusal boundaries |
| Agent harness | Provides the run loop, message organization, and the execution environment |
| Project-level instructions | Describe the codebase's structure, constraints, ways of working, and acceptance criteria |
| Skill description and body | Tell the model which reusable capabilities exist and how to use one once a task matches |
| Tool definitions | Describe the parameters and limits of bash, the browser, an editor, or other tools |
| Environment and history | Provide the current model, time, working directory, session history, and tool results |
| User task | Specify the goal to complete this time |
So AGENTS.md, a Skill, a tool's return value, and a project file can all be part of the prompt. A Skill often exposes only its name and a short description first, with the full content loaded on demand once the task matches; the result of a tool call also goes back into the context and shapes what happens next. A request that looks as simple as "help me change a file" can arrive with a whole set of rules and state behind it.
This is where an agent's power comes from: it sees the task, the environment, the rules, and the feedback it just received at the same time. It also means every item in the context changes what the model produces next. Prompt engineering, then, is about arranging that whole sequence.
2. Context engineering starts as an observation skill
Since a model can see its own context, you can simply have the agent inspect what information is in the current context, which files are loaded, how the tools are defined, and what earlier actions produced. The process resembles making a program print its own runtime state: you will not get all of its internals, but you often find rules and limits you had not noticed before.
That the model can read something does not make it unconditionally trustworthy. Some systems explicitly forbid the model to repeat the system prompt; a tool's safety evaluation may also combine static rules, an allowlist, network permission, and another model. Whether a command runs directly or needs confirmation can involve several layers of judgment at once.
The class used an agent running a bash command as the example. Low-risk commands, operations inside a sandbox, and requests that hit the network allowlist can take different paths; a command that cannot be judged statically may get a short "please assess the safety" text injected into the model's context, asking the model to give a risk rating first. That rating is itself no more than evidence, and does not automatically amount to fact.
A more reliable way to analyze this is to read the relevant implementation, change one specific prompt or rule, and watch whether behavior changes as expected. A behavior change helps locate cause and effect, and still counts as evidence that needs cross-checking. Context engineering therefore covers both writing the rules and observing how they take effect in a real run.
3. Learning in the AI era: ask clearly first, then turn around and play teacher
Context engineering applies beyond programming. Asking a person about something you do not understand can expose your own gaps, and it costs them time; AI will patiently take repeated follow-up questions. An effective learning loop can start with "please explain this concept clearly", then reverse the roles: the learner does the explaining, and the AI plays a student who knows nothing, asking questions and correcting only when there is a logical error, an omission, or a skipped step.
This turns understanding from "I think I followed that" into an expression that can be tested. The learner has to reorganize the concept into a continuous explanation, while the AI keeps asking about premises, counterexamples, and the derivation. The person's knowledge and phrasing then enter the context and become the basis for later collaboration.
Action also gets cheaper: any small snag can be tried immediately, any gap in understanding followed up on the spot, anything uncertain tested with a small experiment right away. AI does not take over responsibility for understanding, but it lowers the threshold for starting to learn, to verify, and to explore.
4. From prompt engineering to context engineering: closing the gaps between the three spaces
The three spaces common in software engineering still hold in agent tasks:
| Space | The question it answers | Example |
|---|---|---|
| Intention | What problem you want to solve | Build a product like a certain game, improve a workflow |
| Specification | What result counts as meeting the requirement | Features, tech stack, data format, style, constraints, and acceptance criteria |
| Implementation | How to land it concretely | Code, assets, scripts, deployment environment, and run results |
A vague Intention leaves the model a large solution space. Say only "build a game like a certain title", and the model may well deliver a runnable game without knowing whether you want a real map, specific art assets, a particular feel in the interaction, or just a demo prototype. It completes the version it understood, which may differ from the one in the requester's head.
Write down the implementation language, the source of dependencies, the scope of the scene, the visual style, and what counts as correct, and the model can more easily move along the same Specification. Even when it produces a wrong result, people and the model can locate the deviation faster: the wrong tech stack, a missing feature, assets that violate their license, or tests that did not pass.
None of this means prompts should grow without limit. Instructions in the context compete for attention, and too much background, explanation, and specification can contaminate the task. The better approach is to write the most important constraints as concise, stable, checkable requirements, and keep them visible at the points where the model has to make a decision.
5. Why models can follow complex instructions
A large language model can be approximated as a system that predicts the next token from context. Each prediction has a limited compute budget; even a model with a huge number of parameters activates only some of them per inference. Limited compute in a single pass does not mean the system can only accomplish limited things, because the model can write what it has already generated back into the context and keep working on a longer sequence.
The difference between a finite-state machine and a Turing machine helps here: a finite-state machine has finitely many states; add a tape it can keep reading and writing, and the system gains stronger memory and computing power. Human thinking works much the same way, with limited attention in one sitting, while paper, notes, and existing knowledge connect many rounds of thought.
Chain of thought models treat the context as a kind of paper and pencil. On a simple question they can answer directly; on a hard one they write intermediate steps, try a solution, check whether it holds, and go back to re-derive when needed. This workspace has one clear limit: generation is largely append-only, so the model cannot truly erase an error from the page the way a person can, only pay less attention to it in later steps and correct again.
What this intermediate reasoning buys is more compute spent on a single answer. The model does not have to guess the answer at the first token; it can generate candidates, find contradictions, adjust its path, and close in on the goal through later tokens. That is also why a model can sometimes satisfy a complex textual constraint it may never have seen in training: as long as the constraint can be checked item by item, the model can keep trying and correcting.
The class combined rhyme, an acrostic, specific character forms, and a fixed line count into a very unnatural writing task, then watched how the model picked an approach first and checked the rhymes, the character counts, and the positions item by item. What the example shows is verifiable requirements keeping a model on course in an unfamiliar task. It says nothing about stable taste. People still have the advantage on goals that resist formalization, such as spatial structure, taste, and emotional pacing.
6. A verifier is stronger than "you are an expert"
On early models, prompts found online often repeated "you are an expert" and "you must think carefully". Wording like that can sometimes steer the model's attention toward a role; it does not state what counts as done, and it gives no clear feedback on errors.
An explicit Verifier in the context changes the picture. For example:
- A test script that returns pass or fail explicitly;
- Output that must use a specified language, format, and data structure;
- A page that must have a white background and no semi-transparent effects;
- A screenshot after every completed screen, checked with a vision model;
- Research experiments that must be compared against real tools and existing algorithms, with timeout paths recorded.
Requirements like these turn "success" into an observable signal. Once training has taught the model to value such signals, it keeps adjusting the implementation until it believes the verifier will pass. The stronger the model, the more a verifier can do: explicit tests let an agent retry tirelessly, and even go looking for tools, references, and new routes to a solution.
Passing the verifier is not the same as solving the real problem. If the verifier is chosen wrongly, the model optimizes the wrong target very earnestly. One research project wrote "prove that a certain method is useful" as a local requirement, and the model built many small benchmarks, running them repeatedly around local positive and negative results, while ignoring the object the research question actually needed to answer. It became a reward hacker: it collected local reward without advancing the overall goal.
Correcting that direction means putting the wider research background, the existing work, the real tools, and the meaning of the evaluation back into the context. A timeout or failure with real value can reveal which program structures make the current algorithm hard to explore, while a pretty result on a toy benchmark may have nothing to do with the problem.
7. Literal compliance and human intent are two different things
A model can follow literal requirements such as "white background", "no frosted glass", and "check with screenshots" to the letter, and still produce a page full of AI flavor. It may lay out all the text too neatly, use the same gradients and cards, and apply the most common modern style it has seen. The instructions were followed; the human aesthetic goal was not really understood.
This is a trade-off in context engineering: more rules suppress some bad outcomes and add context noise that competes for attention with other requirements. An overlong Skill or project instruction can drag an originally simple task into a maintenance swamp. A generic Skill found online may work the first time and reveal its assumptions and limits after repeated use.
So when a model keeps drifting, piling on more prompt text will not fix it. You can go back to the model's attention and reasoning, see what it was looking at and what it ignored at each stage, and then write a shorter requirement closer to the real acceptance criteria. A mature model usually does not need much role-play; putting the Verifier that actually matters into the context is more reliable than describing a fictional expert.
Human taste needs deliberate training as well. Looking at good web pages, résumés, products, and designs left from before the AI era, and understanding why they feel comfortable and why they differ, is what lets you translate "no AI flavor" into specific requirements for structure, material, typography, and interaction. Without that experience, the model can only converge on the most common styles in its training data.
8. When reading a paper, put AI on your side first
Dropping a tightly argued paper into the context and asking for "a summary" is the most common use, and the one most prone to bias. The argument chain in a paper is carefully organized by its author: A therefore B, B therefore C. The model's attention readily follows that chain and accepts the author's premises, and the summary it produces mostly repeats the story the author wanted to tell.
When the reader then says "this paper may be unreliable", the model may immediately switch to match the reader's attitude. It swings between "good paper" and "bad paper", focuses on experimental details that are easy to state but unimportant, and never really judges the work's intellectual value. That kind of agreement is not independent review.
A better context should do the grounding first, aligning the AI and the reader to the same knowledge position:
- State what related problems humanity already knows about, and how far existing methods have gotten;
- Identify the related work, the applicable boundary, and the genuinely new part of this work;
- Put the reader's own knowledge level, existing concepts, and questions into the context;
- Require the model to advance one step on the basis of those shared facts only, and check whether that step is sound.
For example, a reader who does not yet understand linking and loading can start from the existing concept of how a program turns from source files into an executable, then ask why that process cannot be done in one step. The model then explains the new concept from ground the reader already holds, at the reader's own pace through the paper's narrative.
The method applies to reviewing as well. A review checks whether the paper's internal logic closes, and also judges from the frontier of human knowledge: whether the problem is worth solving, whether the contribution is genuinely new, whether the result changes what we know about something. If every article is written by AI and every article is reviewed by an AI that checks only internal logic, papers may look more and more like complete-looking AI slop that fewer and fewer people actually read.
Learning can be seen as steadily expanding your network of facts and concepts. When you read a good paper, a book, or an article from another field, remembering the new conclusions is only part of it: you also ask why you did not know this before, which prerequisite facts were missing, and which old knowledge now needs rewiring. AI speeds up the expansion of that network considerably, but it cannot decide for you which connections have long-term value.
9. Short-range tasks and long-horizon open tasks
Tasks with a clear Verifier usually suit long agent runs. A test script that returns success or failure clearly lets the model modify, rerun, and modify again, pushing the implementation toward an acceptable state. Code compilation, format checks, pixel comparison, and a fixed set of inputs and outputs are all feedback of this kind.
A real long horizon task is different. It starts from an initial state that is not fully clear, its goal, Specification, and Implementation may all change during exploration, and it still has to deliver a high-quality result at the end. Generating a small game or a personal homepage in one shot is rarely hard; adding features, fixing old ones, and keeping the architecture maintainable can make the cost climb sharply at some point.
The difference between P and NP offers a loose analogy: verifying that a given solution satisfies the conditions is often easier than finding the best solution in a huge space. An agent is trained as a system that completes tasks, so when asked for "a plan", it tends to hand over a limited, self-consistent, deliverable plan as fast as it can, and will not necessarily take on the cost of exhaustive search and long comparison.
An open problem cannot be handled by repeating the same prompt. A more workable direction is to split the large search space into many parts that can be checked separately, then trade more compute for more thorough exploration:
- In research, run a systematic literature review before asking the model for a seemingly novel conclusion;
- Generate many candidates, then screen them one by one, breaking the overall choice into several explicit judgments;
- Use several agents to check different candidates, different hypotheses, and different evidence;
- Have every round of output leave behind comparable reasons, facts, and failure records.
An open task such as naming can generate candidate pronunciations, screen out the ones you dislike, and then have different agents check the meaning of the characters, their provenance, and how the combination reads. Once the search space is cut apart, more compute can turn into better choices rather than a faster average answer.
This raises a larger social question: if long-term exploration with real value can reliably trade compute for intelligence, a small group with unlimited compute may open an ever wider capability gap against everyone else. Those inside the wall keep producing new knowledge and plans, while those outside cannot keep up with the rate at which intelligence is produced. That risk has not been solved, and it deserves serious discussion before AI capabilities expand further.
10. Why large, high-quality code suits AI
An agent is usually quick at a small Proof of Concept, but once the code enters maintenance, feature after feature can send the old structure drifting out of control. A simple project's context lacks explicit patterns, leaving the model to guess and patch.
Large, complex systems maintained by people over years can show the opposite. The code of the Linux kernel or a compiler is hard for a person to understand: a function may pass through many layers of calls, and the lock ordering, the choice of helpers, and the conventions between subsystems are not easy to grasp intuitively. For a model, the mass of similar implementations, naming regularities, and recurring design patterns becomes material its attention can match against.
When a model needs to add a feature inside a mature subsystem, it can find similar cases across many files, see how the existing code locks, calls helpers, and handles boundaries, and then combine those local patterns. The long-term structure of high-quality code gives the model a stronger context than generating from a blank page.
One possible research direction is to extract transferable design experience from good software projects, write it up as a concise document like a set of software design principles, and give it to the model together with the specific requirement. Stuffing a whole large project into the context is not ideal, because the designs of different projects conflict: messages can pass through loose coupling, or all go through a single Gateway. Both architectures can be reasonable, and neither can serve as the sole principle of the same system at the same time.
A more promising approach is to supply design slices from several similar projects and let the AI converge, through rounds of comparison and verification, on a structure that fits the current Specification. That direction still needs experiments; putting good code into the context is no guarantee of a good design.
11. Human time should go where the payoff is highest
Context engineering does not make the fundamentals obsolete. Processors, operating systems, compilers, databases, and software design hold a large body of concepts and experience; without any understanding of those objects, you cannot ask the right questions, and you cannot tell which direction the model is drifting in.
What changes is the division of labor in learning and work. For work you already know how to do with results that are easy to accept, let the agent run it. For work that is unfamiliar, expensive to get wrong, or decisive for a research direction, people should spend their time on understanding the problem, injecting domain knowledge, choosing verification criteria, and correcting course in time.
Watching an agent continuously and correcting every drift brings the psychological reward of feeling more useful than the model, and it is not necessarily the highest-yield way to work. Going fully automatic and checking only the final result on return misses the chance to spot structural problems. An effective division keeps human attention for the decisions with the highest payoff and hands execution that is already clear and verifiable to the model.
Instruction-following in a long context also depends on position and content. A model may gradually forget early requirements and still follow the specific task in the last short window quite well. Long-running tasks therefore need continuous context maintenance, with key constraints and verification criteria placed where the model actually needs them, which is rarely only at the very beginning.
12. The conclusions left by the second lecture
Prompt engineering is a matter of understanding what the model sees, what it attends to, what it verifies, and which parts of the context are leading it in the wrong direction. A good agent context answers at least four questions:
- What is the real intention of the current task;
- Which Specifications can shrink the solution space and reduce drift;
- What Verifier can judge whether a result meets the requirement;
- Which facts, experience, and failure records can help the model keep correcting.
For short-range tasks, an explicit verifier turns an agent into an untiring executor. For paper reading and long-term research, aligning AI with the person's knowledge, questions, and value judgments first reduces the risk of contamination by the existing narrative. For software maintenance, a good context includes the task and also the design patterns and long-term constraints of a mature system.
Models will keep getting stronger, and specific prompting tricks will keep going out of date. As long as agents still predict actions from context, generative software engineering will still need people to organize intention, choose structure, build verification loops, and decide when to trust a result and when to stop a bad direction.
