Skip to main content

Overview

folksbase uses Anthropic’s Claude Haiku model in exactly two places:
  1. Column mapping suggestions during CSV import — the AI looks at your CSV headers and sample data, then suggests which contact field each column maps to
  2. Import summary generation — after processing completes, the AI generates a human-readable summary of what was imported
Both uses follow the same principle: AI enhances the experience but never blocks it. If the AI is unavailable, the feature degrades gracefully and the user can continue without interruption.

Column Mapping

When you upload a CSV, the system sends the headers and first two sample rows to Claude Haiku with a focused prompt:
You map CSV headers to contact fields. Reply ONLY with valid JSON, no markdown.
Return a flat JSON object where each key is the EXACT original CSV header
and each value is one of: email | first_name | last_name | phone | company | notes | null
Use null if unsure.
The AI returns something like:
{
  "Email Address": "email",
  "First": "first_name",
  "Last": "last_name",
  "Mobile": "phone",
  "Organization": "company",
  "Random Column": null
}

Confidence Scoring

Each suggestion gets a confidence score (high or low) based on how closely the header name matches the field name:
  • High confidence — the normalized header contains the field name, or the Levenshtein distance is less than 3 (e.g., “Email” → email, “fname” → first_name)
  • Low confidence — the AI suggested a mapping but the names don’t closely match, or the AI returned null
The UI uses confidence scores to visually distinguish strong matches from uncertain ones, helping users quickly spot mappings that need manual adjustment.

Response Parsing

The AI sometimes returns nested objects or changes header casing. The parser handles this by:
  1. First checking if top-level keys match the CSV headers (case-insensitive)
  2. If not, searching nested objects for one whose keys overlap with the headers
  3. Building a case-insensitive lookup to map AI response keys back to original headers
This makes the system resilient to variations in AI output format.

Caching

Column mapping results are cached in Redis for 1 hour. The cache key is a SHA-256 hash of the sorted headers, versioned with a v2 prefix. This means:
  • Uploading the same CSV structure twice hits the cache
  • Different column orders produce the same cache key (headers are sorted)
  • Cache version can be bumped if the prompt or model changes

Graceful Fallback

This is the most important design decision in the AI integration. Every AI call is wrapped in a try/catch that returns a fallback value instead of throwing:
try {
  const result = await callAnthropic(...)
  await redis.setex(cacheKey, 3600, JSON.stringify(result))
  return result
} catch (error) {
  logger.error('AI call failed, using fallback', { error, context })
  return fallbackValue  // never throw
}

What the fallbacks look like

FeatureFallback behavior
Column mappingReturns all headers mapped to null with low confidence — user maps everything manually
Import summaryUses a static fallback string instead of an AI-generated summary

Timeout Protection

Both AI call sites use AbortSignal.timeout(10_000) (10 seconds). If the Anthropic API is slow or unresponsive, the request aborts after 10 seconds and the fallback kicks in. This prevents background job steps from hanging indefinitely.

Why Claude Haiku?

The model choice is intentional:
  • Speed — Haiku responds in under a second for this use case, keeping the upload flow snappy
  • Cost — column mapping is a simple classification task that doesn’t need a larger model
  • Reliability — the fast response time means timeouts are rare in practice
The model is pinned to claude-3-haiku-20240307. Upgrading to a different model should be tested against the existing prompt and response parsing logic, since different models may format JSON responses differently.