К основному содержанию
скилл CX Codex

elasticsearch-search-relevance — скилл для Claude Code: релевантность

Скилл для настройки релевантности в Elasticsearch: закрепляет документы через query rules и правит органический ранкинг через multi_match.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add elastic/agent-skills --skill elasticsearch-search-relevance -a claude-code
Открыть на GitHub

Что делает elasticsearch-search-relevance

Скилл разбирает, почему поиск по контенту или каталогу выдаёт плохие результаты, и предлагает один рычаг под задачу. Если конкретный документ обязан быть первым по конкретному запросу — это query rules с правилом типа pinned. Если фразы в целом матчатся слабо — правка органического запроса: multi_match по text-полям из маппинга, бусты коротких полей вроде title^2.

Работает через elastic CLI, а не через прямой HTTP API. Скилл сначала смотрит маппинг и текущий запрос, потом выбирает рычаг, применяет и проверяет топ выдачи. Важная деталь: создание ruleset само по себе ничего не закрепляет — пин срабатывает только когда поисковый запрос содержит rule query с ruleset_id и match_criteria для всех ключей.

Нужен Elasticsearch 8.10 или новее для query rules и elastic CLI версии 0.2 и выше с поддержкой stack es. Кластер — self-managed, Elastic Cloud Hosted или Serverless. Скилл не для ES|QL-аналитики, индексации и здоровья кластера, и не для векторного поиска. Сортировку по цене или дате вместо починки текстовой релевантности он тоже не делает — это повод проверить, ту ли задачу вы вообще решаете.

Какие задачи решает

  • закрепить конкретный товар первым в выдаче по запросу
  • скрыть документ из результатов для заданной фразы
  • починить ранжирование, когда multi_match по одному полю даёт мусор
  • подобрать бусты полей по маппингу индекса
  • проверить, что criteria правила срабатывают до публикации

Примеры запросов агенту

  • Результаты по запросу «sale» плохие, закрепи документ SKU123 первым через query rules
  • Замени одиночный match на multi_match по title и description, title с бустом 2
  • Проверь маппинг индекса catalog и скажи, какие text-поля стоит бустить

Как установить elasticsearch-search-relevance

1Через Skills CLI (Vercel)

npx skills add elastic/agent-skills --skill elasticsearch-search-relevance -a claude-code

2Вручную: положить файлы

~/.claude/skills/elasticsearch-search-relevance/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/elasticsearch-search-relevance/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о elasticsearch-search-relevance

Как установить elasticsearch-search-relevance в Claude?

Выполните npx skills add elastic/agent-skills --skill elasticsearch-search-relevance -a claude-code. После установки файл скилла лежит в ~/.claude/skills/elasticsearch-search-relevance/SKILL.md.

Что делает elasticsearch-search-relevance?

Настраивает релевантность полнотекстового поиска в Elasticsearch: закрепляет или исключает документы через query rules и правит органический ранкинг через multi_match с бустами полей. Перед изменениями смотрит маппинг и текущий запрос.

Что нужно для работы скилла?

Elasticsearch 8.10 или новее для query rules и elastic CLI версии 0.2 и выше с поддержкой stack es. Кластер может быть self-managed, Elastic Cloud Hosted или Serverless.

Исходный текст

SKILL.md · Apache-2.0
---
name: elasticsearch-search-relevance
description: >
  Improve Elasticsearch search relevance for content and catalog indices: pin or promote
  results with query rules (correct rule type, criteria, and rule-query wiring) and
  tune organic ranking with multi_match, field boosts, and analysis grounded in the
  index mapping. Use when search results rank poorly, a specific document must appear
  first for a query, or the user asks to tune full-text matching — not for ES|QL analytics,
  index ingest, or cluster health.
metadata:
  author: elastic
  version: 0.1.0
  universal: true
compatibility: Elasticsearch 8.10 or later (query rules), self-managed, Elastic Cloud
  Hosted, or Elastic Cloud Serverless. Requires the `elastic` CLI ≥ 0.2 with `stack
  es` support.
---

# Elasticsearch Search Relevance

Improve full-text search results on content and catalog indices. Diagnose the mapping and current query, choose the
right relevance lever (query rules for deterministic pinning vs multi_match and field boosts for organic ranking), apply
the change, and verify top hits before reporting success.

<!-- begin-partial: preamble -->

## Environment Configuration

