161 lines
4.8 KiB
JavaScript
161 lines
4.8 KiB
JavaScript
|
|
// 🎯 CODE NODE: Проверка регулярными выражениями
|
|||
|
|
// Размести эту ноду ПОСЛЕ AI Agent
|
|||
|
|
// Она улучшит оценку, если найдёт точные форматы (ИНН, телефоны, email)
|
|||
|
|
|
|||
|
|
// Получаем данные от AI Agent
|
|||
|
|
const aiResult = $input.item.json;
|
|||
|
|
|
|||
|
|
// Получаем текст из chunks (должен быть в контексте)
|
|||
|
|
// Если у тебя есть отдельная нода для получения chunks - используй её
|
|||
|
|
// Иначе - нужно сделать дополнительный запрос к PostgreSQL
|
|||
|
|
const hotelText = $('Postgres1').all().map(item => item.json.text).join(' ');
|
|||
|
|
|
|||
|
|
// Регулярные выражения для каждого критерия
|
|||
|
|
const regexPatterns = {
|
|||
|
|
1: { // ИНН, ОГРН
|
|||
|
|
patterns: [
|
|||
|
|
/\b\d{10}\b/g, // ИНН юр.лица (10 цифр)
|
|||
|
|
/\b\d{12}\b/g, // ИНН ИП (12 цифр)
|
|||
|
|
/\b\d{13}\b/g, // ОГРН (13 цифр)
|
|||
|
|
/\b\d{15}\b/g, // ОГРНИП (15 цифр)
|
|||
|
|
/инн\s*:?\s*\d{10,12}/gi,
|
|||
|
|
/огрн\s*:?\s*\d{13}/gi
|
|||
|
|
],
|
|||
|
|
weight: 1.0
|
|||
|
|
},
|
|||
|
|
2: { // Адрес
|
|||
|
|
patterns: [
|
|||
|
|
/\d{6}.*?ул\./gi,
|
|||
|
|
/ул\.\s*[А-Яа-яёЁA-Za-z\s]+,?\s*\d+/gi,
|
|||
|
|
/\d{6},?\s*г\.\s*[А-Яа-яёЁ-]+/gi
|
|||
|
|
],
|
|||
|
|
weight: 1.0
|
|||
|
|
},
|
|||
|
|
3: { // Контакты
|
|||
|
|
patterns: [
|
|||
|
|
/(?:\+7|8)\s*\(?\d{3,5}\)?\s*\d{1,3}[-\s]?\d{2}[-\s]?\d{2}/g, // Телефон
|
|||
|
|
/[\w\.-]+@[\w\.-]+\.\w{2,}/g // Email
|
|||
|
|
],
|
|||
|
|
weight: 1.0
|
|||
|
|
},
|
|||
|
|
4: { // Режим работы
|
|||
|
|
patterns: [
|
|||
|
|
/(?:с|с\s+)\d{1,2}(?::|\.)\d{2}\s*(?:до|по)\s*\d{1,2}(?::|\.)\d{2}/gi,
|
|||
|
|
/круглосуточно/gi,
|
|||
|
|
/24\s*[/\-]\s*7/g
|
|||
|
|
],
|
|||
|
|
weight: 1.0
|
|||
|
|
},
|
|||
|
|
5: { // 152-ФЗ
|
|||
|
|
patterns: [
|
|||
|
|
/152[-\s]?фз/gi,
|
|||
|
|
/политика\s+в\s+отношении\s+обработки\s+персональных\s+данных/gi
|
|||
|
|
],
|
|||
|
|
weight: 1.0
|
|||
|
|
},
|
|||
|
|
7: { // Договор-оферта
|
|||
|
|
patterns: [
|
|||
|
|
/публичная\s+оферта/gi,
|
|||
|
|
/договор.*?оказани.*?услуг/gi,
|
|||
|
|
/пользовательское\s+соглашение/gi
|
|||
|
|
],
|
|||
|
|
weight: 1.0
|
|||
|
|
},
|
|||
|
|
9: { // Цены
|
|||
|
|
patterns: [
|
|||
|
|
/\d+\s*(?:руб|₽)/g,
|
|||
|
|
/(?:от|цена|стоимость)\s*\d+/gi
|
|||
|
|
],
|
|||
|
|
weight: 0.8
|
|||
|
|
},
|
|||
|
|
12: { // Онлайн-бронирование
|
|||
|
|
patterns: [
|
|||
|
|
/забронировать/gi,
|
|||
|
|
/форма\s+(?:заявки|бронирования)/gi
|
|||
|
|
],
|
|||
|
|
weight: 0.8
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// Функция проверки паттернов
|
|||
|
|
function checkPatterns(text, patterns) {
|
|||
|
|
const matches = [];
|
|||
|
|
for (const pattern of patterns) {
|
|||
|
|
const found = text.match(pattern);
|
|||
|
|
if (found) {
|
|||
|
|
matches.push(...found.slice(0, 3)); // Макс 3 совпадения на паттерн
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return matches;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Проверяем текущий критерий
|
|||
|
|
const criterionId = aiResult.criterion_id || aiResult.id;
|
|||
|
|
const regexConfig = regexPatterns[criterionId];
|
|||
|
|
|
|||
|
|
let regexScore = 0.0;
|
|||
|
|
let regexMatches = [];
|
|||
|
|
|
|||
|
|
if (regexConfig && hotelText) {
|
|||
|
|
regexMatches = checkPatterns(hotelText, regexConfig.patterns);
|
|||
|
|
|
|||
|
|
if (regexMatches.length > 0) {
|
|||
|
|
regexScore = regexConfig.weight;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ГИБРИДНАЯ ОЦЕНКА: берём максимум из AI и регулярок
|
|||
|
|
const aiScore = parseFloat(aiResult.score) || 0.0;
|
|||
|
|
const finalScore = Math.max(aiScore, regexScore);
|
|||
|
|
|
|||
|
|
// Определяем метод, который дал результат
|
|||
|
|
let method = 'Не найдено';
|
|||
|
|
if (finalScore > 0) {
|
|||
|
|
if (aiScore > regexScore) {
|
|||
|
|
method = 'AI Agent';
|
|||
|
|
} else if (regexScore > aiScore) {
|
|||
|
|
method = 'Регулярные выражения';
|
|||
|
|
} else {
|
|||
|
|
method = 'AI Agent + Регулярки';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Возвращаем улучшенный результат
|
|||
|
|
return {
|
|||
|
|
json: {
|
|||
|
|
criterion_id: criterionId,
|
|||
|
|
criterion_name: aiResult.criterion_name || aiResult.name,
|
|||
|
|
question: aiResult.question,
|
|||
|
|
|
|||
|
|
// Результаты AI Agent
|
|||
|
|
ai_score: aiScore,
|
|||
|
|
ai_found: aiResult.found,
|
|||
|
|
ai_quote: aiResult.quote || '',
|
|||
|
|
ai_url: aiResult.url || '',
|
|||
|
|
|
|||
|
|
// Результаты регулярок
|
|||
|
|
regex_score: regexScore,
|
|||
|
|
regex_matches: regexMatches.slice(0, 5), // Макс 5 совпадений
|
|||
|
|
regex_found: regexMatches.length > 0,
|
|||
|
|
|
|||
|
|
// Итоговая оценка
|
|||
|
|
final_score: finalScore,
|
|||
|
|
method: method,
|
|||
|
|
confidence: finalScore >= 0.8 ? 'Высокая' :
|
|||
|
|
finalScore >= 0.5 ? 'Средняя' :
|
|||
|
|
finalScore >= 0.3 ? 'Низкая' : 'Не найдено',
|
|||
|
|
|
|||
|
|
// Для отчёта
|
|||
|
|
quote: aiResult.quote || (regexMatches.length > 0 ? `Найдено: ${regexMatches[0]}` : ''),
|
|||
|
|
url: aiResult.url || '',
|
|||
|
|
details: aiResult.details || ''
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|