From 12b82b4b57d68f866a729fc1b7f2ed49613bf583 Mon Sep 17 00:00:00 2001 From: Vishnu Samavedula <19195679+vishnu-samavedula@users.noreply.github.com> Date: Fri, 2 Oct 2026 00:31:00 -0700 Subject: [PATCH 1/2] docs: add d1 agent skill setup --- lfm/models/decision-models.mdx | 66 ++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/lfm/models/decision-models.mdx b/lfm/models/decision-models.mdx index 0dcea69e..298f0aab 100644 --- a/lfm/models/decision-models.mdx +++ b/lfm/models/decision-models.mdx @@ -40,12 +40,42 @@ Set the key as an environment variable: export LIQUID_API_KEY="liquid_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ``` -You can also use the following prompt to give your agent to enable it to use Liquid AI's decision models. +## Agent Skill + +The [Liquid d1 agent skill](https://github.com/Liquid4All/liquid-d1-skills) helps coding agents find opportunities for d1 and integrate it into an application. It can inspect an existing codebase, recommend structured replacements for prompt-and-parse LLM calls, and help design effective Choice, Score, and Noul questions. + +Install the skill for the coding agent you use: + + + + ```bash + claude plugin marketplace add Liquid4All/liquid-d1-skills + claude plugin install liquid-d1@liquid-ai + ``` + + + ```bash + codex plugin marketplace add Liquid4All/liquid-d1-skills + codex plugin add liquid-d1@liquid-ai + ``` + + + ```bash + npx skills add Liquid4All/liquid-d1-skills --skill liquid-d1 + ``` + + Choose your agent when prompted. + + + +After installation, start a new agent session and try: ```text -Load https://docs.liquid.ai/.well-known/skills/decision-model/skill.md, then inspect this project for generated-text calls that are really bounded decisions. Recommend d1 replacements for classification, routing, scoring, reranking, and yes/no gates. +Use the Liquid d1 skill to inspect this project for generated-text calls that are really bounded decisions. Recommend d1 replacements for classification, routing, scoring, reranking, and yes/no gates. ``` +The skill includes API and SDK references, guidance for Liquid, Vercel AI Gateway, and OpenRouter, and a dependency-free script for testing requests. Keep `LIQUID_API_KEY` in your environment instead of including it in a prompt. + ## Your First Call A single API call contains three things: @@ -61,7 +91,7 @@ A single API call contains three things: -H "Authorization: Bearer $LIQUID_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "model": "d1:free", + "model": "d1", "state": "I have been waiting over three weeks for my order and nobody has responded to my emails. This is completely unacceptable.", "questions": { "is_complaint": { @@ -87,7 +117,7 @@ A single API call contains three things: ) result = client.system_one( - model="d1:free", + model="d1", state="I have been waiting over three weeks for my order and nobody has responded to my emails. This is completely unacceptable.", questions={ "is_complaint": Noul( @@ -112,7 +142,7 @@ A single API call contains three things: }); const result = await client.systemOne({ - model: "d1:free", + model: "d1", state: "I have been waiting over three weeks for my order and nobody has responded to my emails. This is completely unacceptable.", questions: { is_complaint: { @@ -130,7 +160,7 @@ A single API call contains three things: ```json { - "model": "d1:free", + "model": "d1", "answers": { "is_complaint": { "type": "noul", @@ -165,7 +195,7 @@ A Noul question returns a single probability between 0 and 1. Your code receives -H "Authorization: Bearer $LIQUID_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "model": "d1:free", + "model": "d1", "state": "You'\''re an absolute idiot and I hope your company goes bankrupt. I'\''m going to find out where you work.", "questions": { "is_harmful": { @@ -181,7 +211,7 @@ A Noul question returns a single probability between 0 and 1. Your code receives from typesafe_sdk import Noul result = client.system_one( - model="d1:free", + model="d1", state="You're an absolute idiot and I hope your company goes bankrupt. I'm going to find out where you work.", questions={ "is_harmful": Noul( @@ -194,7 +224,7 @@ A Noul question returns a single probability between 0 and 1. Your code receives ```typescript const result = await client.systemOne({ - model: "d1:free", + model: "d1", state: "You're an absolute idiot and I hope your company goes bankrupt. I'm going to find out where you work.", questions: { is_harmful: { @@ -242,7 +272,7 @@ A Choice question returns the selected option, a probability distribution over a -H "Authorization: Bearer $LIQUID_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "model": "d1:free", + "model": "d1", "state": "Hi, I was charged twice for my subscription last month. The amounts are $29.99 on March 3rd and again on March 5th. Can you refund the duplicate charge?", "questions": { "intent": { @@ -265,7 +295,7 @@ A Choice question returns the selected option, a probability distribution over a from typesafe_sdk import Choice result = client.system_one( - model="d1:free", + model="d1", state="Hi, I was charged twice for my subscription last month. The amounts are $29.99 on March 3rd and again on March 5th. Can you refund the duplicate charge?", questions={ "intent": Choice( @@ -285,7 +315,7 @@ A Choice question returns the selected option, a probability distribution over a ```typescript const result = await client.systemOne({ - model: "d1:free", + model: "d1", state: "Hi, I was charged twice for my subscription last month. The amounts are $29.99 on March 3rd and again on March 5th. Can you refund the duplicate charge?", questions: { intent: { @@ -354,7 +384,7 @@ A Score question returns a continuous value across an ordered rubric you define, -H "Authorization: Bearer $LIQUID_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "model": "d1:free", + "model": "d1", "state": "Our production API is returning 500 errors on every request. All customers are affected. Revenue impact is approximately $12,000 per hour. Started 15 minutes ago.", "questions": { "urgency": { @@ -376,7 +406,7 @@ A Score question returns a continuous value across an ordered rubric you define, from typesafe_sdk import Score result = client.system_one( - model="d1:free", + model="d1", state="Our production API is returning 500 errors on every request. All customers are affected. Revenue impact is approximately $12,000 per hour. Started 15 minutes ago.", questions={ "urgency": Score( @@ -395,7 +425,7 @@ A Score question returns a continuous value across an ordered rubric you define, ```typescript const result = await client.systemOne({ - model: "d1:free", + model: "d1", state: "Our production API is returning 500 errors on every request. All customers are affected. Revenue impact is approximately $12,000 per hour. Started 15 minutes ago.", questions: { urgency: { @@ -462,7 +492,7 @@ You can ask multiple questions of different types in the same call. The model ev -H "Authorization: Bearer $LIQUID_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "model": "d1:free", + "model": "d1", "state": "{\"message\": \"The checkout page crashes with a white screen whenever I try to apply a promo code. I'\''ve tried three different browsers. This is blocking a $4,200 order for our team and we need to place it before our procurement window closes on Friday.\", \"account\": {\"plan\": \"enterprise\", \"arr\": 52000, \"customer_since\": \"2022-03-15\"}}", "questions": { "is_bug": { @@ -507,7 +537,7 @@ You can ask multiple questions of different types in the same call. The model ev } result = client.system_one( - model="d1:free", + model="d1", state=json.dumps(ticket), questions={ "is_bug": Noul( @@ -546,7 +576,7 @@ You can ask multiple questions of different types in the same call. The model ev }; const result = await client.systemOne({ - model: "d1:free", + model: "d1", state: JSON.stringify(ticket), questions: { is_bug: { From 6fd14b02d124915aa821a75f0cc69ce9f2e7c0be Mon Sep 17 00:00:00 2001 From: Vishnu Samavedula <19195679+vishnu-samavedula@users.noreply.github.com> Date: Tue, 20 Oct 2026 11:59:07 -0700 Subject: [PATCH 2/2] docs: address d1 agent skill review feedback --- .mintlify/skills/decision-model/SKILL.md | 264 ----------------------- guides/decision-model-guide.mdx | 4 +- lfm/models/d1.mdx | 5 +- 3 files changed, 4 insertions(+), 269 deletions(-) delete mode 100644 .mintlify/skills/decision-model/SKILL.md diff --git a/.mintlify/skills/decision-model/SKILL.md b/.mintlify/skills/decision-model/SKILL.md deleted file mode 100644 index 26c2de45..00000000 --- a/.mintlify/skills/decision-model/SKILL.md +++ /dev/null @@ -1,264 +0,0 @@ ---- -name: decision-model -description: Integrate Liquid AI's d1 decision model or review existing LLM calls for migration to bounded classification, routing, scoring, reranking, and yes/no decisions. Use when the output is a decision over defined outcomes rather than generated text. -metadata: - author: Liquid AI - version: "1.0" - documentation: https://docs.liquid.ai/lfm/models/decision-models ---- - -# Liquid AI Decision Model Skill - -Use Liquid AI's d1 decision model when the output should be a structured decision rather than generated text. Good fits include classification, routing, binary gates, scoring, reranking, triage, moderation, guardrails, LLM-as-judge replacement, agent tool-call approval, and model routing or cascades. - -Use an LLM instead when the task requires free-form text generation, creative writing, multi-turn conversation, complex multi-step reasoning, open-ended Q&A, summarization, or code generation. - -## Setup - -Get an API key from [console.liquid.ai](https://console.liquid.ai): - -1. Register or sign in and join an organization. -2. Go to **Dashboard > API Keys**. -3. Create a key and store it server-side, outside client bundles and logs. Keys are prefixed with `liquid_`. - -Set the key as an environment variable: - -```bash -export LIQUID_API_KEY="liquid_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -``` - -Requests require a Liquid AI API key and HTTPS access to this decision endpoint: - -```text -POST https://api.liquid.ai/decisions/v1/systemone -``` - -## Request Shape - -A decision model call contains: - -- `model`: the decision model to use: `d1` (default, lower cost) or `d1-ultra` (most capable, for harder decisions). Both accept text and images and use the same request and response format. -- `state`: the context to evaluate, supplied as plain text or a JSON object. -- `questions`: one or more typed questions, each with a name, a `type`, and `instructions`. - -Choice questions include `criteria` as an object mapping option names to descriptions. Score questions include `criteria` as an ordered array of rubric descriptions. Noul questions have no criteria. Multiple independent questions can be evaluated in one call against the same state. Use the decision request schema below; this is not a chat-completions endpoint. - -## Primitives - -Every question uses one of three types: - -| If the answer is... | Use | Return shape | -|---|---|---| -| Yes or no, where the probability itself is useful | `noul` | A probability between 0 and 1 | -| One option from an unordered set | `choice` | A selected option, probability distribution, and confidence | -| A rating along an ordered rubric | `score` | A continuous score, probability distribution, legend, and confidence | - -Pick the primitive based on what your code does next. Use Choice when code branches on a category. Use Score when code compares against an ordered threshold. Use Noul when code gates on a boolean probability. - -Noul and Score are different. A Noul value near `0.5` means uncertainty between yes and no; it does not measure degree or intensity. Use Score for degree, severity, skill level, urgency, or similar ordered concepts. - -Score levels are zero-based: an array of four levels produces a continuous score from `0` to `3`, computed as the probability-weighted position on the rubric. Preserve this meaning when replacing a one-based or integer LLM rating; update downstream thresholds or explicitly map the scale. - -## Review and Migration - -When asked to audit a project, trace candidate model calls through their prompts, schemas or parsers, and downstream consumers. Look for enums, booleans, numeric ratings, routing branches, and loops that score retrieved passages. For each candidate, identify the call site, the current output contract, the proposed primitive and criteria, and any required changes to thresholds or fallback behavior. A recommendation request should produce recommendations; implement replacements when the user requests code changes. - -- Classification or routing to one category: use Choice with the labels the caller expects and descriptions that distinguish the options. -- Yes/no checks: use Noul and convert its probability to an action using explicit thresholds. Do not cast a nonzero probability directly to a boolean. -- Ordered severity, priority, quality, or urgency ratings: use Score with clearly defined levels. -- Reranking: evaluate each query/passage pair with Noul for binary relevance or Score for graded relevance, then sort descending. A Choice selects one option; it does not return a ranked list. -- Multiple independent decisions over the same input: combine them into named questions in one request. Keep separate calls when later questions depend on earlier results. - -Keep generation calls for prose, code, summaries, or open-ended answers. In a mixed pipeline, replace only the bounded decision stage. Preserve the application's expected labels and error handling, and compare representative inputs with the existing behavior before switching callers. - -## Reading Decisions - -Read each result from `answers[question_name]`: `.noul` for yes probability, `.choice` for the selected label, or `.score` for the continuous rating. Choice and Score also expose `.probabilities` and `.confidence`; Score includes `.legend` mapping positions to rubric descriptions. - -Treat HTTP or SDK errors as failures, not decisions; preserve the project's bounded retry policy and fallback behavior. - -Use probabilities and confidence to handle ambiguous cases through an application-appropriate fallback. Set thresholds using representative data and the cost of incorrect decisions; example thresholds in the docs are illustrative. A model's tool-call approval verdict is an input to the application's policy, not permission to bypass existing authorization checks. - -## cURL Example - -```bash -curl -s https://api.liquid.ai/decisions/v1/systemone \ - -H "Authorization: Bearer $LIQUID_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "model": "d1", - "state": "I was charged twice for my subscription last month. Please refund the duplicate charge today.", - "questions": { - "route": { - "type": "choice", - "instructions": "Which team should handle this request?", - "criteria": { - "billing": "Charges, payments, and refunds", - "technical": "Product bugs and outages", - "account": "Login and account settings" - } - }, - "urgency": { - "type": "score", - "instructions": "How urgent is this request?", - "criteria": [ - "Routine: no immediate impact", - "Time-sensitive: should handle today", - "Critical: immediate harm or system failure" - ] - }, - "wants_refund": { - "type": "noul", - "instructions": "Does the customer explicitly request a refund?" - } - } - }' -``` - -Example response: - -```json -{ - "model": "d1", - "answers": { - "route": { - "type": "choice", - "choice": "billing", - "probabilities": { - "billing": 0.9997, - "account": 0.0002, - "technical": 0.0001 - }, - "confidence": 0.9996 - }, - "urgency": { - "type": "score", - "score": 1.2, - "confidence": 0.85, - "probabilities": { - "0": 0.05, - "1": 0.70, - "2": 0.25 - }, - "legend": { - "0": "Routine: no immediate impact", - "1": "Time-sensitive: should handle today", - "2": "Critical: immediate harm or system failure" - } - }, - "wants_refund": { - "type": "noul", - "noul": 0.99 - } - }, - "usage": { - "input_tokens": 84, - "output_tokens": 0 - } -} -``` - -Decision models do not generate output tokens, so `usage.output_tokens` is `0`. - -## Python Example - -```bash -pip install typesafe-sdk -``` - -```python -import os -from typesafe_sdk import TypeSafeClient, Choice, Noul, Score - -client = TypeSafeClient( - api_key=os.environ["LIQUID_API_KEY"], - base_url="https://api.liquid.ai", -) - -result = client.system_one( - model="d1", - state="I was charged twice for my subscription last month.", - questions={ - "route": Choice( - instructions="Which team should handle this request?", - criteria={ - "billing": "Charges, payments, and refunds", - "technical": "Product bugs and outages", - "account": "Login and account settings", - }, - ), - "wants_refund": Noul( - instructions="Does the customer explicitly request a refund?", - ), - "urgency": Score( - instructions="How urgent is this request?", - criteria=[ - "Routine: no immediate impact", - "Time-sensitive: should handle today", - "Critical: immediate harm or system failure", - ], - ), - }, -) - -print(result.answers["route"].choice) # "billing" -print(result.answers["route"].confidence) # 0.99 -print(result.answers["wants_refund"].noul) # 0.99 -print(result.answers["urgency"].score) # 1.2 -``` - -## TypeScript SDK - -```bash -npm install @typesafe-ai/sdk -``` - -```typescript -import { TypeSafeClient } from "@typesafe-ai/sdk"; - -const client = new TypeSafeClient({ - apiKey: process.env.LIQUID_API_KEY!, - baseURL: "https://api.liquid.ai", - compression: false, // the API doesn't accept zstd-compressed request bodies -}); - -const result = await client.systemOne({ - model: "d1", - state: "I was charged twice for my subscription last month.", - questions: { - route: { - type: "choice", - instructions: "Which team should handle this request?", - criteria: { - billing: "Charges, payments, and refunds", - technical: "Product bugs and outages", - account: "Login and account settings", - }, - }, - wants_refund: { - type: "noul", - instructions: "Does the customer explicitly request a refund?", - }, - urgency: { - type: "score", - instructions: "How urgent is this request?", - criteria: [ - "Routine: no immediate impact", - "Time-sensitive: should handle today", - "Critical: immediate harm or system failure", - ], - }, - }, -}); - -console.log(result.answers.route.choice); // "billing" -console.log(result.answers.route.confidence); // 0.99 -console.log(result.answers.wants_refund.noul); // 0.99 -console.log(result.answers.urgency.score); // 1.2 -``` - -## References - -- [Decision Models](https://docs.liquid.ai/lfm/models/decision-models): overview, model comparison, primitives, and pricing -- [d1](https://docs.liquid.ai/lfm/models/d1): setup, API examples, image inputs, and response fields -- [Decision Model Guide](https://docs.liquid.ai/guides/decision-model-guide): migration examples from LLM calls to d1 diff --git a/guides/decision-model-guide.mdx b/guides/decision-model-guide.mdx index 15399c90..48586ed7 100644 --- a/guides/decision-model-guide.mdx +++ b/guides/decision-model-guide.mdx @@ -42,10 +42,10 @@ If the answer is one of N known options, use a decision model. If the answer is Install the relevant SDK and configure your client. The LLM examples use the OpenAI SDK, which works with any OpenAI-compatible endpoint. The decision model examples use the [TypeSafe SDK](https://pypi.org/project/typesafe-sdk/) to call the [d1 decision model](/lfm/models/decision-models) through the Liquid AI API. To get an API key, see [d1: Setup](/lfm/models/d1#setup). -For larger migrations, you can hand your coding agent Liquid's decision-model skill before it audits the codebase: +For larger migrations, use the [Liquid d1 agent skill](https://github.com/Liquid4All/liquid-d1-skills) to help your coding agent audit the codebase. Follow [Agent Skills](/lfm/models/d1#agent-skills) for installation instructions, then start a new agent session and try: ```text -Load https://docs.liquid.ai/.well-known/skills/decision-model/skill.md, then inspect this project for generated-text calls that are really bounded decisions. Recommend d1 replacements for classification, routing, scoring, reranking, and yes/no gates. +Use the Liquid d1 skill to inspect this project for generated-text calls that are really bounded decisions. Recommend d1 replacements for classification, routing, scoring, reranking, and yes/no gates. ``` diff --git a/lfm/models/d1.mdx b/lfm/models/d1.mdx index 9134f09c..1ef53c27 100644 --- a/lfm/models/d1.mdx +++ b/lfm/models/d1.mdx @@ -85,11 +85,11 @@ Install the SDK and create a client: -## Agent Skill +## Agent Skills The [Liquid d1 agent skill](https://github.com/Liquid4All/liquid-d1-skills) helps coding agents find opportunities for d1 and integrate it into an application. It can inspect an existing codebase, recommend structured replacements for prompt-and-parse LLM calls, and help design effective Choice, Score, and Noul questions. -Install the skill for the coding agent you use: +Choose one installation method for the coding agent you use: @@ -121,7 +121,6 @@ Use the Liquid d1 skill to inspect this project for generated-text calls that ar The skill includes API and SDK references, guidance for Liquid, Vercel AI Gateway, and OpenRouter, and a dependency-free script for testing requests. Keep `LIQUID_API_KEY` in your environment instead of including it in a prompt. - ## Your First Call A single API call contains the following fields: