Files
hotels/n8n_code_parse_json.js
Фёдор 684fada337 🚀 Full project sync: Hotels RAG & Audit System
 Major Features:
- Complete RAG system for hotel website analysis
- Hybrid audit with BGE-M3 embeddings + Natasha NER
- Universal horizontal Excel reports with dashboards
- Multi-region processing (SPb, Orel, Chukotka, Kamchatka)

📊 Completed Regions:
- Орловская область: 100% (36/36)
- Чукотский АО: 100% (4/4)
- г. Санкт-Петербург: 93% (893/960)
- Камчатский край: 87% (89/102)

🔧 Infrastructure:
- PostgreSQL with pgvector extension
- BGE-M3 embeddings API
- Browserless for web scraping
- N8N workflows for automation
- S3/Nextcloud file storage

📝 Documentation:
- Complete DB schemas
- API documentation
- Setup guides
- Status reports
2025-10-27 22:49:42 +03:00

122 lines
3.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 🎯 CODE NODE: Парсинг JSON ответов от AI Agent
// Вход: массив с ответами от AI Agent в JSON формате
// Выход: структурированные данные для каждого критерия
const inputData = $input.all();
// Обрабатываем каждый item (ответ на вопрос)
const results = inputData.map((item, index) => {
const rawOutput = item.json.output || item.json.response || '';
let parsedData = {
found: false,
score: 0.0,
quote: '',
url: '',
details: '',
checked_pages: 0,
confidence: 'Не найдено'
};
try {
// Пытаемся распарсить JSON из ответа
// AI может вернуть JSON в разных форматах, пробуем все варианты
// Вариант 1: Чистый JSON
if (rawOutput.trim().startsWith('{')) {
parsedData = JSON.parse(rawOutput);
}
// Вариант 2: JSON в markdown блоке ```json ... ```
else if (rawOutput.includes('```json')) {
const jsonMatch = rawOutput.match(/```json\s*(\{[\s\S]*?\})\s*```/);
if (jsonMatch) {
parsedData = JSON.parse(jsonMatch[1]);
}
}
// Вариант 3: JSON где-то в тексте
else {
const jsonMatch = rawOutput.match(/\{[\s\S]*?"found"[\s\S]*?\}/);
if (jsonMatch) {
parsedData = JSON.parse(jsonMatch[0]);
}
}
} catch (e) {
// Если не удалось распарсить JSON - пытаемся извлечь данные из текста
console.log(`Ошибка парсинга JSON для item ${index}: ${e.message}`);
// Проверяем наличие позитивных маркеров
const isFound = rawOutput.includes('✅ ДА') ||
rawOutput.includes('найдено') ||
rawOutput.includes('указан') ||
rawOutput.includes('представлен');
const isNotFound = rawOutput.includes('❌ НЕТ') ||
rawOutput.includes('не найдено') ||
rawOutput.includes('отсутствует');
// Извлекаем цитату
const quoteMatch = rawOutput.match(/📄 Цитата: "(.+?)"/s) ||
rawOutput.match(/Цитата: (.+?)(?:\n|$)/);
const quote = quoteMatch ? quoteMatch[1].trim() : rawOutput.substring(0, 200);
// Извлекаем URL
const urlMatch = rawOutput.match(/🔗 URL: (.+?)(?:\n|$)/) ||
rawOutput.match(/URL: (.+?)(?:\n|$)/);
const url = urlMatch ? urlMatch[1].trim() : '';
// Оценка
let score = 0.0;
let confidence = 'Не найдено';
if (isFound && quote && url) {
score = 1.0;
confidence = 'Высокая';
} else if (isFound && quote) {
score = 0.5;
confidence = 'Средняя';
} else if (isNotFound) {
score = 0.0;
confidence = 'Не найдено';
} else {
score = 0.2;
confidence = 'Низкая';
}
parsedData = {
found: isFound,
score: score,
quote: quote,
url: url,
details: rawOutput.substring(0, 200),
checked_pages: 0,
confidence: confidence
};
}
// Возвращаем структурированные данные
return {
json: {
criterion_id: item.json.id || (index + 1),
criterion_name: item.json.name || `Критерий ${index + 1}`,
question: item.json.question || '',
raw_answer: rawOutput,
found: parsedData.found,
score: parsedData.score,
quote: parsedData.quote || '',
url: parsedData.url || '',
details: parsedData.details || '',
checked_pages: parsedData.checked_pages || 0,
confidence: parsedData.confidence || 'Не найдено'
}
};
});
return results;