This skill executes Elasticsearch operations through the `elastic` CLI. If the
[`elastic` CLI](https://github.com/elastic/cli#configuration) is not installed, tell the user what it is needed for. Do
not guess credentials, call the HTTP API directly, or attempt other workarounds.

This skill references operations in HTTP-shorthand form (e.g., `GET /`, `GET /_cat/indices`, `GET /{index}/_mapping`,
`GET /{index}/_settings/index.mode`, `POST /_query`). The [Operations](#operations) table at the end of this document
maps each shorthand to the equivalent `elastic` CLI command — always use the CLI rather than calling the HTTP API
directly.

<!-- end-partial: preamble -->

## Scope

This skill covers **Query DSL** relevance on indices with `text` (and optional `keyword`) fields — product catalogs,
documentation, knowledge bases. It uses `POST /{index}/_search` for evaluation and query-rules APIs for pinned or
excluded documents.

Out of scope:

- ES|QL search (`POST /_query`) — use the `elasticsearch-esql` skill.
- Semantic / vector / hybrid retrieval — different field types and retrievers.
- Sorting by price, date, or popularity **instead of** fixing text relevance unless the user explicitly wants
  non-relevance ordering.

## Relevance levers

| User intent                                | Lever                                                       | APIs                                                         |
| ------------------------------------------ | ----------------------------------------------------------- | ------------------------------------------------------------ |
| Always show document X first for query Q   | Query rules — `pinned` rule + `rule` query in search        | `PUT /_query_rules/{ruleset_id}`, `POST /{index}/_search`    |
| Hide specific documents for query Q        | Query rules — `exclude` rule + `rule` query                 | Same                                                         |
| Better ranking for open-ended text queries | `multi_match` across mapped `text` fields with field boosts | `POST /{index}/_search`                                      |
| Tokens not matching user language          | Operator, `minimum_should_match`, or synonym analyzers      | `POST /{index}/_search`, optionally `POST /{index}/_analyze` |

**Decision rule:** If the user names a document that must rank first for a specific query, use query rules. If results
are generally weak for a phrase, tune the organic query from the mapping. Do not simulate pinning with extreme boosts,
`function_score`, or sort clauses.

## Process

1. **Inspect the mapping and current query.** Call `GET /` to confirm connectivity. When the index is unknown, narrow
   candidates with `GET /_cat/indices`, then call `GET /{index}/_mapping`.

   From the mapping, list every `text` field (e.g., `title`, `description`) and every `keyword` field used for filters
   (`brand`, `category`). Note which fields are short (precision) vs long (recall). Read the user's current search body
   if provided — identify which fields it queries and whether it already uses `rule`, `multi_match`, or single-field
   `match`.

   **Decision:** Is the problem **deterministic promotion** (one doc must win for one query) or **organic ranking**
   (several docs should score better)? **Data needed:** index name, mapping properties, current query JSON, example
   query strings, and target document ID(s) when pinning.

2. **Choose the relevance lever.** Apply the decision from step 1:
   - **Pinning / promotion** → Create a query-rules ruleset with a rule of type `pinned` (never `exclude` for
     promotion). Set `criteria` so the rule fires only for the intended query text — e.g., `contains` or `exact` on a
     metadata key such as `query_string` with value `"sale"`. Set `actions` to pin the correct document via `ids` (e.g.,
     `["SKU123"]`) or `docs` (e.g., `[{"_index":"catalog","_id":"SKU123"}]`). Use `docs` when `_id` may not be unique
     across indices. Read [Query Rules Reference](references/query-rules-reference.md) for full structure.

   - **Organic ranking** → Replace single-field `match` on a long field with `multi_match` across the mapped `text`
     fields. Boost short fields (typically `title^2` with `description` unboosted). Consider `operator`,
     `minimum_should_match`, or synonym-aware analyzers when multi-word recall is still poor — but do **not** sort by
     price, date, or keyword fields to fake better text relevance, and do **not** query `.keyword` sub-fields with
     `term` for analyzed user phrases. Read [Multi-Match Tuning](references/multi-match-tuning.md).

   **Decision:** Pick exactly one primary lever per request. **Data needed:** chosen fields and boosts, ruleset ID and
   rule ID names, criteria metadata keys, and pinned document identifiers.

3. **Apply the change.** Execute the APIs for the chosen lever:

   **Query rules path**
   - Create or replace the ruleset with `PUT /_query_rules/{ruleset_id}` (or add one rule with
     `PUT /_query_rules/{ruleset_id}/_rule/{rule_id}`).
   - Confirm structure with `GET /_query_rules/{ruleset_id}`.
   - Validate criteria with `POST /_query_rules/{ruleset_id}/_test` using the same `match_criteria` you will pass at
     search time.
   - **Wire the search:** `POST /{index}/_search` must use a `rule` query whose `ruleset_id` references the ruleset and
     whose `match_criteria` supplies values for every criteria `metadata` key (e.g., `"query_string": "sale"`). Place
     the normal relevance clause inside `organic`. **Creating the ruleset alone does not pin anything** — the pin
     applies only when search includes the `rule` query.

   **Organic tuning path**
   - Build a candidate `multi_match` (or equivalent bool/should) query from the mapping.
   - Optionally inspect analysis with `POST /{index}/_analyze` on sample query text when tokenization explains misses.

   **Decision:** Stop after one coherent change set; avoid stacking unrelated edits before testing.

4. **Test and compare top hits.** Before and after each candidate, call `POST /{index}/_search` with the same `size` (≥
   10), the user's query string, and `"track_scores": true`. For pinning, the search body **must** include the `rule`
   query from step 3.

   Compare for each run:
   - Top `_id` values and order
   - `_score` where relevant
   - Key `_source` fields (`title`, `description`, product id)

   For pinning, confirm the target document (e.g., `SKU123`) is **first** when `match_criteria` matches the query and
   that organic matches still appear below. For organic tuning, confirm titles and intent-aligned documents rise without
   relying on sort or keyword exact-match hacks.

   **Decision:** Ship the candidate that wins on evidence; if none improve results, report what was tried and propose
   the next lever (e.g., synonyms or additional fields). **Data needed:** side-by-side top-hit lists from baseline and
   candidate queries.

## Examples

### Pin SKU123 for query "sale" on `catalog`

**Wrong:** Boost `SKU123`, sort by `_id`, or create a ruleset without a `rule` search query.

**Right:**

1. `PUT /_query_rules/catalog-sale-pin` with a `pinned` rule, criteria matching query text `"sale"`, actions pinning
   `SKU123`.
2. `POST /catalog/_search` with:

```json
{
  "query": {
    "rule": {
      "ruleset_id": "catalog-sale-pin",
      "match_criteria": { "query_string": "sale" },
      "organic": {
        "multi_match": {
          "query": "sale",
          "fields": ["title^2", "description"]
        }
      }
    }
  },
  "size": 10
}
```

Verify `SKU123` is hit #1 and remaining hits are organic matches below the pin.

### Improve "running shoes" when only `description` is searched

Mapping provides `title` and `description` as `text`, plus `brand` and `category` as `keyword`.

**Wrong:** Keep `match` on `description` only; sort by price; `term` query on `title.keyword`.

**Right:**

1. Baseline: `POST /catalog/_search` with the user's current `match` on `description`; record top hits.
2. Candidate: `POST /catalog/_search` with:

```json
{
  "query": {
    "multi_match": {
      "query": "running shoes",
      "fields": ["title^2", "description"],
      "type": "best_fields",
      "operator": "or",
      "minimum_should_match": "75%"
    }
  },
  "size": 10
}
```

1. Compare top hits — documents with "running shoes" in `title` should rank above description-only matches. If recall is
   still thin, consider synonym expansion in a follow-up iteration (not sort-by-price).

## Guidelines

- **Ground every field name in the mapping** — never invent `name`, `content`, or `body` without checking
  `GET /{index}/_mapping`.
- **Query rules for pins, boosts for ranking** — merchandising belongs in query rules; field boosts belong in organic
  queries.
- **Match criteria wiring is mandatory** — `metadata` keys in rule criteria must appear in the search
  `rule.match_criteria` object with the runtime values (typically the user's query string).
- **Test before claiming success** — run baseline and candidate searches; cite top-hit changes.
- **Keyword fields filter; text fields search** — use `keyword` fields in `filter` context, not as the primary full-text
  target for natural language.
- **Always deliver the concrete artifact** — even when you cannot connect to a cluster to verify, produce the full
  ruleset JSON (for pinning) or the candidate query body (for organic tuning), then explain how to verify once the
  connection is available. Never stop at a high-level outline.

## References

- [Query Rules Reference](references/query-rules-reference.md) — criteria types, `pinned` actions, ruleset JSON, `rule`
  query wiring, test API
- [Multi-Match Tuning](references/multi-match-tuning.md) — field boosts, operators, testing discipline, anti-patterns

## Operations

| HTTP API (shorthand)                             | `elastic` CLI command                                                                                                       |
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| `GET /`                                          | `elastic es info`                                                                                                           |
| `GET /_cat/indices`                              | `elastic es cat indices --index '<pattern>'`                                                                                |
| `GET /{index}/_mapping`                          | `elastic es indices get-mapping --index '<index>'`                                                                          |
| `PUT /_query_rules/{ruleset_id}`                 | `elastic es query-rules put-ruleset --ruleset-id '<id>' --rules '<json>'`                                                   |
| `PUT /_query_rules/{ruleset_id}/_rule/{rule_id}` | `elastic es query-rules put-rule --ruleset-id '<id>' --rule-id '<id>' --type pinned --criteria '<json>' --actions '<json>'` |
| `GET /_query_rules/{ruleset_id}`                 | `elastic es query-rules get-ruleset --ruleset-id '<id>'`                                                                    |
| `POST /_query_rules/{ruleset_id}/_test`          | `elastic es query-rules test --ruleset-id '<id>' --match-criteria '<json>'`                                                 |
| `POST /{index}/_search`                          | `elastic es search --index '<index>' --query '<json>'`                                                                      |
| `POST /{index}/_analyze`                         | `elastic es indices analyze --index '<index>' --field '<field>' --text '<text>'`                                            |

© elastic · Apache-2.0 · elastic/agent-skills

Похожие скиллы

Все скиллы по теме «Данные и базы» →
upstash-search-js Upstash Скилл ведёт агента по TypeScript SDK @upstash/search: индексы, документы, keyword, semantic и hybrid-запросы. Пригодится, когда в проект нужно добавить поиск. CX Codex +1 1 200установок reddit-search-api lignertys Скилл даёт модели точную документацию по API сервиса reddapi.dev. Помогает собирать запросы для векторного поиска по Reddit, отслеживать тренды и проверять схемы ответов. CX Codex +1 10 600установок redis-search Redis, Inc. Скилл ведёт агента по Redis Search: схема индекса, типы полей, запросы FT.SEARCH и векторный поиск. Пригодится, когда надо собрать поиск или RAG на Redis. CX Codex +1 1 600установок qdrant-search-quality официальный github Помогает выяснить, почему поиск в Qdrant выдаёт нерелевантные результаты, и выбрать способ улучшить выдачу. Пригодится после смены модели или роста данных. 61установок azure-search-documents-py Microsoft Подсказывает агенту, как писать код для Azure AI Search на Python: векторный и гибридный поиск, семантический ранжинг, индексы. 2установок azure-search-documents-ts Microsoft Скилл для работы с Azure AI Search SDK на JavaScript: индексы, векторный и гибридный поиск, семантический ранкинг. Пригодится, когда агент пишет код поиска по Azure. 1установок

Из того же набора25

elasticsearch-anomaly-detection Скилл настраивает и запускает задачи Elastic ML anomaly detection в Elasticsearch через утилиту elastic CLI. Пригодится для отслеживания всплесков трафика или падений в потоках данных. CX Codex +1 1 000установок elasticsearch-reindex Скилл ведёт агента через reindex в Elasticsearch: подготовка целевого индекса, локальный или удалённый запуск, троттлинг и проверка результата. CX Codex +1 1 000установок elasticsearch-ingest Скилл превращает локальные CSV и JSON в bulk NDJSON и грузит их в Elasticsearch, проверяя маппинги и число документов. CX Codex +1 1 000установок elasticsearch-cluster-health Диагностирует кластер Elasticsearch в жёлтом или красном статусе только в режиме чтения. Находит причину сбоя шардов и предлагает шаги для починки. CX Codex +1 1 000установок observability-service-reliability Помогает выбрать SLI, назначить достижимую цель и вести SLO в Elastic Observability через API Kibana. Пригодится, когда алерты шумят, а бюджет ошибок не сходится. CX Codex +1 1 000установок observability-onboarding Ставит инструментирование EDOT в сервис и проверяет через ES|QL, что трейсы, метрики и логи дошли под нужным именем сервиса. CX Codex +1 1 000установок cloud-onboarding Настраивает контекст elastic CLI и раздаёт доступ в организации Elastic Cloud: приглашения, роли проектов, API-ключи. CX Codex +1 1 000установок cloud-provisioning Создаёт и обслуживает проекты Elastic Cloud Serverless, фильтры трафика и Hosted-развёртывания через elastic CLI. Пригодится, когда нужно поднять проект или ограничить к нему доступ, не уходя из агента. CX Codex +1 1 000установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой