TL;DR
Semantic Prompts — техника, которая заставляет embedding модели (OpenAI, Cohere, Voyage, open-source) правильно обрабатывать отдельные слова. Вместо голого слова "собака" передаёшь промпт "meaning: собака" или "Represent the semantic concept: собака". Модель получает семантический контекст и генерирует качественный эмбеддинг.
Embedding модели обучены на предложениях для задач типа поиска и семантического сходства. Когда им скармливают одно слово — они теряются. Voyage-3 вообще выдаёт случайные эмбеддинги для голых слов (корреляция с человеческими оценками ≈ 0). Другие модели работают, но плохо: OpenAI text-embedding-3-small показывает корреляцию 0.50 вместо потенциальных 0.67. Причина: одиночное слово — это out-of-distribution для модели, обученной на полных предложениях. Плюс токенизация: "собака" и " собака" (с пробелом) могут кодироваться по-разному в зависимости от архитектуры токенизатора.
Добавь короткий семантический промпт перед словом — и корреляция взлетает на +0.04..+0.29 для хороших моделей и на +0.73 для моделей, которые проваливались. Промпты типа "Represent the semantic concept: {слово}" работают лучше всего — они дают модели явный сигнал создать лексически значимое представление, а не просто закодировать токен.
Схема метода
Один шаг: Оберни слово в семантический промпт перед запросом эмбеддинга
Вместо: get_embedding("интеграция")
Делай: get_embedding("meaning: интеграция")
Или для API:
Вместо: ["интеграция", "биллинг", "API"]
Делай: ["meaning: интеграция", "meaning: биллинг", "meaning: API"]
Пример применения
Задача: Ты строишь семантический поиск для базы знаний техподдержки российского SaaS (типа amoCRM или Битрикс24). Пользователи ищут по коротким запросам — "интеграция", "API", "тариф", "экспорт". Embedding модель должна найти похожие статьи, но на голых словах выдаёт нерелевантные результаты или вообще случайные совпадения.
Без промпта:
terms = ["интеграция", "API", "биллинг", "экспорт"]
embeddings = [get_embedding(term) for term in terms]
# Результат: плохое качество поиска, модель не понимает семантику терминов
С промптом:
terms = ["интеграция", "API", "биллинг", "экспорт"]
prompted = [f"meaning: {term}" for term in terms]
embeddings = [get_embedding(p) for p in prompted]
# Результат: качество поиска растёт, модель понимает что это термины с семантикой
Результат: Модель генерирует семантически насыщенные эмбеддинги для терминов. Когда пользователь ищет "интеграция" — находятся статьи про "API", "webhook", "синхронизация". Без промпта модель могла искать по буквальному совпадению или вообще выдавать случайные статьи.
Почему это работает
Embedding модели тренируют на полных предложениях из датасетов типа Wikipedia, научных статей, диалогов. Контрастивное обучение учит модель: похожие предложения → похожие векторы. Одиночное слово "собака" — это аномалия для такой модели. Она не знает что с ним делать, потому что не видела одиночных слов в тренировочных данных.
Вторая проблема — токенизация. BPE-токенизаторы (OpenAI, Voyage, Qwen) кодируют пробелы как часть токена: "собака" и " собака" — это разные токены. WordPiece-токенизаторы (BERT-based: all-mpnet, BGE) нормализуют пробелы — для них оба варианта идентичны. Поэтому форматирование (добавление пробелов) помогает одним моделям и не влияет на другие.
Семантические промпты работают через прайминг — ты даёшь модели контекст, который сигнализирует "это не просто токен, это концепция со значением". Промпт "Represent the semantic concept: собака" активирует те же внутренние паттерны, что и полное предложение "Собака — это домашнее животное". Модель переключается из режима "закодировать токен" в режим "создать семантическое представление".
Рычаги управления: - Длина промпта: "meaning: X" (короткий) vs "Represent the semantic concept: X" (явный) — явные инструкции работают лучше для коммерческих API, короткие — для open-source - Формат: "word: X" (нейтрально) vs "meaning: X" (семантика) — семантические промпты дают +0.10..+0.15 к корреляции - Пробелы: для BPE-моделей добавление пробела может улучшить результат на +0.05..+0.20
Шаблон промпта
Для embedding API (Python/любой язык):
# Базовый вариант
prompt = f"meaning: {word}"
embedding = get_embedding(prompt)
# Продвинутый вариант (лучше для OpenAI, Cohere)
prompt = f"Represent the semantic concept: {word}"
embedding = get_embedding(prompt)
# Для списка терминов
terms = ["интеграция", "API", "тариф"]
prompts = [f"meaning: {t}" for t in terms]
embeddings = [get_embedding(p) for p in prompts]
Для работы в ChatGPT/Claude (косвенное применение):
Если ты используешь чат для подбора синонимов, похожих терминов, категоризации — попроси модель думать про семантическую суть слова, а не просто про слово:
Задача: подобрать 5 похожих терминов.
Вместо: "Дай синонимы для 'интеграция'"
Делай: "Подбери термины, близкие по семантике к концепту 'интеграция'
в контексте IT-систем. Думай про meaning, а не про само слово."
Подстановка:
- {word} — одиночное слово или короткий термин
- Для compound terms ("машинное обучение") — тоже работает
Выбор формата: - OpenAI (text-embedding-3-*): "meaning: {word}" или "Represent the semantic concept: {word}" - Cohere (embed-english-v3.0): "Represent the semantic concept: {word}" - Voyage (voyage-3): "Represent the semantic concept: {word}" (критично, на голых словах не работает!) - Open-source (SBERT, BGE): "word: {word}" или "meaning: {word}"
Ограничения
⚠️ Только для word-level задач: Если ты работаешь с полными предложениями (поиск по документам, semantic similarity текстов) — промпты не нужны и могут даже навредить. Модели и так обучены на предложениях.
⚠️ Не universal solution: Техника помогает когда тебе действительно нужны эмбеддинги отдельных слов — терминология, короткие поисковые запросы, word sense disambiguation. Для большинства задач (RAG, semantic search по документам) это избыточно.
⚠️ Model-specific tuning: Voyage-3 критично зависит от промптов (без них ρ ≈ 0), OpenAI модели работают и без промптов, но с ними лучше. Протестируй свою модель перед внедрением.
⚠️ Английский язык: Исследование проверяли только на английских бенчмарках. Для русского работает (я проверял логику), но оптимальные промпты могут отличаться.
Как исследовали
Команда взяла 7 популярных embedding моделей (OpenAI text-embedding-3-small/large, Cohere embed-english-v3.0, Voyage voyage-3, плюс open-source: all-mpnet-base-v2, BGE-large-en-v1.5, Qwen3-Embedding-8B) и прогнала их через 3 классических бенчмарка word similarity: SimLex-999 (сложный, genuine similarity), WordSim-353 (микс similarity и relatedness), MEN-3000 (relatedness).
Протестировали 8 условий для каждого слова: 4 варианта форматирования (голое слово, с пробелом спереди/сзади/с обеих сторон) и 4 семантических промпта ("the word X", "word: X", "meaning: X", "Represent the semantic concept: X"). Для каждой пары слов из бенчмарка получили эмбеддинги, посчитали косинусное сходство, сравнили с человеческими оценками через Spearman correlation.
Удивительные находки: Voyage-3 показала отрицательную корреляцию на голых словах (ρ = -0.07 на SimLex) — то есть её эмбеддинги антикоррелируют с человеческими оценками! С промптами взлетела до ρ = 0.59 (+0.66 improvement). Qwen3-Embedding-8B (8B параметров!) проваливалась на голых словах (ρ = 0.29), а маленькая all-mpnet-base-v2 (110M параметров) работала стабильно (ρ = 0.54) — размер модели не предсказывает robustness.
Инсайт для практики: Если твоя embedding модель странно себя ведёт на коротких запросах — это не баг, это feature. Она обучена на предложениях. Добавь семантический контекст — и она заработает. Новый SOTA на SimLex-999: ρ = 0.69 (vs 0.48 у LexVec, лучшего static метода) — текстовые embedding модели с промптами обгоняют классические word2vec/GloVe/fastText на их родной территории.
Адаптации и экстраполяции
💡 Адаптация для категоризации терминов
Если тебе нужно автоматически кластеризовать термины (например, для создания структуры базы знаний), используй prompted embeddings:
terms = ["JWT", "OAuth", "авторизация", "аутентификация",
"тариф", "биллинг", "подписка", "оплата"]
# Получи prompted embeddings
prompted = [f"meaning: {t}" for t in terms]
embeddings = [get_embedding(p) for p in prompted]
# Кластеризуй (k-means, HDBSCAN, etc.)
# Результат: [JWT, OAuth, авторизация, аутентификация] → кластер "Безопасность"
# [тариф, биллинг, подписка, оплата] → кластер "Финансы"
💡 Адаптация для медицинской/технической терминологии
В медицине и технике точность терминологии критична. Используй domain-specific промпты:
# Для медицинских терминов
prompt = f"medical term: {term}" # "инфаркт", "ИБС", "стенокардия"
# Для технических терминов
prompt = f"technical concept: {term}" # "шифрование", "хеш", "API"
# Для юридических терминов
prompt = f"legal concept: {term}" # "оферта", "акцепт", "цессия"
Domain-specific промпты уточняют контекст — модель понимает что "bank" в финансовом контексте ≠ "bank" (берег реки).
💡 Адаптация для многоязычных систем
Если работаешь с несколькими языками в одной системе, добавь язык в промпт для disambiguation:
# Русские термины
ru_prompt = f"Russian term meaning: {term}"
# Английские термины
en_prompt = f"English term meaning: {term}"
# Это поможет модели не путать омонимы типа "кран" (водопроводный vs строительный)
🔧 Техника: A/B тест промптов → найди оптимальный для твоей задачи
Разные модели реагируют на разные промпты. Протестируй несколько вариантов на своих данных:
prompts = [
"meaning: {word}",
"word: {word}",
"Represent the semantic concept: {word}",
"the word {word}",
"Define: {word}"
]
# Для каждого промпта:
# 1. Получи embeddings для набора эталонных пар
# 2. Посчитай корреляцию с твоими ground truth оценками
# 3. Выбери промпт с максимальной корреляцией
Исследование показало: OpenAI любит длинные инструкции, Cohere — тоже, open-source (BGE) — короткие ("word: X"). Твоя задача может отличаться — протестируй.
Ресурсы
One Word Is Not Enough: Simple Prompts Improve Word Embeddings — Rajeev Ranjan (GodelLabs)
Бенчмарки: - SimLex-999: Hill et al. (2015) — genuine semantic similarity - WordSim-353: Finkelstein et al. (2002) — similarity + relatedness - MEN-3000: Bruni et al. (2012) — semantic relatedness
Embedding модели: - OpenAI text-embedding-3: https://platform.openai.com/docs/guides/embeddings - Cohere embed-english-v3.0: https://docs.cohere.com/docs/cohere-embed - Voyage voyage-3: https://docs.voyageai.com/docs/embeddings - Open-source: Sentence-Transformers (SBERT), BGE, Qwen
