Using Prompting to Extract Requirements

La Lakshmi Priya Updated 06 Nov 2026
11 min read ·Lesson 98 of 100

What Is Requirements Extraction? Before building software, developers need to know what to build. That information usually arrives in an unstructured form: client emails, meeting notes, chat messages, call transcripts, or a short project brief. Requirements extraction is the process of turning this material into clear, structured, testable requirements.

Language models are well suited to the first draft of this work: finding requirement statements, organizing them, and writing acceptance criteria. They also bring a specific risk: they can fill gaps with plausible requirements that nobody asked for, such as performance targets, security rules, or features that "every app has". An invented requirement is worse than a missing one, because it looks agreed.

This lesson shows how to prompt for requirements that are traceable to their source, how to surface ambiguities and open questions instead of hiding them, and how to check the results in code.

Key Terms Term Meaning Example Functional requirement Something the system must do Students can pay in two installments Non-functional requirement A quality the system must have Pages load quickly on mobile User story A requirement from a user's perspective: "As a [user], I want [goal], so that [benefit]" As a student, I want to pay in installments, so that expensive courses are affordable Acceptance criteria Conditions that must be true for a requirement to be complete Given a course above ₹5,000, when I check out, then I see an installment option Assumption Something believed true but not confirmed Installments are only for individual students, not companies Open question Something that must be decided before building Should WhatsApp reminders be included? Traceability Linking each requirement to where it came from A quote from the client call notes Given/When/Then Acceptance criteria are often written in the Given/When/Then format:

Given a starting situation When an action happens Then an observable result follows This format makes each criterion testable: it describes something that can be checked, and it can be turned directly into automated tests (Lesson 94).

The Requirements Extraction Prompt Extract software requirements from the notes in .

Rules:

  • Include only requirements stated or clearly implied in the notes.
  • For each requirement, copy the exact sentence from the notes it comes from.
  • Do not add requirements that are common in similar projects but not mentioned.
  • Things that are uncertain ("maybe", "not decided", "we'll see") are open questions, not requirements.
  • Vague requirements (such as "fast" or "easy") must be listed with a question asking for a measurable target. Do not invent the target.

Return only JSON: { "requirements": [ {"id": "REQ-1", "type": "functional" or "non-functional", "statement": "a clear, single requirement", "source_quote": "exact sentence from the notes", "acceptance_criteria": ["Given ..., when ..., then ..."]} ], "open_questions": ["..."], "assumptions": ["..."] }

{notes} Why Each Rule Matters Rule Prevents "Only stated or clearly implied" Invented features "Copy the exact sentence" Untraceable requirements; makes verification possible "Not common in similar projects" Generic requirements such as "users can reset passwords" appearing uninvited "Uncertain items are open questions" Undecided ideas becoming commitments "Vague requirements get a question, not a target" Invented numbers such as "load in 2 seconds" A Worked Example The Notes Client call notes (Ravi, 20 Oct): Students should be able to pay in two installments for courses above 5000 rupees. The admin must see a weekly report of failed payments. Pages should load fast on mobile. Maybe we also need WhatsApp reminders, not decided yet. A Good Result { "requirements": [ {"id": "REQ-1", "type": "functional", "statement": "Students can pay for courses priced above ₹5,000 in two installments.", "source_quote": "Students should be able to pay in two installments for courses above 5000 rupees.", "acceptance_criteria": [ "Given a course priced above 5000 rupees, when a student checks out, then a two-installment option is shown.", "Given a course priced at 5000 rupees or less, when a student checks out, then no installment option is shown." ]}, {"id": "REQ-2", "type": "functional", "statement": "The admin can see a weekly report of failed payments.", "source_quote": "The admin must see a weekly report of failed payments.", "acceptance_criteria": [ "Given failed payments in the past week, when the weekly report is generated, then the admin sees each failed payment." ]}, {"id": "REQ-3", "type": "non-functional", "statement": "Pages load fast on mobile devices.", "source_quote": "Pages should load fast on mobile.", "acceptance_criteria": []} ], "open_questions": [ "What load time counts as 'fast' on mobile, and on what network speed?", "Should WhatsApp reminders be included in this project?", "For a course priced exactly 5000 rupees, are installments allowed?", "When is the second installment due, and what happens if it is not paid?" ], "assumptions": [ "Installments apply to individual student purchases." ] } What Makes This Result Good Every requirement has an exact source quote, so a reviewer can check it in seconds. REQ-1's second criterion tests the boundary: "above 5000" means 5000 itself does not qualify. An open question confirms this with the client, because "above" in casual speech is sometimes meant to include the boundary. REQ-3 has no acceptance criteria yet, because "fast" is not measurable. Instead of inventing a number, an open question asks for one. WhatsApp reminders are an open question, not a requirement, because the notes say "not decided yet". Open questions reveal missing decisions, such as when the second installment is due. These questions are often the most valuable part of the output: they would otherwise be discovered during development, when changes are expensive. Checking Extracted Requirements in Code Automated checks catch the most common extraction errors: invented quotes, duplicate IDs, and untestable criteria.

