I took a massive risk this year: I started a new company. Everybody looks at me like I'm a little nuts building an AI tool. They ask "how is this better than Claude or ChatGPT?" and they're not wrong to question me. How is it worth competing with OpenAI or Anthropic when it can build almost anything for you?
My conviction has only grown in the past month with the emergence of decision models. In September, Typesafe AI released a new model called Jev and it took the tech world by storm. It raised an $870 million funding round 24 days after launch led by A16Z at a $7.5 billion valuation. It's valued as much as Dropbox. That's insane!
Just weeks later, major companies came out with their own versions: OpenAI, Microsoft, Cloudflare, Perplexity, Amazon and a lot of startups launched competing models.
When it was announced, I was intrigued by all of the social media influencer hype videos and I saw an immediate way I could use it. I knew it would be useful and reduce my costs, but I wasn't sure if it would live up to the hype. After playing with it and rebuilding my app with it, I have completely come around. I don't know if Typesafe will live up to its lofty valuation, but I think the cooler idea is that it gives an advantage to smaller companies and startups.
I don't want to compete with OpenAI. I want to build something for a specific audience, solving a particular pain point, and I want to optimize the UI and the experience to solve that one thing insanely well. I'm willing to make trade-offs that big companies can't. Anyone can leverage the smartest LLMs, but the thing that's exciting about decision models is that it gives me much better tools to make my product stand out.
I rebuilt the core value prop of my product to be more differentiated, better, faster, and cost me less. In this post, I want to share my experience becoming decision model-pilled by explaining:
Jev is a different kind of LLM. You pass in text and questions, and it answers them in a standard JSON schema. There's no prose output. A couple of quick examples:
That's the simplest possible example. It can get incredibly sophisticated. Here's an example of Jev playing Doom, being called every 100ms to decide whether to move, change directions, jump, or shoot based on the state of the game (health, ammo, location of enemies, are they shooting at you, etc):
Jev answers questions at a comparable intelligence level to existing LLMs, but does it multiple orders of magnitude faster and cheaper. It also does not hallucinate: it always returns information in the format you expect. You can ask many questions at once, and it doesn't slow down the request and questions are evaluated independently. This is important - if you asked multiple questions to another LLM it would impact the output, while it does not for Jev.
The fast, cheap, and independently answered questions enable speculative fan-out. It is magical. Here's a simple example for a support tool triaging an email from a customer. You can classify the text of the email into buckets, but with speculative fan-out you can also ask the follow-up questions for each of the buckets. For instance, before you even know it's a refund request, you can already ask the refund follow-ups: Did they say when the charge happened? Were they charged twice? It took me a while to come around to the idea that you can ask the question and the follow-up at the same time.
Hi,
I've been a customer for about two years, and I've mostly been happy with the product. My team uses it every day for our weekly reports.
This month, though, I was billed $49 twice for our Team plan on March 3. I checked my bank statement, and both charges went through about a minute apart. I didn't upgrade or add any seats, so I'm not sure what happened.
Please refund the extra charge. I'd also like to know why it happened, so it doesn't come up again when our finance team reviews expenses at the end of the quarter.
If this keeps happening, I'll dispute the charges with my bank, cancel, and move the team to another tool.
Thanks,
Sam
+ 4 earlier messages in the thread
refundlook_up_charges and issue_refund. Fewer, narrower tools give better results. This step has to wait for call 1.| Before Jev | With Jev | |
|---|---|---|
| Calls | 2, one after the other | 1 |
| Time to triage | ~17 seconds | ~0.3 seconds |
| Cost to triage | ~$0.017 | ~$0.0001 |
| What comes back | Text you have to parse and check | An answer for every question, in a fixed format |
| Same email, run twice | The answers can change | The same answers |
| The other kinds | Never asked | Answered too, at no extra wait |
POST api.typesafe.ai/v1/systemone { "model": "jev-latest", "state": { "subject": "Charged twice this month", "email": "Hi, I've been a customer for about two years…", "earlier_thread": "…" }, "questions": { "kind": { "type": "choice", "instructions": "Which kind of support email is this?", "criteria": { "refund": "asks for money back", "cancellation": "wants to stop the service", "question": "asks how something works", "bug": "reports something broken", "none": "none of these" } }, "refund_amount_stated": { "type": "noul", "instructions": "Does the email state an amount?" }, "refund_charged_twice": { "type": "noul", "instructions": "Does the customer say they were charged twice?" }, "refund_plan": { "type": "choice", "instructions": "Which plan is the email about?", "criteria": { "starter": "…", "team": "…", "business": "…", "none": "no plan named" } }, "cancel_says_will_cancel": { "type": "noul", "instructions": "Does the customer say they will cancel?" }, "refund_cause": { "type": "choice", "instructions": "What caused the problem?", "criteria": { "duplicate_charge": "…", "proration": "…", "failed_retry": "…", "none": "…" } }, "every_bank_dispute": { "type": "noul", "instructions": "Does the customer threaten a chargeback or a bank dispute?" }, "every_asks_why": { "type": "noul", "instructions": "Does the customer ask why it happened?" }, "question_about_billing": { … }, "bug_describes_error": { … }, … // 20 questions in all } }
{ "answers": {
"kind": { "choice": "refund",
"probabilities": { "refund": 0.91,
"cancellation": 0.06, "question": 0.02,
"bug": 0.01, "none": 0.00 } },
"refund_amount_stated": { "noul": 0.97 },
"refund_charged_twice": { "noul": 0.96 },
"refund_plan": { "choice": "team",
"probabilities": { "team": 0.88, … } },
"refund_cause": { "choice": "duplicate_charge",
"probabilities": { "duplicate_charge": 0.86, … } },
"every_bank_dispute": { "noul": 0.85 },
"every_asks_why": { "noul": 0.94 },
"cancel_says_will_cancel": { "noul": 0.62 },
"question_about_billing": { "noul": 0.90 },
"bug_describes_error": { "noul": 0.40 },
…
},
"usage": { "input_tokens": 2200,
"output_tokens": 0 } }
// cost of this call: about $0.00009
I have an AI app called Work Coach. It's a desktop app that coaches you based on your meetings (interviews, 1:1s, sales calls, presentations, etc). It analyzes what happened, what you said, and how you said it. It gives you the feedback nobody is telling you: what went well, what to improve upon for next time, and the moment in the meeting where it happened.
That coaching is the core of the product, and it's the part I rebuilt on Jev and open-source models. Here are some high level stats of the before and after:
| Before | Now | before now | ||
|---|---|---|---|---|
| Time to coaching | 74 s | ~21 s | about 3.5× faster | |
| Time to judge every chapter | 66 s | 0.28 s | about 230× faster | |
| Cost per meeting | $0.13 | ~$0.01 | about 13× cheaper | |
| Cost per judgment | ~1¢ | 0.0006¢ | about 1,700× cheaper |
Before: the two Sonnet coaching calls. Now: Jev and an open weight model
The same 34-minute one-on-one, you are the report. Tap or hover a dot to read its question. Questions are real ones from the pipeline, shortened, and the probabilities are illustrative. Before, nothing checked the work.
Alternative version of the diagram above, for comparison.
The same 45-minute interview, you are the candidate. Tap or hover anything to read it. Round three, the writing and the claim checks follow the code today. Asking every meeting type's and chapter kind's follow-ups in rounds one and two is the proposed design. Times: the Sonnet calls and the 0.3 s chapter calls are measured; the other steps are estimates from the pipeline's timings. Questions are shortened and answers are illustrative.
When you asked Work Coach to observe a meeting, it recorded it and then analyzed the transcript. The pipeline:
The dynamic custom prompt was the primary source of coaching. An interview candidate got areas like "STAR answer quality". A manager in a one-on-one was coached on how well they coached rather than solved problems for the other person.
On average, meeting transcripts are 20,000 input tokens and it generated over 6,000 output tokens (including thinking tokens). The suggestions took about 1-2 minutes to calculate. One drawback with this is that it was hard to prompt engineer the system to look for specific items. If I wanted it to consider multiple possibilities, I had to put a lot of examples and context into the system prompt and it took a lot of iterating to get it to behave as I wanted. It is hard to generate evals that covered all of the potential coaching points and paths an LLM could take for any given meeting.
When Jev came out I decided to use it for simple meeting classification. As I learned more about it, I ended up rewriting my entire product around it. It wasn't clear to me how powerful it was until I got deep into implementing it.
I had tried open weight models in the past but ultimately stuck with Sonnet. Sonnet was higher quality, especially when I used a fair amount of thinking tokens.
That all changed when I used Jev and open models together.
Here is the same meeting in the new workflow. There is power in the pattern that Jev builds on:
Here's how I use speculative fan-out for Work Coach: I call Jev for each chapter in parallel, and each request sends at least 30 questions to evaluate. In the example of an interview, each request asks what kind of interview chapter it is (Intro, Background, Behavioral question, Case, Technical question, Questions, Logistics, etc) and then I also send the follow-up questions for each of those types.
This all happens in the same request! This is a weird concept for most product builders and technologists today because it hasn't been cost effective or time efficient to do this previously. Jev evaluates all 30 questions simultaneously against the same input tokens, and they don't interfere with each other. By contrast, if I sent all of the questions at the same time to an LLM, it could affect the output just by being in the prompt. It doesn't matter that I'm sending more questions than I need, it's actually better because it's more cost efficient than chaining calls and sending the transcript each time. The majority of the cost is in the transcript tokens, not the tokens associated with the questions.
It all comes back together in about a quarter of a second, for a tiny fraction of a cent. I only use the follow-up answers for the category it picked, and I ignore the answers for the non-picked chapter type.
THEMTell me about a time you turned around a project that was behind.
YOUSure. At my last job, our onboarding redesign was six weeks late. Design and engineering were waiting on each other, and nobody owned the scope.
YOUI pulled the funnel data and saw that two screens caused most of the drop-off. I cut the project down to those two and set up a weekly demo, and we shipped in three weeks.
YOUActivation went from 31% to 44% in the first month.
Jev said behavioral, so the app reads the behavioral row and skips the other 23 answers.
THEMTo start, walk me through your background.
YOUI'm a product manager at Acme. I own onboarding and activation for the self-serve product, which is about 40% of new revenue.
YOUBefore that I spent three years in growth at a fintech startup, and I started out as an analyst.
YOUThat's me in a nutshell.
Jev said background, so the app reads the background row and skips the other 25 answers.
THEMWhat questions do you have for me?
YOUYou mentioned the team moved to weekly releases. What made you change, and what broke?
THEMMostly QA. We had to automate a lot more of the testing.
YOUWhat would make someone great in this role after 90 days?
Jev said your questions, so the app reads the your questions row and skips the other 25 answers.
POST api.typesafe.ai/v1/systemone
{
"model": "jev-latest",
"state": {
"meeting_type": "interview", "user_role": "interviewee",
"chapter_transcript": "THEM: Tell me about a time you turned …"
},
"questions": {
"kind_check": { "type": "choice",
"instructions": "Which kind of chapter is this?",
"criteria": { "intro": "…", "background": "…",
"behavioral": "…", // and 5 more, plus "none" } },
"open_item": { "type": "choice", … },
"behavioral.q1": { "type": "noul",
"instructions": "Did you set the scene and what was at stake?" },
"background.q1": { "type": "noul",
"instructions": "Did you say what you do today?" },
"candidate_questions.q1": { "type": "noul",
"instructions": "Did you ask something only this company could answer?" },
// 30 questions in all
}
}{ "answers": {
"kind_check": { "choice": "behavioral",
"probabilities": { "behavioral": 0.94, … } },
"open_item": { "choice": "answered", … },
"behavioral.q1": { "noul": 0.88 },
"background.q1": { "noul": 0.12 },
"candidate_questions.q1": { "noul": 0.34 },
// all 30 questions have an answer
},
"usage": { "input_tokens": 2300, "output_tokens": 0 } }
// cost of this call: about $0.0001const kind = res.answers.kind_check.choice; // kind is "behavioral" const row = FOLLOW_UPS[kind].map((id) => [id, res.answers[id].noul]); // 5 answers const wentWell = row.filter(([, p]) => p >= 0.8); const coachOn = row.filter(([, p]) => p <= 0.3); // the other 23 answers are not read
POST api.typesafe.ai/v1/systemone
{
"model": "jev-latest",
"state": {
"meeting_type": "interview", "user_role": "interviewee",
"chapter_transcript": "THEM: To start, walk me through your b…"
},
"questions": {
"kind_check": { "type": "choice",
"instructions": "Which kind of chapter is this?",
"criteria": { "intro": "…", "background": "…",
"behavioral": "…", // and 5 more, plus "none" } },
"open_item": { "type": "choice", … },
"behavioral.q1": { "type": "noul",
"instructions": "Did you set the scene and what was at stake?" },
"background.q1": { "type": "noul",
"instructions": "Did you say what you do today?" },
"candidate_questions.q1": { "type": "noul",
"instructions": "Did you ask something only this company could answer?" },
// 30 questions in all
}
}{ "answers": {
"kind_check": { "choice": "background",
"probabilities": { "background": 0.91, … } },
"open_item": { "choice": "answered", … },
"behavioral.q1": { "noul": 0.30 },
"background.q1": { "noul": 0.93 },
"candidate_questions.q1": { "noul": 0.19 },
// all 30 questions have an answer
},
"usage": { "input_tokens": 2300, "output_tokens": 0 } }
// cost of this call: about $0.0001const kind = res.answers.kind_check.choice; // kind is "background" const row = FOLLOW_UPS[kind].map((id) => [id, res.answers[id].noul]); // 3 answers const wentWell = row.filter(([, p]) => p >= 0.8); const coachOn = row.filter(([, p]) => p <= 0.3); // the other 25 answers are not read
POST api.typesafe.ai/v1/systemone
{
"model": "jev-latest",
"state": {
"meeting_type": "interview", "user_role": "interviewee",
"chapter_transcript": "THEM: What questions do you have for m…"
},
"questions": {
"kind_check": { "type": "choice",
"instructions": "Which kind of chapter is this?",
"criteria": { "intro": "…", "background": "…",
"behavioral": "…", // and 5 more, plus "none" } },
"open_item": { "type": "choice", … },
"behavioral.q1": { "type": "noul",
"instructions": "Did you set the scene and what was at stake?" },
"background.q1": { "type": "noul",
"instructions": "Did you say what you do today?" },
"candidate_questions.q1": { "type": "noul",
"instructions": "Did you ask something only this company could answer?" },
// 30 questions in all
}
}{ "answers": {
"kind_check": { "choice": "candidate_questions",
"probabilities": { "candidate_questions": 0.89, … } },
"open_item": { "choice": "answered", … },
"behavioral.q1": { "noul": 0.21 },
"background.q1": { "noul": 0.20 },
"candidate_questions.q1": { "noul": 0.91 },
// all 30 questions have an answer
},
"usage": { "input_tokens": 2300, "output_tokens": 0 } }
// cost of this call: about $0.0001const kind = res.answers.kind_check.choice; // kind is "candidate_questions" const row = FOLLOW_UPS[kind].map((id) => [id, res.answers[id].noul]); // 3 answers const wentWell = row.filter(([, p]) => p >= 0.8); const coachOn = row.filter(([, p]) => p <= 0.3); // the other 25 answers are not read
I rebuilt my app around this concept and I have spent a ton of time writing up this post, but I feel like I'm still wrapping my head around how to use this. It's such a non-intuitive paradigm, to be able to parallelize asking all of your questions at once. You can explore a really diverse and complicated problem space by chaining two or three Jev calls.
Previously, people were using LLMs to do similar tasks. They took a lot longer, cost more, hallucinated when multiple questions were asked simultaneously, and also couldn't give you good probabilistic scores about their confidence answering a question.
This is what makes me think that it's worth the hype. The potential to create more sophisticated and more intelligent agents and apps seems very high.
Previously, I told Claude to double check what it was recommending and to ground its work in quotes from the transcript. It still hallucinated all the time. It drove me crazy.
The coaching points now write the citations that drove the coaching point, for example: "you never asked when you'd hear back." Jev is now used to fact check those points and rewrite anything that isn't grounded in the meeting. If a fact fails, Jev checks it once more against the whole meeting, in case it happened somewhere else. If it still fails, the writer gets one rewrite with the reason attached. If the rewrite fails too, the point is dropped.
Before Jev, checking every sentence like this would have added cost and another wait. Now it's the cheapest part of the whole pipeline, and I've gotten a lot fewer complaints about hallucinations.
You asked plainly for a second designer and named why. Your manager said they'd check with finance, and you never asked when you'd hear back, so the ask can drift.
this says something is missing, but these lines hold a counter-example; drop the absence claim
You asked for a second designer, said what it would unblock, and asked to hear back by Friday. Next time, name what you'll do if the answer is no.
Shown to you. If a fact had failed again, the point would have been dropped.
Jev doesn't write user facing copy, so you still need an LLM for that. I've found that using Jev has closed the gap for me between the open weight models and the frontier models because the LLM has a much smaller and tighter scope of what it needs to do. The LLM no longer decides what's wrong with your meeting; it gets a chapter, the judgments that fired and a short brief, and writes a few sentences. It's faster, cheaper, and produces really high quality suggestions.
When I ran benchmarks comparing the outputs, the Jev + open weight model combination scored much better in terms of user preference as well as reducing hallucinations.
The hardest thing Work Coach grades is a case interview. A case is a business problem you work through out loud, like "Why are this client's profits down?" Interviewers score how you clarify the problem, structure it, use the data, do the math and land a recommendation.
That used to be one huge prompt. Now it's six calls in three waves, and each wave uses the answers from the wave before it. Five of the six calls are Jev. The open model has one job: it sketches the tree of ideas you talked through. Jev measures and checks everything else, including that tree.
Case interviews push it furthest. A 25-minute case is about 120 sentences from the candidate. Each sentence gets its own question: is this Clarify, Structure, Analyze, Math, Recommend, or none of those? Code then smooths the tags into stretches, finds where each stage took hold, and checks the order. A language model asked to do this would hand you a summary. This hands you a timeline.
This candidate jumps to math before finishing a structure, then comes back. That reversal is something the coach can now point at, with timestamps.
All six calls take a few seconds and ask about 200 questions. Code then turns the answers into the case flow and the issue tree you see on the coaching page, and into the coaching point for the case. Here is the real coaching page for a product manager interview.

Here is the whole process on one 45-minute job interview where you were the candidate. Round one classifies the whole transcript: what kind of meeting it is, and your role. The transcript then breaks into chapters, and round two makes one call per chapter that works out what kind of chapter it is and asks the follow-ups for every kind it could be. Round three goes deep only where round two says it should. Then the writing, and a check on every claim. Press Next or Play to step through it, and hover any box to read its question.
Two fingers move and zoom the canvas. Tap a box to read its question.
Sample interview. You are the candidate. Round 2 shows the planned design. Round 1, round 3, the writing and the claim checks show the pipeline as it runs today. The questions are short versions. The answers are examples.
My ambition for the app has increased exponentially as I realize what Jev enables. I can be obsessive around evaluating different perspectives and questions, because they are virtually free. Today, a one-on-one asks Jev a few dozen questions and a case interview a few hundred. There's a lot of room to improve the coaching experience by adding more frameworks and things to evaluate. Luckily, the ceiling is really high! Drag the sliders to see.
Assumes 181 transcript tokens per spoken minute (measured on 100 production meetings), about 60 tokens per question, 400 tokens of context per chapter, and Jev's list price. Calls run in parallel, so latency is one call, about 0.3 s, as long as each call stays inside Jev's 64k-token window.
For what the two old Sonnet coaching calls cost ($0.13), you could ask about 22,000 questions of this meeting.
With a generative model, every extra thing you want the system to notice costs output tokens and seconds, so you limit it. With Jev, a new question costs a line of code, a fraction of a thousandth of a cent, and virtually no latency. It becomes less about how well you can hack your system prompt and more about how thoughtful you are about what Jev considers.
Before, I used big prompts to decide what mattered, measure it and write about it all at once. It was impressive, the LLMs are very good at noticing things we're blind to. But there were all sorts of issues. I thought it was a magical experience before, but now that I'm using Jev it's clear that I was misusing it and missing a key piece.
Now I have a tool that costs virtually nothing, is insanely fast, and helps the LLM do a much better job. I'm able to use code to turn the answers into what gets coached. The LLM gets a chapter, the judgments that fired and a short brief, and does what it does best: write. Then I fact check it with Jev.
Each piece does the job it's best at. The app gets more predictable, faster and cheaper, and the writing gets better because the model has less to juggle.
I think this is going to lead to much, much better applications. I don't know if Typesafe will live up to its impressive valuation, but as a tech enthusiast I can't wait to see what people build with these new tools.
Thanks to Reed Shea, Buford Taylor, Anthony Roldan, Roberto Iturralde, Jeff Dwyer, Adam Fishman, and Roy Hodgman for their feedback on this post.
Newsletter
Occasional notes on building products with AI. No spam, unsubscribe anytime.