Skip to content
xfun-devPublic

About

A complete Go RAG demo built with go-zero, Milvus, and OpenAI

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

rag-demo

一个完整的 Go 版 RAG 示例,基于 go-zero + Milvus + OpenAI,包含:

  • 知识库集合初始化
  • 文档切分与向量化入库
  • 语义检索
  • 基于检索上下文的大模型回答

依赖

  • Go 1.24+
  • Milvus,默认地址 127.0.0.1:19530
  • OpenAI API Key

配置

编辑 etc/rag-demo-api.yaml:

  • 设置 Milvus.Address
  • 设置 OpenAI.ApiKey
  • 如有需要调整 OpenAI.ChatModel、OpenAI.EmbeddingModel
  • 如有需要调整 RAG.CollectionName、ChunkSize、ChunkOverlap

启动

go run ./rag-demo.go -f etc/rag-demo-api.yaml

服务默认监听 http://127.0.0.1:8888。

API

1. 初始化知识库

curl -X POST http://127.0.0.1:8888/api/knowledge/init \
  -H "Content-Type: application/json" \
  -d '{"dropIfExists":true}'

2. 导入文档

curl -X POST http://127.0.0.1:8888/api/knowledge/ingest \
  -H "Content-Type: application/json" \
  -d '{
    "documents":[
      {
        "id":"doc-rag",
        "title":"RAG 简介",
        "source":"internal-docs/rag-intro.md",
        "content":"RAG 是 Retrieval-Augmented Generation 的缩写。它先从知识库检索相关文档,再把命中的上下文交给大模型生成回答。这样可以降低幻觉并引入私有知识。"
      },
      {
        "id":"doc-milvus",
        "title":"Milvus 用途",
        "source":"internal-docs/milvus.md",
        "content":"Milvus 是向量数据库,适合存储 embedding 并执行相似度检索。在 RAG 里,它通常承担召回相关知识块的职责。"
      },
      {
        "id":"doc-pipeline",
        "title":"典型流程",
        "source":"internal-docs/pipeline.md",
        "content":"一个典型的 RAG 流程包括文档切分、embedding、向量入库、用户提问、向量检索、上下文拼接,以及最终回答生成。"
      }
    ]
  }'

3. 单独检索

curl -X POST http://127.0.0.1:8888/api/rag/retrieve \
  -H "Content-Type: application/json" \
  -d '{
    "query":"Milvus 在 RAG 里面负责什么?",
    "topK":3
  }'

4. 生成回答

curl -X POST http://127.0.0.1:8888/api/rag/answer \
  -H "Content-Type: application/json" \
  -d '{
    "query":"请解释一个完整的 RAG 流程",
    "topK":4
  }'

/api/rag/answer 调用时序图

下面这张图对应“用户发起一次问答请求后,代码实际会怎么走”。

sequenceDiagram
    participant U as "User / Client"
    participant H as "AnswerHandler"
    participant L as "AnswerLogic"
    participant R as "rag.Service"
    participant E as "embedding.Service"
    participant M as "Milvus"
    participant G as "llm.Service"
    participant O as "OpenAI"

    U->>H: POST /api/rag/answer {query, topK, minScore, maxTokens}
    Note over H: 解析 HTTP JSON 请求<br/>生成 types.AnswerReq
    H->>L: Answer(req)
    Note over L: 把 API 参数整理成 rag.SearchOptions
    L->>R: Answer(query, searchOptions, maxTokens)

    Note over R: 先执行检索,再执行生成
    R->>R: Retrieve(query, searchOptions)
    R->>E: EmbedText(query)
    E->>O: 调用 Embeddings API<br/>把问题转成向量
    O-->>E: query vector
    E-->>R: []float32

    R->>M: Search(vector, topK)<br/>在 vector 字段做相似度搜索
    M-->>R: topK hits(doc_id, title, content, score...)

    alt 没有命中上下文
        R-->>L: 返回“根据当前知识库内容,我还不能确定”
    else 命中相关 chunk
        R->>R: buildAnswerPrompt(query, hits)
        Note over R: 把“用户问题 + 命中 chunk”拼成 prompt
        R->>G: GenerateAnswer(instructions, prompt, maxTokens)
        G->>O: 调用 Responses API<br/>生成最终回答
        O-->>G: answer text
        G-->>R: answer
        R-->>L: AnswerResult{answer, hits, model}
    end

    L-->>H: CommonResp
    H-->>U: JSON 响应
Loading

对应代码入口可以按这条链路阅读:

  1. internal/handler/answerhandler.go
  2. internal/logic/answerlogic.go
  3. internal/rag/service.go 的 Answer
  4. internal/rag/service.go 的 Retrieve
  5. internal/embedding/embedding.go
  6. internal/llm/generator.go

实现说明

  • 文档会按字符窗口切分,并保留重叠内容,避免上下文在 chunk 边界断裂。
  • Milvus 集合固定包含 doc_id、doc_title、chunk_id、source、content、vector。
  • answer 接口会先检索,再将命中的 chunk 拼成提示词,要求模型只依据知识库回答。
  • 如果没有检索到足够相关的内容,服务会直接返回“根据当前知识库内容,我还不能确定”。

验证

go test ./...
go build ./...

About

A complete Go RAG demo built with go-zero, Milvus, and OpenAI

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages