Pre-launchJoin the waitlist
Taste ClosetKOEN
Technology · engineering notes

How Taste Closet is built on Claude.

Working notes from Purify Solution. The product is in development; anything not built yet is marked planned.

Tool schemas

Look planning and shopping checks run as a Claude tool-use loop. The model can only choose item IDs returned by search_closet (or, later, search_catalog), and every candidate goes through deterministic checks.

tools.json
[
  {"name": "tag_garment",
   "description": "Vision: tag one garment photo into the Garment schema.",
   "input_schema": {"type": "object",
     "properties": {"image_id": {"type": "string"}},
     "required": ["image_id"]}},
  {"name": "search_closet",
   "description": "Find the user's own items matching filters.",
   "input_schema": {"type": "object", "properties": {
     "category": {"enum": ["top","bottom","outer","dress","shoes","bag","accessory"]},
     "season":   {"enum": ["spring","summer","autumn","winter"]},
     "formality_min": {"type": "integer", "minimum": 1, "maximum": 5},
     "formality_max": {"type": "integer", "minimum": 1, "maximum": 5},
     "colors": {"type": "array", "items": {"type": "string"}},
     "exclude_ids": {"type": "array", "items": {"type": "string"}}}}},
  {"name": "get_weather",
   "description": "Hourly forecast for a city and date.",
   "input_schema": {"type": "object", "properties": {
     "city": {"type": "string"}, "date": {"type": "string", "format": "date"}},
     "required": ["city", "date"]}},
  {"name": "score_outfit",
   "description": "Deterministic rule checks for a candidate look.",
   "input_schema": {"type": "object", "properties": {
     "item_ids": {"type": "array", "items": {"type": "string"}},
     "temp_c": {"type": "number"}, "occasion_formality": {"type": "integer"}},
     "required": ["item_ids"]}},
  {"name": "check_fit",
   "description": "Compare an item's size chart and silhouette with the user's sizes.",
   "input_schema": {"type": "object", "properties": {
     "item_ref": {"type": "string"}, "size": {"type": "string"}},
     "required": ["item_ref"]}},
  {"name": "check_color_harmony",
   "description": "Score a color against owned items; returns matching item IDs.",
   "input_schema": {"type": "object", "properties": {
     "hex": {"type": "string", "pattern": "^#[0-9a-f]{6}$"}},
     "required": ["hex"]}},
  {"name": "check_budget",
   "description": "Compare a price with the user's budget for the category.",
   "input_schema": {"type": "object", "properties": {
     "price_krw": {"type": "integer"}, "category": {"type": "string"}},
     "required": ["price_krw", "category"]}}
]
planned tools
// Planned, not built yet
search_catalog(season | item_type, filters)  -> candidate items from partner/affiliate catalogs
get_calendar_context(date)                   -> occasions + formality hints

Garment JSON schema

Vision tagging uses structured outputs against this schema. Responses that fail validation are retried once with the validator errors attached, then shown to the user to fix by hand.

garment.schema.json
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Garment",
  "type": "object",
  "required": ["category", "subcategory", "colors", "pattern",
               "material", "fit", "seasons", "formality", "confidence"],
  "properties": {
    "category":    {"enum": ["top","bottom","outer","dress","shoes","bag","accessory"]},
    "subcategory": {"type": "string", "maxLength": 40},
    "colors": {
      "type": "array", "minItems": 1, "maxItems": 3,
      "items": {"type": "object",
                "properties": {"name": {"type": "string"},
                               "hex": {"type": "string", "pattern": "^#[0-9a-f]{6}$"},
                               "share": {"type": "number"}}}
    },
    "pattern":   {"enum": ["solid","stripe","check","dot","floral","graphic","other"]},
    "material":  {"type": "string"},
    "fit":       {"enum": ["slim","regular","relaxed","oversized","n/a"]},
    "silhouette": {"enum": ["straight","tapered","wide","a-line","boxy","fitted","n/a"]},
    "seasons":   {"type": "array", "items": {"enum": ["spring","summer","autumn","winter"]}},
    "formality": {"type": "integer", "minimum": 1, "maximum": 5},
    "mood_tags": {"type": "array", "maxItems": 6, "items": {"type": "string"}},
    "confidence": {"type": "number", "minimum": 0, "maximum": 1}
  },
  "additionalProperties": false
}

