Skip to content
AI Product Engineer Wiki

    ↑ ↓ to move between results, Enter to open, Esc to close

    Menu

    The AI product lifecycle, from problem to iteration

    The six-step loop every AI feature goes through, from user problem to shipping and learning, with the artifact and exit criterion for each step.

    Level: Beginner 12 min read Updated
    On this page

    Why this matters

    AI features tend to fail in predictable places. Some solve a problem nobody has. Some look great in a demo and fall apart on real inputs. Some launch to everyone at once and can’t be rolled back. Some quietly get worse after a model upgrade.

    A lifecycle gives you a checkpoint before each of those failures. This article walks through the six-step loop the rest of the wiki is organized around. For each step you’ll see the question it answers, the artifact it produces and how you know you’re done.

    The loop

    The lifecycle is a loop, not a line. Shipping isn’t the end: what you learn from real users becomes the next problem to solve.

    The AI product loop. Every launch feeds the next problem.
    Show text descriptionHide text description

    A loop of six steps. The last step leads back to the first.

    1. User problem (Stage 2)
    2. Model and cost (Stage 3)
    3. AI UX (Stage 4)
    4. Prototype (Stage 5)
    5. Evals (Stage 6)
    6. Ship and learn (Stages 7–8)

    After "Ship and learn", what you learned from users becomes the next user problem.

    Step Question Artifact Done when Stage
    1. User problem Is this a real, frequent job worth solving? One-page spec with a success metric The metric and the “no AI” alternative are written down Product Foundations
    2. Model and cost Can a model do this fast and cheaply enough? Model choice, latency and cost estimate Estimated cost per success fits the value LLM Capabilities
    3. AI UX How will people trust, check and correct it? Designs for every state, including failures Every way a call can end has a designed state Designing AI UX
    4. Prototype Does it actually help, on real inputs? Working prototype and test notes Real users tried it and you know why it helped or didn’t Rapid Prototyping
    5. Evals How often is it good enough? Golden dataset, graders, threshold It passes a threshold agreed before measuring Evals as Product Metrics
    6. Ship and learn Does it help at scale, safely and profitably? Flags, staged rollout, dashboards Metrics and cost confirm it, or you roll back Shipping & Iterating, Trust, Safety & Economics

    Step by step

    1. User problem

    Start from a job people already do and find painful, not from a model capability. “Users spend 15 minutes catching up on long threads” is a problem. “We should add an AI summary” is a solution looking for one.

    The artifact is a one-page spec: the user, the job, how they do it today, what success looks like as a number, and what you’d build without AI. That last line matters. If a filter, a template or better defaults solves the problem, ship that instead. When not to use AI covers how to decide.

    2. Model and cost

    Before designing anything, check feasibility. Can current models do the task at the quality you need? How long will a response take? What will each successful use cost?

    You don’t need precise numbers yet, just the right order of magnitude. If a back-of-the-envelope estimate says each summary costs more than the user is worth, find out now, not after launch.

    3. AI UX

    Design the experience for the way AI actually behaves: sometimes slow, sometimes wrong, occasionally declining a request. The core question is how people will trust, check and correct the output.

    The artifact covers every state: loading, streaming, success, partial answer, refusal, error and empty. If you’ve seen the code in the first article, this is where each of those branches gets its design.

    4. Prototype

    Build the cheapest thing that lets real users try the experience on their real inputs. Sometimes that’s a prompt in a playground. Sometimes it’s a Wizard-of-Oz test with a human behind the curtain. Sometimes it’s a one-day Next.js app.

    You’re done when you know why it helped or didn’t, not when the code is clean. Notes from watching five people use it are worth more than a polished demo.

    5. Evals

    Turn what you learned into a golden dataset: real inputs paired with what a good output looks like, plus graders that check each one. Then agree on a pass threshold before you run it. Setting the bar afterwards means setting it wherever the results landed.

    This is the step most often skipped, and the one that makes every later change safe. With an eval set, “I improved the prompt” becomes a number you can check.

    6. Ship and learn

    Roll out behind a feature flag, to a small group first. Watch product metrics (task success, edits, retries), quality signals and cost per success. Expand if they hold. Roll back if they don’t.

    Then the loop restarts. The edits users make, the questions they retry and the cases where the feature failed become new problems for step 1 and new eval cases for step 5.

    What makes this loop different

    If you’ve shipped software before, most of these steps look familiar. Four things are specific to AI features:

    • Evals sit between prototype and launch as a gate. A normal feature passes or fails its tests. An AI feature passes a quality threshold on a representative set.
    • The loop keeps running after launch. Real usage keeps producing new failure cases, so the eval set grows over the feature’s life.
    • Model changes re-enter the loop. A new model version is a change like any other: run the evals before switching.
    • Cost is a per-use metric. It belongs on the launch dashboard next to quality, not in a quarterly finance review.

    An eval gate in code

    Here’s step 5 in miniature: a script that runs golden cases through the summary feature, grades each result with simple checks, and fails the CI job if the pass rate drops below the threshold.

    evals/summary-gate.ts
    import Anthropic from '@anthropic-ai/sdk';
    
    const client = new Anthropic();
    
    interface GoldenCase {
      id: string;
      thread: string;
      /** Facts a good summary must mention. Taken from real threads that users found hard to follow. */
      mustMention: string[];
    }
    
    const cases: GoldenCase[] = [
      {
        id: 'launch-date-moved',
        thread:
          'Ana: Can we still launch on the 12th?\nBen: Legal needs another week.\nAna: OK, moving launch to the 19th. Ben, tell support.',
        mustMention: ['19th', 'legal'],
      },
      {
        id: 'budget-approval',
        thread:
          'Kim: The vendor quote is 18k.\nLee: Over our 15k limit, needs director sign-off.\nKim: Asking Dana to approve by Friday.',
        mustMention: ['18k', 'Dana', 'Friday'],
      },
    ];
    
    const MAX_BULLETS = 5;
    // Agreed with the team before the first run, so the bar can't drift to wherever results land.
    const PASS_THRESHOLD = 0.9;
    
    /** Returns the summary, or null if the answer didn't finish normally. */
    async function summarize(thread: string): Promise<string | null> {
      // No fallback here on purpose: an eval should measure the model you ship, and a refusal counts as a failure.
      const response = await client.messages.create({
        model: 'claude-opus-5-5',
        // Thinking is always on for this model and counts towards max_tokens, so leave headroom beyond the summary.
        max_tokens: 4096,
        output_config: { effort: 'low' },
        system: 'Summarize the email thread in at most five short bullet points. Name the decision that is needed, if any.',
        messages: [{ role: 'user', content: thread }],
      });
    
      // Only a complete answer can pass. Truncated (max_tokens), refused or otherwise unfinished answers fail the case.
      if (response.stop_reason !== 'end_turn') return null;
    
      return response.content.flatMap((block) => (block.type === 'text' ? [block.text] : [])).join('');
    }
    
    /** Lists the reasons a summary fails a case. An empty list means it passed. */
    function grade(summary: string | null, c: GoldenCase): string[] {
      if (summary === null) return ['did not finish normally'];
      const failures: string[] = [];
      const bullets = summary.split('\n').filter((line) => /^\s*[-*•]/.test(line));
      if (bullets.length === 0 || bullets.length > MAX_BULLETS) {
        failures.push(`expected 1–${MAX_BULLETS} bullets, got ${bullets.length}`);
      }
      for (const fact of c.mustMention) {
        if (!summary.toLowerCase().includes(fact.toLowerCase())) failures.push(`missing "${fact}"`);
      }
      return failures;
    }
    
    const results = await Promise.all(
      cases.map(async (c) => ({ id: c.id, failures: grade(await summarize(c.thread), c) })),
    );
    
    for (const r of results) {
      console.log(r.failures.length === 0 ? `PASS ${r.id}` : `FAIL ${r.id}: ${r.failures.join('; ')}`);
    }
    
    const passRate = results.filter((r) => r.failures.length === 0).length / results.length;
    console.log(`Pass rate ${(passRate * 100).toFixed(0)}% (threshold ${PASS_THRESHOLD * 100}%)`);
    
    // A non-zero exit code fails the CI job, which blocks the merge.
    if (passRate < PASS_THRESHOLD) process.exitCode = 1;

    Run it with npx tsx evals/summary-gate.ts and an ANTHROPIC_API_KEY in your environment. Three things to notice:

    • The threshold is a constant decided in advance, with a comment saying so.
    • Unfinished answers fail. The script checks stop_reason before reading the text, so a truncated or refused summary can’t sneak through as a pass.
    • Two cases are far too few. A real eval set starts at a few dozen cases drawn from real usage and grows from there. Simple string checks also miss a lot: Evals as Product Metrics adds rubrics and LLM-as-judge graders.

    Common mistakes

    • Starting at step 4. Prototyping before writing down the problem and success metric produces impressive demos with no way to tell if they work.
    • Treating evals as optional polish. Without them, every prompt change is a guess and every model upgrade is a risk.
    • Shipping to 100% on day one. Roll out to a small group behind a flag, with a rollback plan, even for “small” AI features.
    • Stopping the loop at launch. User edits, retries and complaints are the best source of new eval cases. Collect them from the first day.
    • Skipping the cost estimate. Discovering after launch that each use costs more than it’s worth forces a painful redesign or a quiet shutdown.

    Try it

    Exercise

    About 30 min

    Map one AI feature onto the loop

    1. Choose an AI feature you’d like to build, or one you’ve already built.
    2. For each of the six steps, write the question it answers for your feature, the artifact you’d produce and your “done when” criterion.
    3. Circle the step you’ve thought about least. That’s the most likely place for the feature to fail.
    Show a hint

    Be concrete. “Done when users like it” isn’t a criterion. “Done when at least 4 of 5 test users finish the task without help” is.

    Show a worked solution

    Example for “AI-drafted replies in a support inbox”:

    1. User problem: agents spend most of their time on repetitive questions. Done when the spec names the metric (time to first reply) and the non-AI option (saved replies).
    2. Model and cost: estimate tokens per ticket and cost per drafted reply. Done when cost per accepted draft is clearly below the agent time it saves.
    3. AI UX: drafts are always editable, show the help-center articles they used, and never send automatically. Done when every state is designed.
    4. Prototype: five agents use drafts on real tickets for a day. Done when you know which ticket types drafts help with.
    5. Evals: 50 real tickets with approved replies, graded on accuracy and tone. Done when the pass rate clears 85%, agreed in advance.
    6. Ship and learn: flag on for one team, track edit distance and acceptance rate. Done when metrics hold for two weeks.

    Least-considered step in this example: probably step 2. Drafting replies with long ticket histories can get expensive.

    Check your understanding

    Question 1 of 4: Why is the lifecycle drawn as a loop rather than a line?

    Show answer

    B. Because what you learn after shipping becomes the next problem and new eval cases

    Real usage keeps producing new failure cases and opportunities. They feed back into step 1 as problems and into step 5 as eval cases.

    Question 2 of 4: When should you set the pass threshold for an eval?

    Show answer

    B. Before running the eval for the first time

    Setting the bar after seeing results means setting it wherever the results landed. Agree on it first.

    Question 3 of 4: In the eval gate script, why does summarize return null unless stop_reason is "end_turn"?

    Show answer

    B. So truncated, refused or unfinished answers count as failures instead of passing by accident

    A truncated summary might still contain the required words and pass the string checks. Treating unfinished answers as failures keeps the eval honest.

    Question 4 of 4: Which artifact belongs to step 1, User problem?

    Show answer

    C. A one-page spec with a success metric and a non-AI alternative

    Step 1 ends with a short spec: who, what job, how it is done today, the success metric, and what you would build without AI.

    Key takeaways

    • Every AI feature moves through six steps: user problem, model and cost, AI UX, prototype, evals, ship and learn.
    • Each step has an artifact and a “done when” criterion. Writing them down is what turns the loop into a process.
    • Evals are the gate between prototype and launch, with a threshold agreed in advance and unfinished answers counted as failures.
    • The loop doesn’t end at launch. Real usage feeds new problems and new eval cases back in.

    Progress is saved in this browser and lights up the roadmap.