import re

GIVEN_WHEN_THEN = re.compile(r"^Given .+, when .+, then .+.$")

def normalize(text: str) -> str: return " ".join(text.split()).lower()

def check_requirements(requirements: list[dict], source: str) -> list[str]: issues, seen_ids = [], set() for req in requirements: if req["id"] in seen_ids: issues.append(f"{req['id']}: duplicate ID") seen_ids.add(req["id"]) if normalize(req["source_quote"]) not in normalize(source): issues.append(f"{req['id']}: source quote not found in the notes") if not req["acceptance_criteria"]: issues.append(f"{req['id']}: no acceptance criteria") for criterion in req["acceptance_criteria"]: if not GIVEN_WHEN_THEN.match(criterion): issues.append(f"{req['id']}: criterion not in Given/When/Then form: {criterion!r}") return issues

SOURCE = """Client call notes (Ravi, 20 Oct): Students should be able to pay in two installments for courses above 5000 rupees. The admin must see a weekly report of failed payments. Pages should load fast on mobile. Maybe we also need WhatsApp reminders, not decided yet."""

problematic = [ {"id": "REQ-1", "type": "functional", "statement": "Students can pay for courses above ₹5,000 in two installments.", "source_quote": "Students should be able to pay in two installments for courses above 5000 rupees.", "acceptance_criteria": ["Given a course priced above 5000 rupees, when a student checks out, " "then a two-installment option is shown."]}, {"id": "REQ-2", "type": "functional", "statement": "Admins receive a weekly failed-payments report.", "source_quote": "The admin must see a weekly report of failed payments.", "acceptance_criteria": ["Given failed payments in the past week, when the report runs, " "then the admin sees each failed payment."]}, {"id": "REQ-3", "type": "non-functional", "statement": "Pages load within 2 seconds on mobile.", "source_quote": "Pages should load within 2 seconds on mobile.", "acceptance_criteria": []}, {"id": "REQ-2", "type": "functional", "statement": "Send WhatsApp reminders.", "source_quote": "Maybe we also need WhatsApp reminders, not decided yet.", "acceptance_criteria": ["When reminders are due, send them."]}, ]

for issue in check_requirements(problematic, SOURCE): print(issue) Output:

REQ-3: source quote not found in the notes REQ-3: no acceptance criteria REQ-2: duplicate ID REQ-2: criterion not in Given/When/Then form: 'When reminders are due, send them.' Code Explanation normalize() collapses whitespace and lowercases text, so line breaks and capitalization do not cause false mismatches. Source quote check: REQ-3's quote says "within 2 seconds", but the notes only say "fast". The model invented a target and even altered the quote to support it. The check catches this immediately. Duplicate IDs: the second REQ-2 would cause confusion in tickets and tests. Criteria format: the regular expression requires "Given ..., when ..., then ...". The WhatsApp criterion lacks this structure and is too vague to test. Missing criteria are flagged so they become open questions or are completed. What Code Cannot Check The last item, WhatsApp reminders, also has a deeper problem: it was undecided in the notes but was turned into a requirement. Its source quote exists, so the quote check passes. Recognizing "maybe" and "not decided" as uncertainty requires reading, by the reviewer or by a verification prompt:

