Budowa bazy wiedzy RAG z Google Cloud Vertex AI i BigQuery

Spis treści
- 1. Architektura rozwiązania: Bezserwerowy RAG w Google Cloud
- 2. Generowanie wektorów w BigQuery ML krok po kroku
- 3. Indeksowanie wektorowe i wyszukiwanie semantyczne krok po kroku
- 4. Potok generowania RAG z modelem Gemini krok po kroku
- 5. Podsumowanie i wartość architektoniczna
- Pytania i odpowiedzi
- Źródła
Standardowe duże modele językowe (LLM) często wykazują tendencję do halucynacji i posiadają nieaktualną wiedzę, gdy są odpytywane o wewnętrzne instrukcje firmowe, dedykowane bazy danych czy specjalistyczną dokumentację techniczną. Generowanie wspomagane wyszukiwaniem (Retrieval-Augmented Generation – RAG) eliminuje te ograniczenia, osadzając proces generowania odpowiedzi w zweryfikowanym, specyficznym dla przedsiębiorstwa repozytorium wiedzy. Wdrożenie bezserwerowej architektury RAG z wykorzystaniem mechanizmu Google Cloud Vertex AI Embeddings oraz BigQuery Vector Search umożliwia skalowalne wyszukiwanie semantyczne w milionach fragmentów dokumentów bez konieczności utrzymywania odrębnej infrastruktury baz danych wektorowych.
1. Architektura rozwiązania: Bezserwerowy RAG w Google Cloud
Profesjonalny potok RAG w Google Cloud rozdziela przetwarzanie dokumentów, indeksowanie semantyczne i generowanie odpowiedzi na trzy zarządzane usługi:
- Pozyskiwanie danych i podział (Chunking): Surowe podręczniki PDF, strony intranetowe oraz ustrukturyzowane tabele baz danych są wgrywane do Google Cloud Storage (GCS) i dzielone na semantyczne fragmenty (chunki) po 500–1000 tokenów z 10-procentowym nakładaniem.
- Indeksowanie wektorowe BigQuery ML: Fragmenty są przechowywane w tabelach BigQuery, gdzie modele osadzania Vertex AI (np.
gemini-embedding-001, który obsługuje wiele języków; starszetext-embedding-004itext-multilingual-embedding-002Google wyłącza 1 kwietnia 2027 r.) generują wysokowymiarowe wektory bezpośrednio za pomocą poleceń SQL. - Osadzanie faktów w Vertex AI Gemini: W momencie wpłynięcia zapytania, usługa BigQuery Vector Search wykonuje wyszukiwanie przybliżonych najbliższych sąsiadów (ANN), aby pobrać najbardziej trafne fragmenty tekstu, które następnie są wstrzykiwane jako merytoryczny kontekst do monitu modelu Gemini.
2. Generowanie wektorów w BigQuery ML krok po kroku
Aby generować osadzenia wektorowe bez eksportowania danych do zewnętrznych skryptów Python, należy skonfigurować zdalne połączenie z modelem Vertex AI wewnątrz BigQuery. Poniższy skrypt SQL łączy model osadzania i przekształca tabelę z surowymi fragmentami dokumentów w zaindeksowane wektorowo repozytorium wiedzy:
-- 1. Utworzenie zdalnego połączenia z punktem końcowym Vertex AI Embedding
CREATE OR REPLACE MODEL `enterprise_kb.vertex_embed_model`
REMOTE WITH CONNECTION `us-central1.vertex_ai_connection`
OPTIONS (
ENDPOINT = 'gemini-embedding-001'
);
-- 2. Wygenerowanie osadzeń wektorowych dla surowych fragmentów dokumentów
CREATE OR REPLACE TABLE `enterprise_kb.document_embeddings` AS
SELECT
doc_id,
chunk_id,
content_text,
source_url,
ml_generate_embedding_result AS content_embedding
FROM
ML.GENERATE_EMBEDDING(
MODEL `enterprise_kb.vertex_embed_model`,
(SELECT *, content_text AS content FROM `enterprise_kb.raw_document_chunks`),
STRUCT(TRUE AS flatten_json_output)
)
WHERE
content_text IS NOT NULL;
3. Indeksowanie wektorowe i wyszukiwanie semantyczne krok po kroku
W celu zapewnienia błyskawicznego czasu odpowiedzi w dużych zbiorach dokumentów, na kolumnie wektorowej należy utworzyć indeks IVF (Inverted File) przed uruchomieniem zapytań o podobieństwo semantyczne:
-- 1. Utworzenie indeksu IVF (Approximate Nearest Neighbor)
CREATE VECTOR INDEX `kb_semantic_index`
ON `enterprise_kb.document_embeddings`(content_embedding)
OPTIONS (
index_type = 'IVF',
distance_type = 'COSINE',
ivf_options = '{"num_lists": 1000}'
);
-- 2. Wykonanie wyszukiwania wektorowego w celu pobrania 3 najbardziej trafnych fragmentów
SELECT
base.doc_id,
base.chunk_id,
base.content_text,
base.source_url,
distance AS cosine_distance
FROM
VECTOR_SEARCH(
TABLE `enterprise_kb.document_embeddings`,
'content_embedding',
(
SELECT ml_generate_embedding_result AS content_embedding
FROM ML.GENERATE_EMBEDDING(
MODEL `enterprise_kb.vertex_embed_model`,
(SELECT 'Jakie są zasady eskalacji SLA podczas krytycznych awarii serwerów?' AS content),
STRUCT(TRUE AS flatten_json_output)
)
),
top_k => 3,
distance_type => 'COSINE'
)
ORDER BY distance ASC;
4. Potok generowania RAG z modelem Gemini krok po kroku
Po pobraniu odpowiednich fragmentów kontekstu za pośrednictwem BigQuery Vector Search, ustrukturyzowany monit jest składany i przekazywany do interfejsu API Vertex AI Gemini za pomocą języka Python:
from google.cloud import bigquery
from google import genai
# Inicjalizacja klientów Google Cloud
bq_client = bigquery.Client(project='enterprise-ai-project')
genai_client = genai.Client(vertexai=True, project='enterprise-ai-project', location='us')
def answer_query_with_rag(user_question):
"""Wykonuje wyszukiwanie wektorowe BigQuery i osadza odpowiedzi Gemini w faktach."""
# Pobranie 3 najbardziej trafnych semantycznie fragmentów z BigQuery
search_query = f"""
SELECT base.content_text, base.source_url
FROM VECTOR_SEARCH(
TABLE `enterprise_kb.document_embeddings`,
'content_embedding',
(
SELECT ml_generate_embedding_result AS content_embedding
FROM ML.GENERATE_EMBEDDING(
MODEL `enterprise_kb.vertex_embed_model`,
(SELECT @question AS content),
STRUCT(TRUE AS flatten_json_output)
)
),
top_k => 3,
distance_type => 'COSINE'
)
"""
job_config = bigquery.QueryJobConfig(
query_parameters=[bigquery.ScalarQueryParameter("question", "STRING", user_question)]
)
results = bq_client.query(search_query, job_config=job_config).result()
# Sformatowanie pobranych fragmentów w blok kontekstowy
context_block = "\n---\n".join([f"Źródło ({row.source_url}): {row.content_text}" for row in results])
# Zbudowanie rygorystycznego monitu RAG
rag_prompt = f"""Jesteś autorytatywnym asystentem technicznym w firmie.
Odpowiedz na pytanie WYŁĄCZNIE w oparciu o fakty podane w poniższym Kontekście.
Jeśli odpowiedzi nie można ustalić na podstawie Kontekstu, poinformuj wyraźnie, że informacja jest niedostępna.
Kontekst:
{context_block}
Pytanie:
{user_question}
"""
response = genai_client.models.generate_content(model="gemini-3.5-flash", contents=rag_prompt)
return response.text
if __name__ == '__main__':
output = answer_query_with_rag("Jakie są zasady eskalacji SLA podczas krytycznych awarii serwerów?")
print(output)
5. Podsumowanie i wartość architektoniczna
Co da się osiągnąć dzięki temu poradnikowi: Wdrożenie bezserwerowej, wysoce skalowalnej bazy wiedzy RAG przy użyciu mechanizmów osadzania Google Cloud Vertex AI, indeksowania wektorowego BigQuery ML oraz generowania opartego na faktach w modelu Gemini.
Wynikająca z tego wartość: Specjalistyczne pytania dotyczące wewnętrznej dokumentacji firmowej, podręczników i baz danych uzyskują precyzyjne odpowiedzi poparte rzetelnymi przypisami źródłowymi. Zjawisko halucynacji sztucznej inteligencji zostaje znacząco ograniczone poprzez rygorystyczne powiązanie generowanych treści ze sprawdzonymi danymi organizacji. Ponadto realizacja indeksowania i wyszukiwania wektorowego bezpośrednio w BigQuery eliminuje potrzebę utrzymywania kosztownych, dedykowanych klastrów baz wektorowych przy zachowaniu najwyższych standardów bezpieczeństwa danych oraz uprawnień IAM.
Pytania i odpowiedzi
Jakie uprawnienia i lokalizacje musi ze sobą zgrać ta konfiguracja?
Trzy punkty, w których konfiguracja w przeciwnym razie zawodzi albo kieruje dane tam, gdzie nikt się ich nie spodziewa:
- Połączenie
vertex_ai_connectionma własne konto usługi. Dopiero gdy to konto ma w projekcie rolę Vertex AI User, BigQuery może wywołać model osadzania; bez niejML.GENERATE_EMBEDDINGkończy się błędem uprawnień. - Skrypt w Pythonie działa z własnymi poświadczeniami, które muszą obejmować uprawnienia do uruchamiania zadań BigQuery i odczytu tabeli
document_embeddings, a do wywołania Gemini także dostęp do Vertex AI. - Zbiór danych
enterprise_kbi połączenie muszą znajdować się w tej samej lokalizacji. Artykuł używa regionuus-central1, położonego w Stanach Zjednoczonych, a dla Gemini lokalizacjius, również w Stanach Zjednoczonych. Jeśli dokumenty mają być przetwarzane w UE, zbiór danych i połączenie należy utworzyć w regionie europejskim, a wgenai.Client()podać europejską lokalizację, taką jakeu, o ile używane modele są tam dostępne.
Zarządzanie uprawnieniami IAM, o którym mówi artykuł, opiera się właśnie na tych rolach i lokalizacjach.
Czy pytanie musi zostać osadzone tym samym modelem co dokumenty?
Tak. Wektory z różnych modeli osadzania leżą w różnych przestrzeniach, często nawet o różnej liczbie wymiarów, a odległość kosinusowa między nimi nic nie znaczy; kod w artykule konsekwentnie używa do obu celów enterprise_kb.vertex_embed_model. Wynika z tego ograniczenie w eksploatacji: jeśli model się zmieni, na przykład dlatego, że Google wycofuje daną wersję modelu, wszystkie fragmenty należy osadzić od nowa i ponownie utworzyć indeks wektorowy.