---
title: "Set a similarity threshold"
lesson_id: "03"
---

# Set a similarity threshold

- **Lesson ID:** 03
- **Goal:** Store cache rows and accept a hit only above a high cosine threshold.
- **Human lesson:** [03-similarity-and-threshold.html](03-similarity-and-threshold.html)

## Prerequisites

- Lesson 02 embedder with a fixed dimension.

## Inputs, outputs, and artifacts

- **Inputs:** New question vector, in-memory rows, threshold, now date.
- **Outputs:** Optional matching row, or nil on miss or expiry.

## Agent build steps

1. Define a row with question, answer, embedding, createdAt, and optional expiresAt.
2. Implement cosine similarity with a matching-length precondition.
3. Start the threshold near 0.90 to 0.94.
4. Filter expired rows before scoring.
5. Say a miss that generates is better than a wrong hit.

## Constraints

No vector database required. No em dashes. iOS 27 and macOS 27.

## Key concepts

- Store embedding, question, answer, created time, and optional expiry as a cache row.
- Score with cosine similarity and gate on a minimum threshold.
- Start high, around 0.90 to 0.94. Lower only after you read misses.
- Time-sensitive rows need an expiry.

## Takeaways

- A miss that generates beats a hit that lies.
- A few hundred in-memory rows is enough for a first ship.
- A low threshold can look like a high hit rate while serving wrong answers.

## Acceptance checks

- Cosine is implemented in the lesson.
- Threshold starts high.
- Expiry is shown.
- Agent brief link is present.