Taste profile JSON schema

Seeded by the onboarding quiz, then updated from likes, dislikes, saved looks and direct edits.

taste_profile.schema.json
{
  "title": "TasteProfile",
  "type": "object",
  "required": ["styles", "palette", "fit", "sizes", "budget_krw"],
  "properties": {
    "styles":  {"type": "array", "items": {"type": "object",
                "properties": {"tag": {"type": "string"},
                               "weight": {"type": "number", "minimum": 0, "maximum": 1}}}},
    "palette": {"type": "array", "maxItems": 8,
                "items": {"type": "string", "pattern": "^#[0-9a-f]{6}$"}},
    "avoid":   {"type": "array", "items": {"type": "string"}},
    "fit":     {"type": "object", "properties": {
                "tops": {"enum": ["slim","regular","relaxed","oversized"]},
                "bottoms": {"enum": ["straight","tapered","wide"]}}},
    "sizes":   {"type": "object", "properties": {
                "top": {"type": "string"}, "bottom_waist_cm": {"type": "number"},
                "shoe_mm": {"type": "integer"}}},
    "formality_range": {"type": "array", "items": {"type": "integer"}, "minItems": 2, "maxItems": 2},
    "budget_krw": {"type": "object", "additionalProperties": {"type": "integer"}},
    "source": {"enum": ["quiz", "feedback", "user_edit"]}
  }
}

Validation rules

  • Existence: every item ID must belong to the user's closet (or the candidate catalog result).
  • Slots: at most one item per slot (top, bottom or dress, outer, shoes); outer required below a temperature threshold.
  • Weather fit: seasons and warmth must suit the forecast; rain excludes suede and canvas shoes.
  • Formality: each item within ±1 of the occasion's formality level.
  • Color harmony: neutral base, at most one high-saturation accent, rule-based palette check.
  • Shopping checks: fit vs the user's sizes and silhouettes, material vs preferences and season, color vs owned items, mood vs style profile, price vs budget. All five are reported; failures are shown, never hidden.
  • Freshness: avoid repeating the same top within the user's chosen window.

Model routing

TaskModel tierWhy
Garment tagging (vision)Smaller, faster Claude modelHigh volume, narrow schema, easy to evaluate
Quick swapsSmaller modelConstrained search inside a known look
Taste & closet analysisLarger Claude modelInterpretation across the whole closet
Daily, situation and capsule looksLarger modelMulti-step tool use and trade-offs
Shopping verification (planned)Larger model + deterministic checksChecks in code; model explains trade-offs

Prompt caching

The system prompt, tool definitions, the taste profile and a compact JSON summary of the user's closet form a stable prefix marked for prompt caching. Per-request inputs (date, weather, situation, shopping query) come after it. The cache is invalidated when the closet or taste profile changes.

Evaluation plan

EvalMetricStatus
Tagging accuracy vs human labelsPer-field accuracy (category, pattern, fit, formality); color matchIn progress
Schema validityShare of tagging responses valid on first tryIn progress
Outfit rule checksPass rate on weather fit, formality, color harmonyPlanned
Situation looksHuman rating on a fixed set of situation promptsPlanned
Shopping verificationCheck agreement with human judgment on fit, color, pricePlanned
Grounded explanationsReasons consistent with tool resultsPlanned
Cost and latencyTokens, cache hit rate, p50/p95 latency per routePlanned

No results are published yet; no metrics are claimed on this site.

Privacy of user photos

When the app launches, closet photos are planned to be processed by the Claude API for tagging, and we plan to keep the structured tags rather than the photos wherever possible. Today the website collects only waitlist sign-ups. See the privacy page.

How we build

Taste Closet is developed with Claude Code. This site is static and hosted on Cloudflare Pages.