Skip to main content
Oracle AI 数据库通过在单一系统中将非结构化内容的语义搜索与业务数据的关系查询相结合,支持以文档为中心的 AI 工作流。这使得构建检索工作流(如 RAG)无需将数据和向量拆分到多个数据库中。 本指南将介绍如何:
  • 从 Python 连接到 Oracle 数据库
  • 使用 OracleDocLoader 加载文档(来自数据库表、文件或目录)
  • 使用 OracleTextSplitter 对内容分块,以备嵌入和检索
为什么要在数据库内进行文档处理? 您可以将 Oracle 数据库的能力——安全性、事务、可扩展性和高可用性——应用于加载、分块和存储 AI 搜索与检索内容的同一流程中。
如果您刚开始使用 Oracle 数据库,可以探索 免费的 Oracle 26 AI,它提供了简单的入门方式。在使用数据库时,建议避免将 SYSTEM 用户用于应用负载,而是创建具有最低所需权限的专用用户。完整的端到端设置演示,请参阅 Oracle AI 向量搜索演示 notebook。关于用户管理的背景信息,请参阅官方 Oracle 指南

前提条件

安装 langchain-oracledbpython-oracledb 驱动将作为依赖自动安装。
pip install -qU langchain-oracledb

连接到 Oracle 数据库

以下示例代码演示如何连接到 Oracle 数据库。默认情况下,python-oracledb 以”Thin”模式运行,直接连接到 Oracle 数据库,无需 Oracle 客户端库。但使用客户端库时可获得一些额外功能,此时称为”Thick”模式。两种模式均全面支持 Python Database API v2.0 规范。请参阅此 指南 了解各模式支持的功能。如果无法使用 thin 模式,可切换到 thick 模式。
import sys

import oracledb

# Please update with your username, password, hostname, port and service_name
username = "<username>"
password = "<password>"
dsn = "<hostname>:<port>/<service_name>"

connection = oracledb.connect(user=username, password=password, dsn=dsn)
print("Connection successful!")
现在创建一个表并插入一些示例文档用于测试。
try:
    cursor = conn.cursor()

    drop_table_sql = """drop table if exists demo_tab"""
    cursor.execute(drop_table_sql)

    create_table_sql = """create table demo_tab (id number, data clob)"""
    cursor.execute(create_table_sql)

    insert_row_sql = """insert into demo_tab values (:1, :2)"""
    rows_to_insert = [
        (
            1,
            "If the answer to any preceding questions is yes, then the database stops the search and allocates space from the specified tablespace; otherwise, space is allocated from the database default shared temporary tablespace.",
        ),
        (
            2,
            "A tablespace can be online (accessible) or offline (not accessible) whenever the database is open.\nA tablespace is usually online so that its data is available to users. The SYSTEM tablespace and temporary tablespaces cannot be taken offline.",
        ),
        (
            3,
            "The database stores LOBs differently from other data types. Creating a LOB column implicitly creates a LOB segment and a LOB index. The tablespace containing the LOB segment and LOB index, which are always stored together, may be different from the tablespace containing the table.\nSometimes the database can store small amounts of LOB data in the table itself rather than in a separate LOB segment.",
        ),
    ]
    cursor.executemany(insert_row_sql, rows_to_insert)

    conn.commit()

    print("Table created and populated.")
    cursor.close()
except Exception as e:
    print("Table creation failed.")
    cursor.close()
    conn.close()
    sys.exit(1)

加载文档

用户可以通过适当配置加载器参数,灵活地从 Oracle 数据库、文件系统或两者同时加载文档。有关这些参数的详细说明,请参阅 Oracle AI 向量搜索指南 使用 OracleDocLoader 的一大优势是它能够处理 150 多种不同的文件格式,无需为不同文档类型使用多个加载器。完整支持格式列表,请参阅 Oracle Text 支持的文档格式 下面是演示如何使用 OracleDocLoader 的示例代码片段:
from langchain_oracledb.document_loaders.oracleai import OracleDocLoader
from langchain_core.documents import Document

"""
# loading a local file
loader_params = {}
loader_params["file"] = "<file>"

# loading from a local directory
loader_params = {}
loader_params["dir"] = "<directory>"
"""

# loading from Oracle Database table
loader_params = {
    "owner": "<owner>",
    "tablename": "demo_tab",
    "colname": "data",
}

""" load the docs """
loader = OracleDocLoader(conn=conn, params=loader_params)
docs = loader.load()

""" verify """
print(f"Number of docs loaded: {len(docs)}")
# print(f"Document-0: {docs[0].page_content}") # content

拆分文档

文档大小可能差异很大,从很小到非常大不等。用户通常希望将文档分块为较小的片段,以便生成嵌入向量。此拆分过程提供了多种自定义选项。有关这些参数的详细说明,请参阅 Oracle AI 向量搜索指南 下面是演示如何实现此功能的示例代码:
from langchain_oracledb.document_loaders.oracleai import OracleTextSplitter
from langchain_core.documents import Document

"""
# Some examples
# split by chars, max 500 chars
splitter_params = {"split": "chars", "max": 500, "normalize": "all"}

# split by words, max 100 words
splitter_params = {"split": "words", "max": 100, "normalize": "all"}

# split by sentence, max 20 sentences
splitter_params = {"split": "sentence", "max": 20, "normalize": "all"}
"""

# split by default parameters
splitter_params = {"normalize": "all"}

# get the splitter instance
splitter = OracleTextSplitter(conn=conn, params=splitter_params)

list_chunks = []
for doc in docs:
    chunks = splitter.split_text(doc.page_content)
    list_chunks.extend(chunks)

""" verify """
print(f"Number of Chunks: {len(list_chunks)}")
# print(f"Chunk-0: {list_chunks[0]}") # content

端到端演示

请参阅完整演示指南 Oracle AI 向量搜索端到端演示指南,借助 Oracle AI 向量搜索构建完整的 RAG 流水线。