Best Approach When User Request Is Vague or Underspecified: 4 Principles from the Andrej Karpathy Guidelines
The best approach when facing a vague or underspecified user request is to pause, explicitly surface hidden assumptions, ask targeted clarifying questions, and define concrete testable success criteria before writing any implementation code.
Handling ambiguous requirements is one of the most common failure points in AI-assisted software development. The forrestchang/andrej-karpathy-skills repository provides a systematic framework for transforming vague requests into clear, maintainable solutions through four tightly-coupled principles that guide every interaction.
The Four Principles for Handling Ambiguity
The repository structures its approach to vague requests around four core tenets documented in README.md and CLAUDE.md. These principles prevent silent misinterpretation and ensure the assistant never guesses or over-engineers.
Think Before Coding
Think Before Coding requires explicitly surfacing hidden assumptions, presenting multiple valid interpretations, and asking clarifying questions before generating code. According to the source guidelines in [README.md lines 28-38](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/README.md#L28-L38), this prevents the model from silently choosing a single meaning—such as assuming all user fields are exportable—and forces the conversation to clarify scope, format, and edge cases.
The EXAMPLES.md file demonstrates this in the Hidden Assumptions example (lines 11-55), where a vague request like "Add a feature to export user data" triggers a list of unknowns including output format, data scope, field selection, and delivery method before any code is proposed.
Goal-Driven Execution
Goal-Driven Execution turns ambiguous requests into concrete, testable goals and iterates until they are verified. As implemented in [README.md lines 71-82](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/README.md#L71-L82), this principle transforms a vague directive like "Fix the authentication system" into a checklist of test-first steps, ensuring the assistant knows exactly when the job is done.
Surgical Changes
Surgical Changes mandates limiting edits to only the lines that address the clarified need. The guidelines in [README.md lines 53-66](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/README.md#L53-L66) emphasize that once assumptions are cleared, the assistant must modify just the relevant code, avoiding accidental refactoring or unrelated modifications that introduce regressions.
Simplicity First
Simplicity First dictates implementing the minimal solution that satisfies the clarified request. Documented in [README.md lines 40-51](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/README.md#L40-L51), this principle avoids over-engineering—such as building a full strategy pattern for a single discount calculation—until the problem truly demands increased complexity.
Step-by-Step Workflow for Vague Requests
The repository prescribes a specific six-step loop for handling underspecified requests, illustrated in the Multiple Interpretations example in [EXAMPLES.md lines 59-91](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/EXAMPLES.md#L59-L91).
-
Detect ambiguity — Identify missing information such as output format, data scope, or performance constraints.
-
Ask clarifying questions — List each unknown as a specific bullet point for the user to answer.
-
Wait for the user’s answers — Only proceed after receiving explicit clarification; never guess.
-
Define success criteria — Formulate concrete, testable goals (e.g., "API endpoint returns paginated JSON with 20 records per page").
-
Implement the minimal solution — Write just enough code to satisfy the criteria, following Surgical Changes.
-
Verify — Run the tests or manual checks defined in step 4 to confirm completion.
This workflow ensures the assistant never proceeds on unverified assumptions and always produces measurable results.
Practical Implementation Examples
The following code snippets demonstrate how to apply these guidelines when handling a vague request programmatically or in development workflows.
Detecting and Surfacing Ambiguity
This Python-style pseudo-code illustrates how to programmatically detect missing information and request clarification before implementation:
def handle_request(request: str) -> str:
"""
Given a user request, return either:
• A list of clarification questions, or
• The final implementation (once clarified).
"""
# 1️⃣ Detect missing information (simple heuristic)
missing = []
if "export" in request.lower():
if "format" not in request.lower():
missing.append("What export format do you need? (e.g., JSON, CSV, XML)")
if "scope" not in request.lower():
missing.append("Should we export all users or a filtered subset?")
if "fields" not in request.lower():
missing.append("Which user fields should be included?")
if "delivery" not in request.lower():
missing.append("How should the file be delivered (download, email, API response)?")
# 2️⃣ If anything is missing, ask the user
if missing:
return "Before implementing, could you clarify:\n- " + "\n- ".join(missing)
# 3️⃣ Once clarified, define success criteria
success = (
"✅ Goal: Provide an API endpoint `/users/export` that returns a paginated JSON "
"containing the requested fields.\n"
"Test: `GET /users/export?page=1&size=20` returns 20 users and correct schema."
)
# 4️⃣ Minimal implementation (omitted for brevity)
return success
This approach detects vague aspects and asks targeted questions, then converts the clarified request into a concrete goal and test.
Encoding Success Criteria as Tests
Following Goal-Driven Execution, define success criteria as failing tests before writing implementation code:
# tests/test_export.py
def test_export_endpoint(client):
"""
Verify the export endpoint satisfies the clarified goal:
- Returns JSON
- Is paginated (default page size = 20)
- Includes only the fields 'id' and 'email'
"""
resp = client.get("/users/export?page=1&size=20")
assert resp.status_code == 200
data = resp.json()
assert isinstance(data, list) and len(data) == 20
for user in data:
assert set(user.keys()) == {"id", "email"}
This test encodes the specific success criteria agreed upon during clarification, ensuring the implementation satisfies the exact scope defined by the user.
Surgical, Minimal Implementation
Once requirements are clarified and tests defined, implement only the necessary functionality:
# app/routes.py (only the newly needed lines)
@router.get("/users/export")
def export_users(page: int = 1, size: int = 20, db: Session = Depends(get_db)):
"""
Simple export – returns paginated JSON with only id and email.
"""
stmt = select(User.id, User.email).offset((page - 1) * size).limit(size)
results = db.execute(stmt).fetchall()
return [{"id": r.id, "email": r.email} for r in results]
This implementation contains no extra abstractions, no caching layer, and no file generation—exactly the minimal solution that fulfills the clarified request, adhering to Simplicity First and Surgical Changes.
Summary
- Never code immediately when facing a vague request; always surface hidden assumptions first.
- Ask clarifying questions about scope, format, fields, and delivery mechanisms before proceeding.
- Define testable goals that specify exactly what success looks like and how to verify it.
- Change only what's necessary by limiting edits to the specific lines that address the clarified requirement.
- Start minimal and avoid over-engineering; add complexity only when the problem demands it.
Frequently Asked Questions
What makes a user request "vague" or "underspecified"?
A request is vague when it lacks critical parameters necessary for implementation, such as output format (JSON vs. CSV), data scope (all records vs. filtered), field selection, volume constraints, or error handling requirements. According to the EXAMPLES.md guidelines, requests like "Add a feature to export user data" contain at least four hidden assumptions that must be clarified before coding begins.
How do I avoid over-engineering when requirements are unclear?
Apply the Simplicity First principle from [README.md lines 40-51](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/README.md#L40-L51): implement only the minimal functionality that satisfies the clarified success criteria. Do not build abstraction layers, caching mechanisms, or plugin architectures until the user explicitly requests them or the codebase demonstrates a recurring need.
When should I ask clarifying questions versus making assumptions?
Always ask clarifying questions when any ambiguity exists. The Think Before Coding principle in [README.md lines 28-38](https://github.com/forrestchang/andrej-karpathy-skills/blob/main/README.md#L28-L38) explicitly forbids silent assumption-making. If you can identify multiple valid interpretations of a request, you must present them to the user and wait for a decision rather than selecting the most common default.
How do these guidelines integrate with Claude Code?
The repository provides a ready-to-install skill via skills/karpathy-guidelines/SKILL.md and .claude-plugin/plugin.json, which injects these four principles into Claude Code's system prompt. This ensures the AI assistant follows the clarification workflow automatically when processing vague or underspecified requests in any project where the skill is enabled.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →