> For the complete documentation index, see [llms.txt](https://docs.telys.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.telys.ai/tuning/tuner-and-plan.md).

# Tuner & plans

A **Tuner** inspects a collection and a workload and emits a **TuningPlan** — a serializable description of the recall target, exact-search crossover, and IVF layout to apply. `Tuner` and `TuningPlan` are top-level imports; the concrete tuners resolve from the signed native runtime or an optional adapter.

```python
from telys import Tuner, TuningPlan
```

## `Tuner` (base class)

`Tuner` is the abstract interface every tuner implements. It defines the contract but computes no plans — `tune_collection` raises `NotImplementedError`.

| Attribute / method | Signature                                                                   | Description                                                                                                                                                                    |
| ------------------ | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`             | `str` — `"base"`                                                            | Identifier recorded on plans produced by this tuner.                                                                                                                           |
| `mode`             | `str`                                                                       | How `Collection.tune(dry_run=None)` behaves. When it equals `"suggest_then_apply"`, a `None` dry-run applies the plan automatically; otherwise a `None` dry-run only suggests. |
| `tune_collection`  | `tune_collection(collection, workload=None, objectives=None) -> TuningPlan` | Build a plan for `collection` under an optional `workload` and `objectives`. **Base raises `NotImplementedError`** — use a concrete tuner.                                     |
| `choose_plan`      | `choose_plan(stats, query)`                                                 | Query-time hook: pick search parameters given current collection `stats` and a query. Primarily overridden by runtime tuners.                                                  |
| `explain`          | `explain()`                                                                 | Return a description of the strategy this tuner uses to make its decisions.                                                                                                    |

`workload` and `objectives` are free-form inputs a concrete tuner interprets — for example a sample of representative queries, or a latency/recall objective. The base accepts them for interface stability.

## Bundled tuners

You rarely construct `Tuner` directly. Two concrete implementations exist, both **outside** the runtime-free SDK:

{% tabs %}
{% tab title="HeuristicTuner" icon="wand-magic-sparkles" %}
The default, dependency-free tuner. Listed in `telys.__all__`, it resolves **lazily** from the signed native runtime.

```python
from telys import HeuristicTuner   # ImportError without the runtime installed
```

It sizes the IVF and picks nprobe from collection statistics and your recall target — no query sample or training required.

{% hint style="warning" %}
On a runtime-free install this import raises `ImportError`. Install and verify the runtime first: `telys runtime install` then `telys runtime verify`.
{% endhint %}
{% endtab %}

{% tab title="AlgentaTuner" icon="chart-line" %}
An optional, workload-aware tuner in the separate `telys-algenta` adapter — **not** part of the `telys` package.

```python
from telys_algenta import AlgentaTuner   # provided by the telys-algenta adapter
```

It fits parameters to a supplied `workload` (representative queries), matching your access pattern more tightly than the heuristic default.
{% endtab %}
{% endtabs %}

Attach a tuner when you create a collection, so `col.tune()` knows which one to run:

```python
from telys import Telys, HeuristicTuner   # HeuristicTuner needs the runtime

db = Telys("$TELYS_HOME/store")
col = db.create_collection("notes", dim=384, partition_by="scope", tuner=HeuristicTuner())
```

## `TuningPlan`

A dataclass recording a tuning decision. Every field is a plain attribute; it carries no engine handles and is safe to log, diff, and serialize.

```python
TuningPlan(
    collection,             # str  — name of the collection the plan targets
    tuner,                  # str  — name of the tuner that produced it
    target_recall,          # float — recall the plan aims for (e.g. 0.98)
    exact_crossover_rows,   # int  — below this row count a partition searches exactly
    ivf,                    # dict — chosen IVF layout (e.g. cell count, nprobe)
    expected,               # dict — predicted metrics (p50/p95 ms, recall_at_k, fallback_rate)
    constraints,            # dict — bounds the tuner honored (latency/recall/memory)
    decision_trace,         # list — ordered, human-readable reasoning steps
    workload_hash="",       # str  — fingerprint of the workload the plan was fit to
    engine="telys",         # str  — engine identifier
    plan_id="",             # str  — stable id; auto-filled as "tune_<hash>" when empty
)
```

### Fields

| Field                  | Type    | Meaning                                                                                                 |
| ---------------------- | ------- | ------------------------------------------------------------------------------------------------------- |
| `collection`           | `str`   | Name of the collection this plan targets.                                                               |
| `tuner`                | `str`   | `name` of the tuner that produced the plan.                                                             |
| `target_recall`        | `float` | Recall the plan aims for; becomes `default_target_recall` when applied.                                 |
| `exact_crossover_rows` | `int`   | Row count below which a partition keeps exact (brute-force) search.                                     |
| `ivf`                  | `dict`  | Chosen IVF layout — for example the number of cells and the nprobe to scan.                             |
| `expected`             | `dict`  | Predicted post-apply metrics (for example `p50` / `p95` latency in ms, `recall_at_k`, `fallback_rate`). |
| `constraints`          | `dict`  | The latency / recall / memory bounds the tuner was asked to honor.                                      |
| `decision_trace`       | `list`  | Ordered, readable steps explaining how the tuner arrived at the plan.                                   |
| `workload_hash`        | `str`   | Fingerprint of the workload the plan was fit to (empty when none was supplied).                         |
| `engine`               | `str`   | Engine identifier; defaults to `"telys"`.                                                               |
| `plan_id`              | `str`   | Stable identifier; auto-filled as `"tune_<hash>"` when left empty.                                      |

### Methods

| Method          | Returns | Description                                                                                           |
| --------------- | ------- | ----------------------------------------------------------------------------------------------------- |
| `as_dict()`     | `dict`  | The plan as a plain dictionary — every field, ready to log or compare.                                |
| `to_json(**kw)` | `str`   | JSON string of the plan; keyword arguments pass through to the JSON encoder (for example `indent=2`). |

```python
plan = col.tune()                 # returns a TuningPlan
print(plan.plan_id, plan.tuner)   # e.g. tune_9f2a1c  heuristic
print(plan.expected["p95"])       # predicted p95 latency, ms
print(plan.to_json(indent=2))     # pretty-print the whole plan
```

{% hint style="info" %}
There is **no** `TuningPlan.save`. A plan is a description, not persistent state. Apply it with `col.apply_tuning(plan)`, then persist with `col.save()`, which stores `default_target_recall` and `applied_tuner`.
{% endhint %}

## See also

* [Run a tuning pass](/tuning/running-a-pass.md) — produce a plan with `col.tune()`.
* [Apply & save a plan](/tuning/apply-and-save.md) — write a plan's settings onto the collection.
* [Tuner & TuningPlan API](/reference/tuner-api.md) — the same surface in the full API reference.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.telys.ai/tuning/tuner-and-plan.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
