
Взломать свой собственный тряпкий стек менее чем за час
10 июля 2025 г.Если вы создаете чат -бот, поисковую систему или любое приложение для искусственного интеллекта, которое нужно «знать что -то», вы, вероятно, наткнулись на жесткую правду:
Большие языковые модели (LLMS) не могут получить доступ к вашим частным или специфичным для домена данных, если вы не подаете их им.
Будь то документация по продукту, внутренние политики или записи в реальном времени, крупные языковые модели не могут получить доступ к внешним знаниям, если.Вы явно кормите их имПолем
ВходитьТряпичный(Поизводимое поколение).
RAG объединяет творческую силу LLM с фактической точностью ваших собственных данных. По своей сути, он полагается наСемантический поискПоиск наиболее важных фрагментов текста на основезначение, не только ключевые слова.
Вместо того, чтобы просить LLM для галлюцинатных ответов, тряпичные трубопроводы сначала извлекают соответствующий контент из ваших источников данных, а затем передайте его в модель. Результат? Более точные, обоснованные и полезные ответы.
Но как вы построите часть поиска?
В этом уроке мы создадим легкий, быстрый и бесплатный Semantic Search API, используя:
- PostgreSQL + PGVectorхранить и запросить вторжения
- Transformers.jsЧтобы запустить модель MINILM в JavaScript, не требуется облако
- ФормификацияДля прокатного веб-сервера
Примечание:Это руководство предполагает, что вы чувствуете себя удобно с базовым JavaScript/Node.js и установили PostgreSQL. Некоторое знакомство с APIS REST и векторными встраиваниями поможет, но мы будем держать вещи практичными и ориентированными на код во всем мире
Давайте начнем.
1. Настройка PostgreSQL с помощью PGVector
Установите расширение вектора в базе данных PostgreSQL:
CREATE EXTENSION IF NOT EXISTS vector;
Затем создайте простую таблицу для хранения документов и их вторжений:
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
title TEXT,
content TEXT,
embedding vector(384) -- Dimensions of MiniLM-L6-v2
);
2. Создание встроений с Transformers.js
Установите зависимости:
npm install pg @xenova/transformers
Используйте этот скрипт, чтобы встроить свой контент и хранить его в Postgres:
import { Client } from 'pg';
import { pipeline } from '@xenova/transformers';
const db = new Client({ connectionString: 'postgres://localhost/yourdb' });
let embedder = null;
async function generateEmbedding(text) {
if (!embedder) {
embedder = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
}
const output = await embedder(text, { pooling: 'mean', normalize: true });
return Array.from(output.data);
}
const docs = [
{ title: 'Cats', content: 'Cats are independent and curious animals.' },
{ title: 'Space', content: 'The universe is vast and mostly unexplored.' },
{ title: 'Bananas', content: 'Bananas are a yellow tropical fruit.' },
];
await db.connect();
for (const doc of docs) {
const vec = await generateEmbedding(doc.content);
const pgVector = `[${vec.join(',')}]`;
await db.query(
'INSERT INTO documents (title, content, embedding) VALUES ($1, $2, $3::vector)',
[doc.title, doc.content, pgVector]
);
console.log(`Inserted: ${doc.title}`);
}
await db.end();
3. Запрос с помощью PGVector
Чтобы найти наиболее релевантный контент с запросом пользователя, встройте запрос и сравните его с векторами документов, используя косинусное расстояние:
SELECT title, content, embedding <#> $1::vector AS score
FROM documents
ORDER BY score ASC
LIMIT 3;
Оператор <#> возвращает расстояние косинуса. Нижний означает более похожие.
4. Создание API поиска фазвии
npm install fastify @fastify/cors
import Fastify from 'fastify';
import cors from '@fastify/cors';
import { Pool } from 'pg';
import { pipeline } from '@xenova/transformers';
const fastify = Fastify();
await fastify.register(cors, { origin: '*' });
const pool = new Pool({ connectionString: 'postgres://localhost/yourdb' });
let embedder = null;
async function generateEmbedding(text) {
if (!embedder) {
embedder = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
}
const output = await embedder(text, { pooling: 'mean', normalize: true });
return `[${Array.from(output.data).join(',')}]`;
}
fastify.post('/search', async (req, res) => {
const { query } = req.body;
if (!query) return res.status(400).send({ error: 'Query is required' });
const vector = await generateEmbedding(query);
const { rows } = await pool.query(
`SELECT title, content, embedding <#> $1::vector AS score
FROM documents
ORDER BY score ASC
LIMIT 3`,
[vector]
);
res.send(rows);
});
fastify.listen({ port: 3000 }, () => {
console.log('API ready at http://localhost:3000');
});
Проверьте это с помощью:
curl -X POST http://localhost:3000/search \
-H "Content-Type: application/json" \
-d '{"query": "Tell me about fruit"}'
5. варианты использования и следующие шаги
Этот стек идеально подходит для:
- Rag Pipelines (подача результатов в LLM)
- Внутренний поиск знаний
- Поиск памяти Чатбота
- Умная фильтрация с естественным языком
Что добавить дальше:
- Фильтрация метаданных в запросах
- Chunking для более длинных документов
- Гибридный поиск (текст + вектор)
- Интеграция с Openai или Mistral
Заключение
Векторный поиск больше не для инженеров ML. С PGVector, Tansformer.js и фазвией вы можете построить свою собственную семантическую поисковую систему менее чем за час, без блокировки поставщиков. Это не готово производства, но может помочь в качестве базовой линии для ваших приложений Prod.
Счастливого взлома!
Оригинал