Compare commits

...
5 changed files with 117 additions and 87 deletions
@@ -83,6 +83,73 @@ Only active when `retain_extraction_mode` is `custom`. Replaces the built-in ext
See [Retain configuration](/developer/configuration#retain) for environment variable names and defaults.
### entity_labels {#entity-labels}
Defines a controlled vocabulary of `key:value` classification labels extracted at retain time and stored as entities. Because labels become entities, they automatically link memories in the knowledge graph (two memories with `pedagogy:scaffolding` are linked), improve semantic and BM25 retrieval, and optionally filter memories via the standard `tags`/`tags_match` API when `tag: true` is set on a group.
Each entry in `entity_labels` is a **label group** — one classification dimension:
```json
{
"entity_labels": [
{
"key": "engagement",
"description": "Student engagement level during the session",
"type": "value",
"optional": true,
"values": [
{ "value": "active", "description": "Student is actively participating" },
{ "value": "passive", "description": "Student is listening but not participating" }
]
},
{
"key": "pedagogy",
"description": "Teaching strategies used",
"type": "multi-values",
"values": [
{ "value": "scaffolding", "description": "Breaking complex tasks into smaller steps" },
{ "value": "direct_instruction", "description": "Explicit explanation by the teacher" },
{ "value": "socratic_questioning", "description": "Guiding through questions rather than answers" }
]
}
]
}
```
| Field | Default | Description |
|-------|---------|-------------|
| `key` | — | Label group identifier. Becomes the prefix in `key:value` entities. |
| `description` | `""` | Shown to the LLM to guide label assignment. |
| `type` | `"value"` | `"value"` → pick one enum value; `"multi-values"` → pick multiple; `"text"` → free-form string. |
| `values` | `[]` | Allowed values for `"value"` and `"multi-values"` types. Ignored for `"text"`. |
| `optional` | `true` | When `true` the LLM may skip the label if not applicable. When `false` the LLM must always assign a value. Has no effect on `"multi-values"` groups (always optional). |
| `tag` | `false` | When `true`, extracted `key:value` labels are also written as tags on the memory unit, enabling filtering via `tags`/`tags_match` in recall/reflect. |
**Enum groups** (`type: "value"` or `type: "multi-values"`): the LLM picks from the predefined `values` list; anything outside the list is silently dropped. Vocabulary stays stable and graph links stay tight. Use `"multi-values"` when a fact can belong to several values at once.
**Free-text groups** (`type: "text"`): the LLM writes any string. Use the `description` field to provide examples and guidance. Graph clustering is less reliable than with enum groups because the model may phrase the same concept differently across sessions.
```json
{
"key": "topic",
"description": "Specific subject being discussed. Examples: algebra, quadratic equations, geometry.",
"type": "text",
"optional": true,
"values": []
}
```
### entities_allow_free_form
By default, entity labels are extracted **alongside** regular named entities (people, places, concepts). Set to `false` to disable free-form extraction so only label entities are stored:
```json
{
"entity_labels": [...],
"entities_allow_free_form": false
}
```
### enable_observations {#observations-configuration}
Toggles automatic observation consolidation on or off. Defaults to `true` when the observations feature is enabled on the server.
+6
View File
@@ -26,6 +26,12 @@ Hindsight works with any provider that exposes an OpenAI-compatible API (e.g., A
See [Configuration](./configuration#llm-provider) for setup examples.
:::
### Benchmarks
Not sure which model to use? The **[Model Leaderboard](https://benchmarks.hindsight.vectorize.io/)** benchmarks models across accuracy, speed, cost, and reliability for retain, reflect, and observation consolidation so you can pick the right trade-off for your use case.
[![Model Leaderboard](/img/leaderboard.png)](https://benchmarks.hindsight.vectorize.io/)
### Tested Models
The following models have been tested and verified to work correctly with Hindsight:
+6 -84
View File
@@ -90,6 +90,12 @@ The same entity mentioned different ways gets unified:
If "Alice" appears with "Google" and "Stanford" multiple times, a new "Alice" mentioning those is likely the same person. Hindsight uses co-occurrence patterns to disambiguate common names.
### Entity Labels
You can define a controlled vocabulary of `key:value` classification labels (e.g. `pedagogy:scaffolding`, `engagement:active`) that are extracted at retain time and stored as entities. Because labels become entities, they automatically link related memories in the knowledge graph and improve both semantic and keyword retrieval. Labels can optionally also write to the memory unit's tags, enabling standard tag-based filtering during recall and reflect.
See [entity_labels in the bank config](/developer/api/memory-banks#entity-labels) for full configuration details.
---
## Building Connections
@@ -199,90 +205,6 @@ Set `retain_mission` and `retain_extraction_mode` via the [bank config API](/dev
---
## Entity Labels
**Entity labels** let you define a controlled vocabulary of classification labels that are extracted at retain time and stored as entities alongside regular named entities. Each label takes the form `key:value` (e.g. `pedagogy:scaffolding`, `engagement:active`).
Because labels become entities, they automatically:
- Appear in the **knowledge graph** — two memories with `pedagogy:scaffolding` are linked
- Improve **semantic and BM25 retrieval** — label strings are included in both the dense embedding and the sparse `text_signals` field
- Support **labels-only mode** — optionally disable free-form entity extraction so only labels are stored
Labels are configured per bank via `entity_labels` in the bank config.
### Defining Label Groups
Each label group defines one classification dimension:
```json
{
"entity_labels": [
{
"key": "engagement",
"description": "Student engagement level during the session",
"type": "value",
"optional": true,
"values": [
{ "value": "active", "description": "Student is actively participating" },
{ "value": "passive", "description": "Student is listening but not participating" }
]
},
{
"key": "pedagogy",
"description": "Teaching strategies used",
"type": "multi-values",
"values": [
{ "value": "scaffolding", "description": "Breaking complex tasks into smaller steps" },
{ "value": "direct_instruction", "description": "Explicit explanation by the teacher" },
{ "value": "socratic_questioning", "description": "Guiding through questions rather than answers" }
]
}
]
}
```
| Field | Default | Description |
|-------|---------|-------------|
| `key` | — | Label group identifier. Becomes the prefix in `key:value` entities. |
| `description` | `""` | Shown to the LLM to help it assign the right label. |
| `type` | `"value"` | `"value"` → single enum value; `"multi-values"` → multiple enum values; `"text"` → free-form string. |
| `values` | `[]` | Allowed values for `"value"` and `"multi-values"` types. Ignored for `"text"` type. |
| `optional` | `true` | `true` → the LLM may skip this label if not applicable (default). `false` → LLM must always assign a value. Has no effect on `"multi-values"` groups (always optional). |
| `tag` | `false` | `true` → also write extracted `key:value` entities as tags on the memory unit, enabling filtering via the standard `tags`/`tags_match` API parameters. |
### Enum vs Free-text Labels
**Enum groups** (`type: "value"` or `type: "multi-values"`): the LLM must pick from the predefined `values` list. Values not in the list are silently dropped. This is the most reliable option — the vocabulary is stable and graph clustering is tight. Use `"multi-values"` when a single fact can match multiple values.
**Free-text groups** (`type: "text"`): the LLM can write any string value. The `values` field is ignored — use the `description` to provide examples and guidance instead.
```json
{
"key": "topic",
"description": "The specific subject being discussed. Examples: algebra, geometry, quadratic equations.",
"type": "text",
"optional": true,
"values": []
}
```
The trade-off with free-text: the LLM may use different phrasings for the same concept across sessions (`topic:fractions` vs `topic:fraction arithmetic`), so graph linking is less reliable than with enum groups.
### Labels-only Mode
By default, entity labels are extracted **alongside** regular named entities (people, places, concepts). Set `entities_allow_free_form: false` to disable free-form extraction and store only label entities:
```json
{
"entity_labels": [...],
"entities_allow_free_form": false
}
```
Configure both via the [bank config API](/developer/api/memory-banks#retain-configuration).
---
## Observation Consolidation
After `retain()` completes, Hindsight automatically triggers **observation consolidation** in the background. This process:
+38 -3
View File
@@ -1,7 +1,7 @@
---
title: Frequently Asked Questions
description: Common questions and answers about Hindsight
hide_table_of_contents: true
hide_table_of_contents: false
---
# Frequently Asked Questions
@@ -67,6 +67,16 @@ Configure your provider using the `HINDSIGHT_API_LLM_PROVIDER` environment varia
---
### Which model should I use with Hindsight?
The **[Model Leaderboard](https://benchmarks.hindsight.vectorize.io/)** benchmarks models across accuracy, speed, cost, and reliability for retain, reflect, and observation consolidation — it's the best place to find the right trade-off for your use case.
[![Model Leaderboard](/img/leaderboard.png)](https://benchmarks.hindsight.vectorize.io/)
See [Models](/developer/models) for the full list of supported and tested models, provider defaults, and configuration examples.
---
### Do I need to host my own infrastructure?
No! You have two options:
@@ -110,7 +120,8 @@ There are two approaches for multi-user applications:
Choose per-user banks for simplicity and privacy, or single bank with tags if you need holistic reasoning across users. See [Memory Banks](/developer/api/memory-banks) for management details.
---
---
### What's the difference between retain, recall, and reflect?
Hindsight has three core operations:
@@ -174,7 +185,7 @@ Typical latencies:
See [Performance](/developer/performance) for tuning options.
---
### Does Hindsight support metadata filtering?
@@ -193,6 +204,30 @@ client.recall(bank_id="my-bank", query="...", tags=["user:alice"])
See [Tags](/developer/api/retain#tags-and-document_tags) for full details including document-level tagging.
**What about filtering by entities?**
Entities (people, places, concepts) extracted from memories are stored in the knowledge graph and drive graph-based retrieval — so querying "tell me about Alice" will naturally surface Alice-related memories without any manual filtering.
If you need explicit tag-based filtering on entity-like values, use **entity labels** with `tag: true`. Entity labels let you define a controlled vocabulary of `key:value` classifiers (e.g. `user:alice`, `topic:algebra`) extracted at retain time. Setting `tag: true` on a label group automatically writes each extracted label as a tag on the memory unit, making them available for standard `tags`/`tags_match` filtering:
```python
# Bank config: entity label group with tag: true
{
"entity_labels": [{
"key": "user",
"type": "text",
"tag": True,
"description": "The user this memory belongs to"
}]
}
# The label "user:alice" is extracted and also written as a tag
# Filter at recall time using the standard tags parameter
client.recall(bank_id="my-bank", query="...", tags=["user:alice"])
```
See [Entity Labels](/developer/retain#entity-labels) for configuration details.
**What about document `metadata`?**
Document metadata (the `metadata` key-value pairs on a retain item) serves a different purpose. It is:
Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB