diff --git a/VectorGraphRag/pom.xml b/VectorGraphRag/pom.xml
new file mode 100644
index 0000000..c28d0b1
--- /dev/null
+++ b/VectorGraphRag/pom.xml
@@ -0,0 +1,103 @@
+
+
+ 4.0.0
+
+ com.zjkl
+ vector-graph-rag
+ 0.1.0
+ jar
+ Vector Graph RAG
+ Graph RAG using pure vector search with Milvus
+
+
+ 21
+ 21
+ 21
+ UTF-8
+ 3.5.11
+ 2.6.18
+ 2.13.2
+ 3.2.0
+ 1.18.44
+ 2.0.17
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
+
+
+ io.milvus
+ milvus-sdk-java
+ ${milvus-sdk.version}
+
+
+
+ com.google.code.gson
+ gson
+ ${gson.version}
+
+
+
+ com.github.ben-manes.caffeine
+ caffeine
+ ${caffeine.version}
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.14.0
+
+ 21
+ 21
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+
+
+
+
diff --git a/VectorGraphRag/src/main/java/com/zjkl/vectorgraphrag/VectorGraphRAG.java b/VectorGraphRag/src/main/java/com/zjkl/vectorgraphrag/VectorGraphRAG.java
new file mode 100644
index 0000000..8cba48a
--- /dev/null
+++ b/VectorGraphRag/src/main/java/com/zjkl/vectorgraphrag/VectorGraphRAG.java
@@ -0,0 +1,451 @@
+package com.zjkl.vectorgraphrag;
+
+import com.zjkl.vectorgraphrag.config.VectorGraphRagSettings;
+import com.zjkl.vectorgraphrag.graph.Graph;
+import com.zjkl.vectorgraphrag.graph.GraphBuilder;
+import com.zjkl.vectorgraphrag.graph.GraphRetriever;
+import com.zjkl.vectorgraphrag.graph.SubGraph;
+import com.zjkl.vectorgraphrag.llm.AnswerGenerator;
+import com.zjkl.vectorgraphrag.llm.EntityExtractor;
+import com.zjkl.vectorgraphrag.llm.LLMCache;
+import com.zjkl.vectorgraphrag.llm.LLMReranker;
+import com.zjkl.vectorgraphrag.llm.OpenAiClient;
+import com.zjkl.vectorgraphrag.llm.TripletExtractor;
+import com.zjkl.vectorgraphrag.model.*;
+import com.zjkl.vectorgraphrag.storage.EmbeddingClient;
+import com.zjkl.vectorgraphrag.storage.MilvusStore;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Vector Graph RAG - Graph RAG using pure vector search with Milvus.
+ *
+ * Main entry point for building and querying a Graph RAG system.
+ * Implements the full pipeline: triplet extraction → graph building →
+ * embedding → Milvus indexing → multi-way retrieval → subgraph expansion →
+ * LLM reranking → answer generation.
+ *
+ * Example:
+ *
{@code
+ * VectorGraphRagSettings settings = VectorGraphRagSettings.builder()
+ * .openaiApiKey(System.getenv("OPENAI_API_KEY"))
+ * .milvusUri("./my_graph.db")
+ * .build();
+ *
+ * VectorGraphRAG rag = new VectorGraphRAG(settings);
+ *
+ * rag.addTexts(List.of(
+ * "Albert Einstein developed the theory of relativity.",
+ * "The theory of relativity revolutionized physics."
+ * ));
+ *
+ * QueryResult result = rag.query("What did Einstein develop?");
+ * System.out.println(result.getAnswer());
+ * }
+ */
+@Slf4j
+public class VectorGraphRAG {
+
+ private final VectorGraphRagSettings settings;
+
+ private final EmbeddingClient embeddingClient;
+ private final MilvusStore store;
+ private final GraphBuilder graphBuilder;
+ private final TripletExtractor tripletExtractor;
+ private final EntityExtractor entityExtractor;
+ private final LLMReranker reranker;
+ private final AnswerGenerator answerGenerator;
+ private final LLMCache llmCache;
+ private final OpenAiClient openAiClient;
+ private final Graph graph;
+
+ @Getter
+ private GraphRetriever retriever;
+
+ @Getter
+ private ExtractionResult extractionResult;
+
+ /**
+ * Create VectorGraphRAG with custom settings.
+ */
+ public VectorGraphRAG(VectorGraphRagSettings settings) {
+ this.settings = settings;
+ this.llmCache = settings.isUseLlmCache() ? new LLMCache() : null;
+ this.openAiClient = new OpenAiClient(settings, llmCache);
+ this.embeddingClient = new EmbeddingClient(settings, openAiClient);
+ this.store = new MilvusStore(settings, embeddingClient);
+ this.graphBuilder = new GraphBuilder(settings);
+ this.tripletExtractor = new TripletExtractor(settings, openAiClient);
+ this.entityExtractor = new EntityExtractor(settings, openAiClient);
+ this.reranker = new LLMReranker(settings, openAiClient);
+ this.answerGenerator = new AnswerGenerator(settings, openAiClient);
+ this.graph = new Graph(settings, store, embeddingClient);
+
+ // Create collections if they don't exist
+ store.createCollections(false);
+ }
+
+ /**
+ * Create VectorGraphRAG with default settings (reads OPENAI_API_KEY from environment).
+ */
+ public static VectorGraphRAG createDefault() {
+ VectorGraphRagSettings settings = VectorGraphRagSettings.builder()
+ .openaiApiKey(System.getenv().getOrDefault("OPENAI_API_KEY", ""))
+ .build();
+ return new VectorGraphRAG(settings);
+ }
+
+ // ==================== Indexing ====================
+
+ /**
+ * Add text strings to the knowledge base.
+ */
+ public ExtractionResult addTexts(List texts) {
+ return addTexts(texts, null, true);
+ }
+
+ /**
+ * Add text strings with extraction control.
+ */
+ public ExtractionResult addTexts(List texts, List ids, boolean extractTriplets) {
+ List documents = new ArrayList<>();
+ for (int i = 0; i < texts.size(); i++) {
+ String docId = (ids != null && i < ids.size()) ? ids.get(i) : UUID.randomUUID().toString();
+ documents.add(Document.builder()
+ .id(docId)
+ .text(texts.get(i))
+ .build());
+ }
+ return addDocuments(documents, extractTriplets, true);
+ }
+
+ /**
+ * Add Document objects to the knowledge base.
+ * Full indexing pipeline: extract triplets → build graph → embed → index in Milvus.
+ */
+ public ExtractionResult addDocuments(List documents, boolean extractTriplets, boolean showProgress) {
+ // Ensure all documents have IDs
+ for (Document doc : documents) {
+ if (doc.getId() == null) {
+ doc.setId(UUID.randomUUID().toString());
+ }
+ }
+
+ // Extract triplets
+ if (extractTriplets) {
+ documents = tripletExtractor.extractFromDocuments(documents, showProgress);
+ }
+
+ // Build graph
+ this.extractionResult = graphBuilder.buildFromDocuments(documents);
+
+ // Generate embeddings
+ if (showProgress) log.info("Generating embeddings...");
+
+ List entityTexts = graphBuilder.getEntityTexts();
+ List relationTexts = graphBuilder.getRelationTexts();
+ List passageTexts = graphBuilder.getPassageTexts();
+
+ List> entityEmbeddings = entityTexts.isEmpty() ? List.of()
+ : embeddingClient.embedBatch(entityTexts, showProgress);
+ List> relationEmbeddings = relationTexts.isEmpty() ? List.of()
+ : embeddingClient.embedBatch(relationTexts, showProgress);
+ List> passageEmbeddings = passageTexts.isEmpty() ? List.of()
+ : embeddingClient.embedBatch(passageTexts, showProgress);
+
+ // Build metadata for adjacency
+ List