For each requirement in , check its source quote. If the quote expresses uncertainty (maybe, possibly, not decided, we'll see), report the requirement ID. Return only a JSON array of IDs. Additional Extraction Prompts Detecting Conflicts Requirements gathered from several people or meetings often contradict each other.

Compare the requirements in and the notes in . List pairs of statements that conflict or cannot both be true, with both source quotes and a question that would resolve the conflict. Example conflict: one note says "only admins can issue refunds", another says "mentors should refund students directly".

Generating User Stories Convert each functional requirement in into a user story: "As a , I want , so that ." Use only user types and benefits stated or clearly implied in the notes. If the benefit is not stated, write "so that [benefit to confirm]". Prioritizing With MoSCoW MoSCoW is a prioritization method that sorts requirements into Must have, Should have, Could have, and Won't have (this time).

Suggest a MoSCoW priority for each requirement in , based only on priority signals in the notes (words like "must", "important", "nice to have", deadlines). Where the notes give no signal, write "Priority to confirm". Prioritization is a business decision. The model's suggestions are a starting point for discussion with the client, not a final ranking.

A Practical Workflow

  1. Collect all source material: notes, emails, transcripts, briefs
  2. Extract requirements, open questions, and assumptions (main prompt)
  3. Check in code: quotes, IDs, criteria format
  4. Review uncertainty and conflicts (verification prompts)
  5. Send open questions to the client or product owner
  6. Update requirements with their answers
  7. Turn acceptance criteria into tests (Lesson 94) Steps 5 and 6 are where most of the value lies. The model's main contribution is to make gaps visible early, so that people can make decisions before development starts.

Common Mistakes Mistake 1: Accepting Invented Requirements What it is: Keeping requirements that sound sensible but were never requested.

Why it happens: They look professional and complete.

What it causes: Wasted development effort and features the client did not agree to.

How to fix it: Require exact source quotes and check them in code.

Mistake 2: Inventing Measurable Targets What it is: Turning "fast" into "under 2 seconds" without asking.

Why it happens: Testable requirements need numbers.

What it causes: Targets nobody agreed to, which may be too strict or too loose.

How to fix it: Turn vague requirements into open questions asking for targets.

Mistake 3: Treating Ideas as Decisions What it is: Including items marked "maybe" or "not decided" as requirements.

Why it happens: The model extracts everything that sounds like a feature.

What it causes: Scope creep and misunderstandings with clients.

How to fix it: Route uncertain items to open questions, and verify with a check prompt.

Mistake 4: Untestable Acceptance Criteria What it is: Criteria such as "the system works well".

Why it happens: The format was not specified.

What it causes: Disagreements about when a feature is done.

How to fix it: Require Given/When/Then format and check it in code.

Mistake 5: Skipping Human Confirmation What it is: Treating the extracted list as final.

Why it happens: It looks complete and organized.

What it causes: Building from misunderstood or incomplete requirements.

How to fix it: Review the list and send open questions to the people who decide.

Best Practices Require traceability. Every requirement needs an exact source quote.

Separate requirements, open questions, and assumptions. Uncertainty must stay visible.

Never invent targets. Ask for measurable values instead.

Write testable acceptance criteria. Given/When/Then, including boundaries.

Check structure in code and uncertainty with review. Quotes, IDs, formats, and hedging language.

Treat open questions as the most valuable output. Resolve them before building.

Try It Yourself Exercise 1: Extract and Check Write notes from a realistic client conversation for a small feature, such as course reviews or a referral program, including one vague requirement, one undecided idea, and one boundary such as "more than 3". Run the extraction prompt, then check_requirements(), and review the open questions.

Exercise 2: Find Conflicts Write two sets of notes from two stakeholders about the same feature, with two deliberate contradictions. Use the conflict detection prompt and check whether both contradictions are found and the suggested questions would resolve them.

Exercise 3: From Criteria to Tests Take the acceptance criteria for REQ-1 from the worked example and write pytest tests for a function installment_options(course_price) that returns the available payment options. Check that the boundary criterion (exactly ₹5,000) is tested.

0 Comments

Reviewed before they appear

No comments yet.

Prompt Engineering
Prompt Engineering Introduction How Large Language Models Respond to Prompts Prompting Basics Elements of an Effective Prompt Writing Clear Instructions for AI Models Adding Context to a Prompt Providing Input Data in Prompts Using Output Indicators and Response Formats Prompt Formatting: Questions, Instructions, and Templates General Tips for Designing Better Prompts Common Prompt Engineering Mistakes Iterative Prompt Design and Refinement Understanding Instruction, Context, Input, and Output How Specificity and Conciseness Affect Prompt Quality Breaking Large Tasks into Smaller Prompting Tasks Zero-Shot Prompting Zero-Shot Prompting Examples for Everyday Tasks Zero-Shot Text Classification Zero-Shot Question Answering Zero-Shot Summarization Zero-Shot Translation Zero-Shot Prompting for Information Extraction When to Use Zero-Shot Prompting Limitations of Zero-Shot Prompting Improving Weak Zero-Shot Prompts Few-Shot Prompting One-Shot Prompting vs Few-Shot Prompting Choosing Good Examples for Few-Shot Prompts Formatting Examples in Few-Shot Prompts Few-Shot Classification with Examples Few-Shot Prompting for Structured Output Few-Shot Prompting Zero-Shot vs Few-Shot Prompting Role Prompting and Persona Instructions Instruction-Based Prompting Task-Oriented Prompt Templates Using Delimiters to Separate Prompt Sections Prompt Templates with Variables Chain-of-Thought Prompting Zero-Shot Chain-of-Thought Prompting Few-Shot Chain-of-Thought Prompting Automatic Chain-of-Thought (Auto-CoT) When Chain-of-Thought Prompting Helps Limitations of Chain-of-Thought Prompting Self-Consistency Prompting Comparing Chain-of-Thought and Self-Consistency Tree of Thoughts (ToT) Prompting Exploring Multiple Solutions with Tree of Thoughts Least-to-Most Prompting Complexity-Based Prompting Maieutic Prompting Self-Consistency: Sampling Multiple Reasoning Paths Self-Consistency for Arithmetic and Logic Tasks Tree of Thoughts: Search, Evaluation, and Backtracking Meta Prompting Generate Knowledge Prompting Directional Stimulus Prompting Program-Aided Language Models (PAL) React: Reasoning and Acting with Language Models Reflexion: Improving Agents Through Feedback Prompt Chaining Designing Multi-Step Prompt Chains Decomposing Complex Tasks into Prompt Chains Automatic Prompt Engineer (APE) Active-Prompt: Selecting Useful Reasoning Examples Optimizing Prompts Systematically Prompt Iteration and Versioning Building Reusable Prompt Libraries Testing Prompt Variants Prompt Chaining Fundamentals Passing Outputs Between Prompt Steps Prompt Chains for Summarization and Extraction Validating Intermediate Results in a Prompt Chain Debugging a Multi-Step Prompt Workflow Graph Prompting Multimodal Chain-of-Thought Prompting Automatic Reasoning and Tool-Use (ART) Prompting for Tool Selection and Use Combining Prompting Techniques for Complex Tasks Prompts for Text Summarization Prompts for Information Extraction Prompts for Text Classification Prompts for Question Answering Prompts for Sentiment Analysis Prompts for Rewriting and Editing Prompts for Translation and Localization Prompts for Brainstorming and Creative Writing Prompts for Generating Structured Data Prompts for Explaining Technical Concepts Prompts for Generating and Reviewing Code Prompting for Code Generation Prompting for Code Explanation Prompting for Debugging and Error Analysis Prompting for Unit Test Generation Prompting for SQL Query Generation Prompting for API Documentation Prompting for Technical Documentation Using Prompting to Extract Requirements Creating JSON-Style Structured Responses with Prompts Designing Prompts for Repeatable Developer Workflows
Ask about this post
AI Ask about this post

Ask questions about Using Prompting to Extract Requirements and get answers drawn from it.

Signed-in readers only.