23ai 新特性之搭建企业知识库RAG系统

步骤1:环境准备与权限配置

确保Oracle 23ai数据库已启用原生向量引擎(默认开启),```sql
创建专用用户并授予相关权限:
-- 创建RAG专用用户
CREATE USER rag_user IDENTIFIED BY RAG@123456;
-- 授予必要权限
GRANT CONNECT, RESOURCE, CREATE TABLE, CREATE INDEX TO rag_user;
-- 授予向量操作、分块、嵌入相关权限
GRANT EXECUTE ON SYS.VECTOR_EMBEDDING TO rag_user;
GRANT EXECUTE ON SYS.VECTOR_CHUNKS TO rag_user;
-- 授予模型加载权限(如需导入自定义ONNX模型)
GRANT EXECUTE ON SYS.DBMS_VECTOR TO rag_user;

#### 步骤2:创建数据表,存储文档与向量数据
创建三张核心表,分别存储文档元数据、分块后的文本、向量数据(可合并为一张表,拆分更便于维护):
```sql
-- 1. 文档元数据表(存储原文档信息)
CREATE TABLE doc_archives (
    doc_id NUMBER PRIMARY KEY,
    doc_name VARCHAR2(200) NOT NULL, -- 文档名称
    doc_type VARCHAR2(50) NOT NULL, -- 文档类型(制度/产品/培训)
    doc_content CLOB NOT NULL, -- 文档完整内容
    upload_time DATE DEFAULT SYSDATE
);

-- 2. 文本块表(存储分块后的文本与向量)
CREATE TABLE doc_chunks (
    chunk_id NUMBER PRIMARY KEY,
    doc_id NUMBER REFERENCES doc_archives(doc_id), -- 关联文档ID
    chunk_content CLOB NOT NULL, -- 分块文本内容
    chunk_index NUMBER NOT NULL, -- 分块序号
    chunk_offset NUMBER NOT NULL, -- 分块在原文档中的偏移量
    chunk_emb VECTOR(1536) FLOAT32 -- 1536维文本嵌入向量
);

-- 创建关联索引,提升查询效率
CREATE INDEX idx_chunks_doc_id ON doc_chunks(doc_id);
-- 创建HNSW向量索引,优化相似检索性能
CREATE INDEX idx_chunks_emb_hnsw ON doc_chunks
USING VECTOR HNSW (chunk_emb VECTOR_COSINE_DISTANCE)
WITH (DIMENSIONS=1536, M=16, EF_CONSTRUCTION=200);

步骤3:文档分块与向量生成(全流程数据库内完成)

插入一篇企业数字化转型制度文档,调用VECTOR_CHUNKS分块,再调用VECTOR_EMBEDDING生成向量:

-- 1. 插入原文档
INSERT INTO doc_archives (doc_id, doc_name, doc_type, doc_content)
VALUES (
    1,
    '企业数字化转型实施制度',
    '制度文档',
    '企业数字化转型是指企业利用云计算、大数据、人工智能等新一代信息技术,对业务流程、组织架构、商业模式进行全面重构,核心步骤包括:1. 战略规划,明确转型目标与路径;2. 数据治理,梳理企业数据资产,建立数据标准;3. 技术选型,搭建数字化技术底座;4. 业务落地,推动各业务线数字化改造;5. 人才培养,提升员工数字化能力;6. 持续优化,根据业务反馈迭代转型方案。'
);
COMMIT;

-- 2. 文档分块并插入文本块表
INSERT INTO doc_chunks (chunk_id, doc_id, chunk_content, chunk_index, chunk_offset)
SELECT 
    ROWNUM,
    1 AS doc_id,
    chunk_text AS chunk_content,
    ROWNUM AS chunk_index,
    chunk_offset
FROM TABLE(VECTOR_CHUNKS(
    (SELECT doc_content FROM doc_archives WHERE doc_id = 1),
    100, -- 分块长度(100字/块)
    10,  -- 重叠度(10字)
    'by chars'
));
COMMIT;

-- 3. 为文本块生成向量
UPDATE doc_chunks
SET chunk_emb = VECTOR_EMBEDDING(
    'all-MiniLM-L6-v2',
    chunk_content,
    VECTOR_OUTPUT => 'FLOAT32',
    DIMENSIONS => 1536
)
WHERE doc_id = 1;
COMMIT;

步骤4:执行RAG检索,生成智能回答

用户提问“企业数字化转型的核心步骤有哪些”,生成向量后检索相似文本,再调用LLM生成回答(以调用本地Ollama为例):

DECLARE
    v_query VARCHAR2(1000) := '企业数字化转型的核心步骤有哪些';
    v_query_emb VECTOR(1536) FLOAT32;
    v_context CLOB; -- 检索到的相似文本上下文
    v_answer VARCHAR2(4000); -- LLM生成的回答
BEGIN
    -- 1. 生成用户提问的向量
    v_query_emb := VECTOR_EMBEDDING('all-MiniLM-L6-v2', v_query, VECTOR_OUTPUT => 'FLOAT32', DIMENSIONS => 1536);

    -- 2. 检索Top3相似文本块,拼接为上下文
    SELECT LISTAGG(chunk_content, ' ') WITHIN GROUP (ORDER BY similarity DESC)
    INTO v_context
    FROM (
        SELECT 
            chunk_content,
            VECTOR_SIMILARITY(chunk_emb, v_query_emb, 'COSINE') AS similarity
        FROM doc_chunks
        WHERE doc_id = 1
        ORDER BY chunk_emb <-> v_query_emb
        FETCH FIRST 3 ROWS ONLY
    );

    -- 3. 调用本地Ollama的LLaMA 3模型,生成回答
    v_answer := DBMS_CLOUD.INVOKE_FUNCTION(
        function_name => 'OLLAMA_LLM',
        params => JSON_OBJECT(
            'prompt' VALUE '基于以下上下文,回答用户问题:' || v_context || ' 用户问题:' || v_query,
            'model' VALUE 'llama3',
            'temperature' VALUE 0.2
        )
    );

    -- 4. 输出结果
    DBMS_OUTPUT.PUT_LINE('用户提问:' || v_query);
    DBMS_OUTPUT.PUT_LINE('LLM回答:' || v_answer);
END;
/

执行后,LLM会基于检索到的制度文本,生成精准的回答,且所有数据均在Oracle数据库内流转,无需外部传输,安全且高效。

Related Posts