В потоке обратной связи нужно заметить сообщение о проблеме и отделить его от вопроса или благодарности. В демонстрации используются только придуманные учебные фразы, а не отзывы клиентов; небольшой классификатор показывает принцип предварительной разметки.
УЧЕБНЫЙ ПРИМЕР
Первичная разметка обратной связи
Учебная модель сравнивает сообщения с примерами похвалы, проблемы и вопроса. Фразы можно менять и переобучать модель; это не готовая оценка качества обслуживания.
Это ширина демонстрационного холста. Она не заменяет проверку настоящего устройства.
DEMO / ai-feedback
Первичная разметка обратной связи
В потоке обратной связи нужно заметить сообщение о проблеме и отделить его от вопроса или благодарности. В демонстрации используются только придуманные учебные фразы, а не отзывы клиентов; небольшой классификатор показывает принцип предварительной разметки.
Открыть рабочую демонстрацию
Первичная разметка обратной связи
Посмотреть рабочий код модели
Функция обучения
function trainTextModel(samples) {
if (!Array.isArray(samples) || samples.length < 4 || samples.length > 30) throw new Error('CLASSIFIER_COUNT');
const classes = new Map();
const vocabulary = new Set();
for (const sample of samples) {
if (!sample || typeof sample.label !== 'string' || !sample.label.trim() ||
typeof sample.text !== 'string' || !sample.text.trim()) throw new Error('TRAINING_FORMAT');
const label = sample.label.trim();
const key = label.toLowerCase();
const tokens = tokenizeText(sample.text);
if (!tokens.length) throw new Error('TRAINING_WORDS');
if (!classes.has(key)) classes.set(key, {label, documents: 0, tokens: 0, counts: new Map()});
const target = classes.get(key);
target.documents += 1;
for (const token of tokens) {
vocabulary.add(token);
target.tokens += 1;
target.counts.set(token, (target.counts.get(token) || 0) + 1);
}
}
if (classes.size < 2) throw new Error('CLASSIFIER_LABELS');
if (Array.from(classes.values()).some(target => target.documents < 2)) throw new Error('CLASSIFIER_EXAMPLES');
return {kind: 'classifier', classes: Array.from(classes.values()), vocabulary, documents: samples.length};
}Функция проверки запроса
function rankText(model, text) {
if (!model || model.kind !== 'classifier') throw new Error('NOT_TRAINED');
if (typeof text !== 'string' || text.length > 500) throw new Error('QUERY_LIMIT');
const tokens = tokenizeText(text);
const known = tokens.filter(token => model.vocabulary.has(token));
const coverage = tokens.length ? known.length / tokens.length : 0;
if (!known.length) return {review: true, reason: tokens.length ? 'UNKNOWN_WORDS' : 'QUERY_WORDS', label: null, scores: [], known: 0, total: tokens.length, coverage, gap: 0};
const counts = new Map();
known.forEach(token => counts.set(token, (counts.get(token) || 0) + 1));
const logs = model.classes.map(target => {
let value = Math.log(target.documents / model.documents);
counts.forEach((count, token) => {
value += count * Math.log(((target.counts.get(token) || 0) + 1) / (target.tokens + model.vocabulary.size));
});
return {label: target.label, value};
});
const maximum = Math.max(...logs.map(item => item.value));
const total = logs.reduce((sum, item) => sum + Math.exp(item.value - maximum), 0);
const scores = logs.map(item => ({label: item.label, score: Math.exp(item.value - maximum) / total}))
.sort((left, right) => right.score - left.score);
const gap = scores[0].score - scores[1].score;
const reason = tokens.some(token=>token.startsWith('neg:')&&!model.vocabulary.has(token)) ? 'NEGATION_REVIEW' : coverage < 0.2 ? 'LOW_COVERAGE' : gap < 0.12 ? 'CLOSE_SCORES' : '';
return {review: !!reason, reason, label: reason ? null : scores[0].label, scores, known: known.length, total: tokens.length, coverage, gap};
}
Показаны функции из этой демонстрации. Полная реализация также включает подготовку текста и интерфейс.
Малый учебный корпус ограничивает применимость: модель сопоставляет статистику слов и не понимает смысл. Незнакомые и неоднозначные тексты требуют ручной оценки.
Небольшие статистические модели работают в браузере без сети: это не LLM, не нейросеть и не облачный ИИ.
Двенадцать редактируемых синтетических сообщений с тремя метками.
Попробовать сообщение об ошибке и смешанный текст с благодарностью и жалобой; проверить результат после изменения обучающих фраз.
Задача в этом сценарии
В потоке обратной связи нужно заметить сообщение о проблеме и отделить его от вопроса или благодарности. В демонстрации используются только придуманные учебные фразы, а не отзывы клиентов; небольшой классификатор показывает принцип предварительной разметки.
Как устроено решение
- Обучаем модель на четырёх фразах каждой категории: «Похвала», «Проблема», «Вопрос». После изменения набора статистика пересчитывается при повторном обучении.
- Сравниваем новый текст с выученной статистикой слов и показываем относительные баллы. Модель не понимает смысл, иронию или весь контекст переписки.
- При недостаточных или неоднозначных признаках нужна ручная оценка. Итоговое решение о приоритете сообщения остаётся частью согласованного рабочего процесса.
Промежуточные материалы
- Исходная задача и ограничения → В потоке обратной связи нужно заметить сообщение о проблеме и отделить его от вопроса или благодарности. В демонстрации используются только придуманные учебные фразы, а не отзывы клиентов; небольшой классификатор показывает принцип предварительной разметки.
- Состав решения → Двенадцать редактируемых синтетических сообщений с тремя метками.
- Проверка перед запуском → Попробовать сообщение об ошибке и смешанный текст с благодарностью и жалобой; проверить результат после изменения обучающих фраз.
Что проверить перед запуском
- Попробовать сообщение об ошибке и смешанный текст с благодарностью и жалобой; проверить результат после изменения обучающих фраз.
- До применения на настоящих сообщениях проверить ошибки на отложенном наборе и согласовать, какие сообщения всегда должен просматривать человек.
Что входит в пример
- Двенадцать редактируемых синтетических сообщений с тремя метками.
- Локальное обучение и сравнение категорий для введённого сообщения.
- Сравнительные баллы, обозначение ручной оценки и фрагмент работающего кода.
Технический паспорт
DevPilot 1.5.2 · Охват проверок, исходники и дата свидетельств
- Статус
- DEMO · Вымышленная компания и учебные данные
- Материалы
- Собственные HTML/CSS/SVG, исходники и локальные алгоритмы. Фотографии клиентов не используются.
- Обработка
- Демонстрация выполняется в браузере. Открытие примера не создаёт заявку или оплаченный проект.
- Доказательства
- Содержимое и локальные проверки отделены от реальной браузерной, хостинговой и коммерческой приёмки.