Intent detection · Developer docs
zeroproof-ecommerce-1b reads a payment-assistant conversation and returns one JSON verdict: the intent type, typed details, confidence, and the supporting messages. Hosted warm, with an MCP tool for agents and an OpenAI-compatible API for everything else.
The model classifies a conversation into one of seven intent types and fills a typed details object for that intent.
Open weights. The model and its evaluation set are on Hugging Face under zero-proof-ai; the hosted endpoint serves the same weights.
The recommended route for agents. Both routes need a bearer key; request one at jacob@zeroproofai.com. The server applies the model’s trained prompt format for you; pass only the raw conversation to the detect_payment_intent tool.
claude mcp add --transport http zeroproof-intent \
https://zeroproofai--zeroproof-intent-vllm-mcp.modal.run/mcp \
--header "Authorization: Bearer $API_KEY"detect_payment_intent({
"messages": [
{ "role": "user", "content": "cancel my hulu subscription, its 17.99 a month", "seq": 0 }
]
})
// -> { "intent_detected": true, "core_type": "recur",
// "details": { "action": "cancel", "merchant": "Hulu", "amount": 17.99, ... },
// "confidence": 0.95, "reason": "...", "source_message_seqs": [0] }The same model behind the standard Chat Completions API. You must reproduce the trained prompt format exactly; it is not a general chat model. The system prompt and per-intent schemas ship with the model on Hugging Face. If you cannot reproduce the format, use the MCP route.
from openai import OpenAI
client = OpenAI(
base_url="https://zeroproofai--zeroproof-intent-vllm-serve.modal.run/v1",
api_key=API_KEY,
)
resp = client.chat.completions.create(
model="zeroproof-intent",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_prompt(conversation)},
],
max_tokens=512,
temperature=0,
)
verdict = json.loads(resp.choices[0].message.content)The response is a single JSON object with no markdown fencing; treat a parse failure as a signal that your prompt format is wrong.
Every response has the same shape. The details object is typed per intent, with explicit nulls for unknown fields. Missing details alone never make a conversation none; that label is reserved for genuine non-intent such as browsing, questions, or status checks.
{
"intent_detected": true,
"core_type": "spend",
"details": {
"product_name": "Sony WH-1000XM5",
"quantity": 1,
"total_amount": 348,
"currency": "USD",
"color": "black",
"...": null
},
"confidence": 0.9,
"reason": "User confirmed and authorized the purchase.",
"source_message_seqs": [0, 2]
}This is the short reference. The full guide, with the prompt contract and every behavior note, is the skill above. Hand it to your coding agent.
The current 1B release (v2) was trained on 17,144 conversations and evaluated on the same 1,977-conversation held-out set used for v1. It improves overall routing and the weakest intent classes.
| Measure | v1 | v2 | Change |
|---|---|---|---|
| Intent detection | 71.5% | 80.7% | +9.2 |
| Intent type | 65.9% | 75.3% | +9.4 |
| Intent details | 65.1% | 66.3% | +1.2 |
| Bill | 57.1% | 71.8% | +14.7 |
| Recurring payment | 67.5% | 78.5% | +11.0 |
Points, macro-averaged. Same held-out set across versions.