docs: position addrkit as a universal address service
- core = address normalization/resolution (universal, no EDDS coupling) - "events by house" (outages) framed as an optional plugin module - README: positioning, API table marks /v1/outages optional, selfcheck section, updated typo numbers and LLM variant-guard note
This commit is contained in:
@@ -1,13 +1,29 @@
|
||||
# addrkit
|
||||
|
||||
**Детерминированный сервис нормализации и поиска адресов** с подключаемым
|
||||
внешним слоем отключений. Разбирает вольные реплики (дроби, литеры, корпуса,
|
||||
строения, опечатки), сопоставляет их с каноническим реестром и отдаёт ответ
|
||||
**только из данных** — LLM не участвует в пути корректности.
|
||||
**Универсальный детерминированный сервис нормализации и поиска адресов.**
|
||||
Разбирает вольные реплики (дроби, литеры, корпуса, строения, опечатки),
|
||||
сопоставляет их с каноническим реестром и отдаёт ответ **только из данных** —
|
||||
LLM не участвует в пути корректности.
|
||||
|
||||
Ядро продукта — **только адрес**: оно не привязано ни к ЕДДС, ни к отключениям.
|
||||
Опциональный модуль «**события по дому**» (отключения, аварии, плановые работы —
|
||||
данные, привязанные к конкретному дому) подключается отдельно; ЕДДС — лишь один
|
||||
из его потребителей.
|
||||
|
||||
Проект на Go, живёт офлайн (один статический бинарь + SQLite), без MCP в
|
||||
рантайме.
|
||||
|
||||
## Позиционирование
|
||||
|
||||
- **Ядро (универсальное):** нормализация, структурирование и поиск адреса по
|
||||
реестру, статусы `found/partial/ambiguous/not_found`, версия данных.
|
||||
Годится для колл-центра, доставки, CRM, аналитики, любого робота.
|
||||
- **Опциональный модуль «события по дому»:** получает канонический адрес из
|
||||
ядра и отдаёт события, **привязанные к этому дому** (совпадение дома, дроби,
|
||||
литеры и корпуса; строение игнорируется). Источник — plug-in
|
||||
(`outages.Source`): сегодня ArcGIS-портал ЕДДС, завтра любой фид (ES, SQL,
|
||||
API). Ядро про события ничего не знает.
|
||||
|
||||
## Зачем
|
||||
|
||||
Существующая логика поиска адреса в диалоговом сценарии страдала от
|
||||
@@ -22,13 +38,13 @@
|
||||
|
||||
```
|
||||
cmd/addrkitd сервис (HTTP)
|
||||
cmd/addrkit CLI: seed | verify | resolve
|
||||
cmd/addrkit CLI: seed | verify | resolve | eval | selfcheck
|
||||
internal/
|
||||
domain/address нормализация и разбор адреса (чистые функции)
|
||||
domain/match сопоставление с индексом, статусы
|
||||
domain/outages выборка отключений по дому (чистая логика)
|
||||
domain/match сопоставление с индексом, статусы ← ядро
|
||||
domain/outages «события по дому»: фильтр по дому ← опциональный модуль
|
||||
adapters/registrystore SQLite (modernc, без CGO)
|
||||
adapters/arcgis клиент портала (timeout/retry)
|
||||
adapters/arcgis клиент источника событий (timeout/retry) ← пример plug-in
|
||||
adapters/llm опциональный rewriter (OpenAI-совместимый)
|
||||
adapters/httpapi версионированный JSON API
|
||||
config конфиг + ${VAR}
|
||||
@@ -41,7 +57,7 @@ internal/
|
||||
"2-я Станционная улица 1/1 стр."
|
||||
-> address.Parse -> {ordinal:2, name:станционная, house:1, frac:1}
|
||||
-> match.Resolve -> exact street -> exact house -> FOUND
|
||||
-> (опц.) outages.Source -> фильтр по дому -> ответ
|
||||
-> (опц. модуль «события по дому») -> фильтр по дому -> ответ
|
||||
```
|
||||
|
||||
## Быстрый старт
|
||||
@@ -66,14 +82,15 @@ CLI без сервиса:
|
||||
```bash
|
||||
./bin/addrkit resolve -db registry.db "кошурникова 11/1"
|
||||
./bin/addrkit verify -db registry.db
|
||||
./bin/addrkit selfcheck -db registry.db
|
||||
```
|
||||
|
||||
## API v1
|
||||
|
||||
| Метод | Путь | Назначение |
|
||||
|---|---|---|
|
||||
| POST | `/v1/resolve` | адрес → `{status, address, district, confidence, candidates[]}` |
|
||||
| POST | `/v1/outages` | адрес → канонический адрес + отключения по дому |
|
||||
| POST | `/v1/resolve` | **[ядро]** адрес → `{status, address, district, confidence, candidates[]}` |
|
||||
| POST | `/v1/outages` | **[опц. модуль]** адрес → канонический адрес + события/отключения по дому |
|
||||
| GET | `/v1/healthz` | живость |
|
||||
| GET | `/v1/readyz` | готовность (индекс загружен) |
|
||||
| GET | `/v1/version` | версия данных |
|
||||
@@ -100,7 +117,12 @@ CLI без сервиса:
|
||||
`partial`, а не «похожий» дом.
|
||||
- **LLM — опция, выключена по умолчанию.** `adapters/llm` лишь предлагает
|
||||
варианты записи адреса; результат всегда берётся из реестра, поэтому модель
|
||||
не может «выдумать» адрес.
|
||||
не может «выдумать» адрес. Вариант принимается только если он исправляет
|
||||
*написание* улицы, не меняя слова, порядковый и дом (`compatibleVariant`).
|
||||
- **Ядро универсально, события по дому — опциональный модуль.** Ядро
|
||||
(`domain/address`, `domain/match`) не знает ни про ЕДДС, ни про отключения;
|
||||
источник событий — plug-in (`outages.Source`), поэтому модуль переиспользуем
|
||||
для любых данных, привязанных к дому.
|
||||
- **Данные.** Сервис владеет своим индексом, построенным из дампа реестра.
|
||||
Источник истины и регламент обновления — предмет отдельного согласования.
|
||||
- **Часовой пояс.** Даты отключений трактуются в `Asia/Novosibirsk` (UTC+7).
|
||||
@@ -145,7 +167,7 @@ ADDRKIT_REGISTRY=/path/to/address_registry.ndjson \
|
||||
| type_front | `улица Станционная 1` | 100 % |
|
||||
| corpus_synonym | `корпус` вместо `к` | 100 % |
|
||||
| structure_drop | без `стр.` | 100 % |
|
||||
| **typo** | опечатка в названии улицы | ~70–75 % (остальное — `ambiguous`) |
|
||||
| **typo** | опечатка в названии улицы | ~78–82 % (остальное — `ambiguous`) |
|
||||
| drop_ordinal / drop_letter / drop_fraction | потеря `2-я` / литеры / дроби | потери (lossy) |
|
||||
|
||||
Ключевой результат: **0 случаев, когда сервис подставил неверный дом**
|
||||
@@ -153,6 +175,23 @@ ADDRKIT_REGISTRY=/path/to/address_registry.ndjson \
|
||||
распознаются, либо честно уходят в `ambiguous`/`not_found`, но не превращаются
|
||||
в чужой адрес.
|
||||
|
||||
С подключённым LLM-rewriter'ом (опция, `llm.enabled`) точность на опечатках
|
||||
поднимается до **~90 %** при том же нуле неверных адресов (вариант модели
|
||||
принимается только если исправляет лишь *написание* улицы — см. «Принятые
|
||||
решения»).
|
||||
|
||||
## Самопроверка (`addrkit selfcheck`)
|
||||
|
||||
Прогоняет **весь** реестр на самого себя (не выборку):
|
||||
|
||||
```bash
|
||||
./bin/addrkit selfcheck -db registry.db
|
||||
```
|
||||
|
||||
На реестре 72 825 записей: **72 811 (99.98 %) резолвятся точно**, 14 — `partial`
|
||||
(битые форматы дома: `27с1`, `32 к 1/4-1/6`, `112с729`), 0 `not_found`,
|
||||
0 неверных.
|
||||
|
||||
## Локальный dev
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user