|
| 1 | +# Copyright 2025 Google LLC |
| 2 | + |
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +# you may not use this file except in compliance with the License. |
| 5 | +# You may obtain a copy of the License at |
| 6 | + |
| 7 | +# https://www.apache.org/licenses/LICENSE-2.0 |
| 8 | + |
| 9 | +# Unless required by applicable law or agreed to in writing, software |
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +# See the License for the specific language governing permissions and |
| 13 | +# limitations under the License. |
| 14 | + |
| 15 | +import pytest |
| 16 | +from llama_index.core import PropertyGraphIndex, Settings |
| 17 | +from llama_index.core.indices.property_graph import SchemaLLMPathExtractor |
| 18 | +from llama_index.core.query_engine import RetrieverQueryEngine |
| 19 | +from llama_index.llms.google_genai import GoogleGenAI |
| 20 | +from llama_index.readers.wikipedia import WikipediaReader |
| 21 | + |
| 22 | +from llama_index_spanner.graph_retriever import SpannerGraphCustomRetriever |
| 23 | +from tests.utils import get_random_suffix, get_resources, google_api_key |
| 24 | + |
| 25 | + |
| 26 | +@pytest.fixture(scope="module", params=["static", "flexible"]) |
| 27 | +def index_and_models(request): |
| 28 | + """Setup the index for integration tests.""" |
| 29 | + schema_type = request.param |
| 30 | + graph_store, _, query_llm, embed_model = get_resources( |
| 31 | + f"e2e_rag_{schema_type}_{get_random_suffix()}", |
| 32 | + clean_up=True, |
| 33 | + use_flexible_schema=(schema_type == "flexible"), |
| 34 | + ) |
| 35 | + |
| 36 | + loader = WikipediaReader() |
| 37 | + documents = loader.load_data(pages=["Google"], auto_suggest=False) |
| 38 | + |
| 39 | + index_llm = GoogleGenAI( |
| 40 | + model="gemini-1.5-pro-latest", |
| 41 | + api_key=google_api_key, |
| 42 | + ) |
| 43 | + Settings.llm = query_llm |
| 44 | + Settings.embed_model = embed_model |
| 45 | + |
| 46 | + index = PropertyGraphIndex.from_documents( |
| 47 | + documents, |
| 48 | + property_graph_store=graph_store, |
| 49 | + llm=query_llm, |
| 50 | + embed_model=embed_model, |
| 51 | + embed_kg_nodes=True, |
| 52 | + kg_extractors=[ |
| 53 | + SchemaLLMPathExtractor( |
| 54 | + llm=index_llm, |
| 55 | + max_triplets_per_chunk=1000, |
| 56 | + num_workers=4, |
| 57 | + ) |
| 58 | + ], |
| 59 | + show_progress=True, |
| 60 | + ) |
| 61 | + yield index, query_llm, embed_model |
| 62 | + graph_store.clean_up() |
| 63 | + |
| 64 | + |
| 65 | +@pytest.mark.flaky(retries=3, only_on=[AssertionError], delay=1) |
| 66 | +def test_e2e_rag(index_and_models): |
| 67 | + """ |
| 68 | + Test End-to-End RAG flow from document loading to querying with a custom retriever. |
| 69 | + This test is parameterized to run for both 'static' and 'flexible' schemas. |
| 70 | + """ |
| 71 | + index, llm, embed_model = index_and_models |
| 72 | + |
| 73 | + retriever = SpannerGraphCustomRetriever( |
| 74 | + graph_store=index.property_graph_store, |
| 75 | + embed_model=embed_model, |
| 76 | + llm_text_to_gql=llm, |
| 77 | + include_raw_response_as_metadata=True, |
| 78 | + verbose=True, |
| 79 | + similarity_top_k=10, |
| 80 | + path_depth=3, |
| 81 | + ) |
| 82 | + |
| 83 | + query_engine = RetrieverQueryEngine(retriever=retriever) |
| 84 | + |
| 85 | + # Query 1: Parent company |
| 86 | + response1 = query_engine.query("what is parent company of Google?") |
| 87 | + |
| 88 | + # Query 2: Office locations |
| 89 | + response2 = query_engine.query("Where are all the Google offices located?") |
| 90 | + |
| 91 | + # Query 3: Products |
| 92 | + response3 = query_engine.query("Some Products of Google?") |
| 93 | + |
| 94 | + assert any( |
| 95 | + ( |
| 96 | + "Alphabet" in str(response1), |
| 97 | + "Mountain View" in str(response2), |
| 98 | + ( |
| 99 | + "Search" in str(response3) |
| 100 | + or "Android" in str(response3) |
| 101 | + or "Chrome" in str(response3) |
| 102 | + ), |
| 103 | + ) |
| 104 | + ) |
0 commit comments