目录

从一句“让它能回答文档问题”开始

Milvus:当你第一次意识到“记忆不能靠prompt”

LlamaIndex:让“向量搜索”变成“知识检索”

查询阶段:控制“回答质量”的开始

LangChain:让系统“知道自己在干什么”

最终完整调用链

 

从一句“让它能回答文档问题”开始

        最初的需求永远很简单:

“把这些文档喂给模型,让它能回答问题。”

        你可能先写了一个最原始的版本:

prompt = f"""
根据以下内容回答问题:
{doc_text}
问题:{question}
"""

        然后你很快发现:文档多了,模型开始乱说。

        这不是模型的问题。这是你没有给它一个“记忆系统”。

Milvus:当你第一次意识到“记忆不能靠prompt”

        你第一次接触Milvus,往往不是因为它有多酷,而是因为——你撑不住了

你真正需要的,不是“存文本”,而是“存相似度

        于是你开始这样设计:

文档 → 切块 → embedding → 向量库

        Milvus在系统里,从一开始就应该是底层设施


第一次配置Milvus

from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection

connections.connect(
    alias="default",
    host="localhost",
    port="19530"
)

fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
    FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=768),
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=2048),
]

schema = CollectionSchema(fields, description="knowledge base")
collection = Collection("kb", schema)

         这里你必须明白三件事:

  • dim必须和embedding模型一致
  • Milvus不关心你text是什么语义
  • 它只负责“算得快”

LlamaIndex:让“向量搜索”变成“知识检索”

        但你很快会发现:“能搜到 ≠ 能用”

        这时候,LlamaIndex登场。

        如果你自己写过完整RAG,你一定写过这些:

  • chunk切分
  • overlap
  • embedding
  • TopK
  • 拼上下文

用 LlamaIndex 接管这些脏活

from llama_index.vector_stores.milvus import MilvusVectorStore
from llama_index.core import StorageContext, VectorStoreIndex

在 LlamaIndex 中配置 Milvus(关键)

vector_store = MilvusVectorStore(
    uri="http://localhost:19530",
    collection_name="kb",
    dim=768,
    overwrite=False
)

storage_context = StorageContext.from_defaults(
    vector_store=vector_store
)

        这段代码意味着什么?

        从这一刻开始,LlamaIndex接管了Milvus的使用方式。

        你不再需要直接操作collection,而是只用关心:数据进来,问题出去

构建索引:你终于不用自己写 chunk 逻辑了

 

from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader("./docs").load_data()

index = VectorStoreIndex.from_documents(
    documents,
    storage_context=storage_context
)

        这里发生了五件事:

  1. 文档被读取
  2. 被切成合适的chunk
  3. 自动embedding
  4. 写入Milvus
  5. metadata自动绑定

        你第一次感觉到:

        这是工程,而不是prompt技巧。

查询阶段:控制“回答质量”的开始

query_engine = index.as_query_engine(
    similarity_top_k=5
)

response = query_engine.query("系统支持哪些部署方式?")
print(response)

        这一步的意义,不是“能不能回答”,而是——回答开始稳定了

LangChain:让系统“知道自己在干什么”

        但系统一上线,你会遇到一个新问题,“不是每个问题,都该查知识库。”

        LangChain出现的时机,几乎总是系统复杂化的那一天

把LlamaIndex,变成LangChain的工具

from langchain.tools import Tool

def search_knowledge(query: str) -> str:
    return str(query_engine.query(query))

knowledge_tool = Tool(
    name="KnowledgeSearch",
    func=search_knowledge,
    description="用于查询内部知识库"
)

        这一刻非常重要:

        LangChain不再关心Milvus,也不关心LlamaIndex

        它只知道:“我有一个工具,可以查资料。

初始化Agent“决策层”

from langchain.agents import initialize_agent

agent = initialize_agent(
    tools=[knowledge_tool],
    llm=llm,
    agent="openai-functions",
    verbose=True
)

        此时,你的系统有了“判断能力”。

最终完整调用链

用户输入
 ↓
LangChain Agent
 ↓(决定是否查知识库)
LlamaIndex QueryEngine
 ↓
Milvus 向量搜索
 ↓
LLM 生成答案
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