AI Skill Report Card

Engineering Technical Prompts

A-87·Nov 10, 2026·Source: Web
15 / 15

Bad prompt:

Write a function to parse dates.

Good prompt:

Context:
- Language: Python 3.11
- Framework: none (stdlib only)
- Constraint: must run in <10ms per call, no external deps

Task:
Write a function `parse_date(s: str) -> date | None` that parses dates
in formats "YYYY-MM-DD", "DD/MM/YYYY", and "Month DD, YYYY".

Input: a string, possibly malformed or empty.
Output: a `datetime.date` object, or `None` if parsing fails (do not raise).

Requirements:
- Add type hints and a docstring with examples.
- Handle edge cases: empty string, whitespace-only, None input,
  invalid day/month (e.g. 30/02/2024), ambiguous format conflicts.
- Add inline comments explaining format-detection logic.
- Include 5 unit tests covering normal cases and edge cases.
Recommendation▾
Add a brief section on handling ambiguous or contradictory requirements from stakeholders before drafting prompts
14 / 15

Progress:

  • Step 1: Define context block (language/version, framework, runtime constraints)
  • Step 2: Define input contract (types, nullability, valid ranges)
  • Step 3: Define output contract (type, error-handling behavior)
  • Step 4: List known edge cases explicitly
  • Step 5: Require comments/docstrings and test coverage
  • Step 6: Review draft prompt for ambiguity before sending

Step 1 — Context block. Always state: exact language version (e.g. "Python 3.11" not "Python"), framework + version, memory/time budget if relevant, and dependency constraints ("stdlib only", "no new packages").

Step 2 — Input/Output contract. Specify exact function/API signature if known. State types, nullability, valid ranges, and what happens on invalid input (raise? return None? default value?). Never leave this implicit.

Step 3 — Edge cases. Brainstorm and explicitly list: empty/null/zero inputs, boundary values, concurrency, malformed data, very large inputs, non-ASCII/unicode, duplicate entries, timeouts/network failures.

Step 4 — Documentation requirement. Require: docstrings with param/return descriptions, inline comments on non-obvious logic, and usage examples.

Step 5 — Verification requirement. Request unit tests or a self-check demonstrating edge cases pass.

Recommendation▾
Include an example of a 'bad outcome' - i.e., what happens when a vague prompt actually gets executed vs. the engineered version
19 / 20

Example 1: Input (vague request): "Write a caching decorator." Output (engineered prompt):

Context: Python 3.10, async codebase using asyncio, no third-party libs.
Constraint: cache must be bounded (max 1000 entries, LRU eviction), thread-safe
for asyncio single-loop use.

Task: Implement `@async_cache(maxsize=1000)` decorator for async functions.

Input: any async function with hashable positional/keyword args.
Output: wrapped async function returning cached result on repeat calls.

Edge cases to handle:
- Unhashable arguments -> bypass cache, call function directly, log a warning.
- Exceptions raised by wrapped function -> do not cache, propagate exception.
- Cache eviction when maxsize exceeded -> evict least-recently-used entry.
- Concurrent calls with same args before first completes -> share the same
  in-flight future (avoid duplicate execution).

Require: docstring, inline comments on eviction logic, and 6 unit tests
(including concurrency and exception cases).

Example 2: Input (vague request): "Parse a CSV file." Output (engineered prompt):

Context: Node.js 20, TypeScript 5.3, using only built-in `fs` + `string` methods
(no csv-parse lib). Memory constraint: must stream, not load full file (files
up to 2GB).

Task: write `parseCsvStream(filePath: string): AsyncGenerator<Record<string,string>>`.

Input: path to a CSV file; first row is header.
Output: async generator yielding one object per row, keyed by header.

Edge cases:
- Trailing newline or missing final newline.
- Quoted fields containing commas or embedded newlines.
- Empty file -> generator yields nothing, no error.
- Rows with fewer/more columns than header -> throw a descriptive error
  including the line number.

Require: TSDoc comments, explanation of the streaming/buffering approach,
and 5 test cases covering the edge cases above.
Recommendation▾
Consider a condensed reusable template block summarizing the Context/Task/Input/Output/Edge cases structure for quick copy-paste
  • State versions, not just names ("React 18.2" not "React").
  • Make error-handling behavior explicit — never let the model guess whether to throw, return null, or log.
  • Prefer enumerated edge cases over "handle edge cases properly" — the model fills gaps with assumptions otherwise.
  • Ask for tests/examples as a forcing function for correctness.
  • When performance matters, state the budget numerically (ms, MB, O(n) complexity) rather than "fast" or "efficient".
  • Keep the prompt structured (Context / Task / Input / Output / Edge cases / Requirements) so nothing is skipped.
  • Omitting language/framework version — leads to code using deprecated or mismatched APIs.
  • Leaving error behavior implicit — causes inconsistent exception vs. null-return handling.
  • Saying "handle edge cases" without listing any — model will handle only the obvious ones.
  • Forgetting to ask for comments — resulting code is correct but unmaintainable.
  • Mixing multiple unrelated tasks in one prompt — reduces precision of each requirement.
0
Grade A-AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
15/15
Workflow
14/15
Examples
19/20
Completeness
17/20
Format
15/15
Conciseness
13/15