第一阶段:添加向量类型支持

因为我们要存储 AI 的"向量(Embedding)",需要先给 Python 环境装个补丁。请在 apps/api 目录下运行:

uv add pgvector

第二阶段:定义模型 (models.py)

apps/api 下新建一个文件 models.py。我们将定义用户(User)和文档(Document)这两个核心表。

from pgvector.sqlalchemy import Vector
from sqlmodel import Field, SQLModel, Relationship, Column
from typing import List, Optional
from datetime import datetime

# 1. 用户模型
class User(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    username: str = Field(index=True, unique=True)
    email: str = Field(unique=True)
    created_at: datetime = Field(default_factory=datetime.utcnow)
    
    # 建立与文档的关联:一个用户可以拥有多份文档
    documents: List["Document"] = Relationship(back_populates="owner")

# 2. 文档模型(知识库的核心)
class Document(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    title: str = Field(index=True)
    content: str  # 原始内容
    
    # 2026 年标配:向量字段
    # 1536 是常用的向量维度(例如 OpenAI 的 text-embedding-3-small)
    embedding: Optional[List[float]] = Field(
        sa_column=Column(Vector(1536))
    )
    
    user_id: Optional[int] = Field(default=None, foreign_key="user.id")
    owner: Optional[User] = Relationship(back_populates="documents")
    
    created_at: datetime = Field(default_factory=datetime.utcnow)

第三阶段:关键点解析

3.1 为什么文档表要有 embedding

这是 RAG(检索增强生成) 的根基。

  • 当你上传一篇文章时,AI 会将其转化为一串 1536 维的数字(向量)并存入此字段。
  • 检索时,数据库会计算你问题的向量与这些数字的"余弦相似度",从而瞬间找到最相关的知识。

3.2 行级安全 (RLS) 的预留

虽然代码里还没写,但我们在模型中关联了 user_id。这在 2026 年的企业级开发中至关重要,它能确保:A 公司的员工绝对搜不到 B 公司的机密文档,实现物理级的数据隔离。

3.3 HNSW 索引预告

我们在 title 上加了 index=True,而对于 embedding 字段,我们之后会手动在数据库中创建 HNSW 索引。这是 2026 年处理千万级文档、保持毫秒级搜索性能的秘密武器。


第四阶段:同步到数据库

回到你的 main.py,确保它导入了这些模型,以便启动时自动建表:

# 在 main.py 顶部添加
from models import User, Document
# 确保在 lifespan 函数中调用了 init_db()

更新后的 main.py 完整内容如下:

from fastapi import FastAPI
from contextlib import asynccontextmanager
from database import init_db, engine
from sqlmodel import text
from models import User, Document  # 导入模型,确保表被创建

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 启动时执行
    with engine.connect() as conn:
        # 激活向量扩展,这是 2026 年 RAG 系统的核心
        conn.execute(text("CREATE EXTENSION IF NOT EXISTS vector;"))
        conn.commit()
    init_db()  # 这会创建所有表,包括 User 和 Document
    yield
    # 关闭时执行(如果需要清理资源)

app = FastAPI(lifespan=lifespan)

@app.get("/")
async def root():
    return {"message": "Hello from KnoSphere API!"}

@app.get("/health")
async def health():
    return {"status": "healthy"}

# 可选的测试代码
# if __name__ == "__main__":
#     import uvicorn
#     uvicorn.run(app, host="0.0.0.0", port=8000)

注意:如果你想运行测试服务器,请确保已经安装了 uvicorn:

uv add uvicorn[standard]

检查点:KnoSphere 的骨架已成型

  1. User 表:可以存储用户信息和权限控制。
  2. Document 表:不仅能存文本,还能存 AI 向量。
  3. 关联关系:系统已经知道哪份知识属于哪个用户。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