基础核心
🧠 系统架构
+-------------------------+
| 用户界面 UI |
| (Web / CLI / API) |
+-----------+-------------+
|
v
+---------------+----------------+
| Nova AI Core Engine | ←→ 自定义插件系统(PDF、OCR、网页抓取等)
| (基于 DeepSeek + LangChain) |
+---------------+----------------+
|
+--------------+---------------+
| 模型上下文协议 (MCP Proxy) |
| 请求预处理 + 上下文路由 + 日志 |
+--------------+---------------+
|
v
+---------------+----------------+
| 本地知识数据库 (Chroma) |
| + 文档解析 + 向量检索(RAG) |
+---------------+----------------+
|
v
本地大模型 Ollama / DeepSeek-R1
💡 技术栈搭建
模块 | 工具 | 描述 |
---|---|---|
大模型 | DeepSeek-R1 + Ollama | 高性能本地模型 |
知识库 | ChromaDB | 本地向量数据库 |
检索增强生成 | LangChain + Faiss | 实现 RAG 检索-生成 |
协议中转 | 自定义 MCP Router(Flask) | 模拟模型上下文协议 |
插件系统 | Python 模块热加载 | 动态扩展功能如读取本地 Word/PDF |
UI界面(可选) | Gradio / Streamlit / FastAPI | 轻量交互方式 |
🔧 核心实操步骤
第 1 步:部署 Ollama + DeepSeek-R1 模型
ollama run deepseek-coder:instruct
✔ 本地离线运行,响应速度快
✔ 不依赖网络
第 2 步:构建 RAG 知识库
from langchain.vectorstores import Chroma
from langchain.embeddings import OllamaEmbeddings
embeddings = OllamaEmbeddings(model="deepseek-coder:instruct")
db = Chroma(persist_directory="./vector_store", embedding_function=embeddings)
db.add_texts(["你的本地文档内容...", "知识内容 2...", "资料内容 3..."])
第 3 步:自定义 MCP 上下文协议中转器
# mcp_router.py
from flask import Flask, request, jsonify
from rag_pipeline import get_rag_answer
app = Flask(__name__)
@app.route('/mcp', methods=['POST'])
def mcp_entry():
data = request.json
question = data['query']
response = get_rag_answer(question)
return jsonify({"response": response})
app.run(port=5001)
第 4 步:插件式加载文档解析能力(Word / PDF / 网页)
# 插件架构示例
import importlib.util
def load_plugin(path):
spec = importlib.util.spec_from_file_location("plugin", path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
plugin = load_plugin("./plugins/pdf_reader.py")
text = plugin.read("/your/pdf/path.pdf")
第 5 步:构建用户界面(可选)
用 Gradio:
import gradio as gr
import requests
def ask(query):
resp = requests.post("http://localhost:5001/mcp", json={"query": query})
return resp.json()["response"]
gr.Interface(fn=ask, inputs="text", outputs="text").launch()
二次开发
🧩 一、向量知识库模块(文档自动入库)
1. 文本向量化并保存到 Chroma
# vector_db.py
from langchain.vectorstores import Chroma
from langchain.embeddings import OllamaEmbeddings
class KnowledgeVectorStore:
def __init__(self, persist_dir="./vector_store"):
self.embeddings = OllamaEmbeddings(model="deepseek-coder:instruct")
self.db = Chroma(persist_directory=persist_dir, embedding_function=self.embeddings)
def add_docs(self, texts: list, metadata=None):
self.db.add_texts(texts, metadatas=metadata)
def query(self, query: str, k: int = 3):
return self.db.similarity_search(query, k=k)
📁 二、文件处理插件(PDF / Word / 网页)
1. PDF 插件(插件文件:plugins/pdf_reader.py
)
# plugins/pdf_reader.py
import fitz # PyMuPDF
def read(filepath):
doc = fitz.open(filepath)
text = ""
for page in doc:
text += page.get_text()
return text
2. Word 插件(plugins/word_reader.py
)
# plugins/word_reader.py
from docx import Document
def read(filepath):
doc = Document(filepath)
return "\n".join([p.text for p in doc.paragraphs])
🔌 三、插件加载机制
# plugin_loader.py
import importlib.util
import os
def load_plugins(plugin_dir='./plugins'):
plugins = {}
for filename in os.listdir(plugin_dir):
if filename.endswith('.py'):
path = os.path.join(plugin_dir, filename)
name = filename[:-3]
spec = importlib.util.spec_from_file_location(name, path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
plugins[name] = module
return plugins
💬 四、RAG 问答模块(带历史上下文)
# rag_pipeline.py
from vector_db import KnowledgeVectorStore
from langchain.llms import Ollama
from langchain.chains import ConversationalRetrievalChain
class RagAgent:
def __init__(self):
self.vector_db = KnowledgeVectorStore()
self.llm = Ollama(model="deepseek-coder:instruct")
self.qa_chain = ConversationalRetrievalChain.from_llm(
self.llm,
retriever=self.vector_db.db.as_retriever(),
)
self.chat_history = []
def answer(self, question: str):
result = self.qa_chain.run({'question': question, 'chat_history': self.chat_history})
self.chat_history.append((question, result))
return result
🌐 五、构建 Flask API 服务
# app.py
from flask import Flask, request, jsonify
from rag_pipeline import RagAgent
from plugin_loader import load_plugins
app = Flask(__name__)
agent = RagAgent()
plugins = load_plugins()
@app.route('/api/upload', methods=['POST'])
def upload():
file = request.files['file']
plugin_type = request.args.get("type") # 'pdf_reader' / 'word_reader'
plugin = plugins.get(plugin_type)
if not plugin:
return jsonify({"error": "Unsupported plugin"}), 400
text = plugin.read(file)
agent.vector_db.add_docs([text])
return jsonify({"message": "文档已成功入库"})
@app.route('/api/query', methods=['POST'])
def query():
q = request.json.get("query")
if not q:
return jsonify({"error": "缺少 query 参数"}), 400
result = agent.answer(q)
return jsonify({"response": result})
if __name__ == "__main__":
app.run(port=5001)
🌈 六、前端调用示例(Gradio)
# ui.py
import gradio as gr
import requests
def chat_fn(question):
r = requests.post("http://localhost:5001/api/query", json={"query": question})
return r.json().get("response", "出错了")
gr.Interface(fn=chat_fn, inputs="text", outputs="text", title="Nova 本地知识AI").launch()
🚀 Bonus:上传文件界面(可拓展)
用 FastAPI + Vue、React 或 Gradio 组合一个上传+问答的前后端界面,只需调用 /api/upload
接口即可。