以编程方式使用文档

Kinetica 是一个支持文本到 SQL 生成集成的数据库。

本笔记本演示如何使用 Kinetica 将自然语言转换为 SQL 并简化数据检索过程。此演示旨在展示文本生成工作流程,而非 LLM 的能力。

概述

使用 Kinetica LLM 工作流程,您可以在数据库中创建一个 LLM 上下文,提供 推理所需的信息,包括表、注解、规则和 样本。调用 ChatKinetica.load_messages_from_context() 将检索 数据库中的上下文信息,以便可用于创建聊天提示。

聊天提示由 SystemMessageHumanMessage/AIMessage that contain the samples which are question/SQL 对组成。您可以向此列表追加样本,但这并非用于 促进典型的自然语言对话。

从聊天提示创建链并执行后,Kinetica LLM 将 从输入生成 SQL。可选地,您可以使用 KineticaSqlOutputParser to 执行 SQL 并将结果作为 DataFrame 返回。

目前,支持 2 个用于 SQL 生成的 LLM:

1. **Kinetica SQL-GPT**:此 LLM 基于 OpenAI ChatGPT API。 2. **Kinetica SqlAssist**:此 LLM 专门构建用于与 Kinetica 数据库集成,可运行在安全的客户 premises。

在此演示中,我们将使用 **SqlAssist**。请参阅 Kinetica 文档 site for more information.

前置条件

要开始使用,您需要 Kinetica DB 实例。如果您没有,可以 获取一个 免费开发实例.

您需要安装以下包...

pip install -qU langchain-kinetica faker

数据库连接

您必须在以下环境变量中设置数据库连接。如果您使用虚拟环境,可以在 .env 项目文件中设置:

  • * KINETICA_URL:数据库连接 URL(例如 http://localhost:9191)
  • * KINETICA_USER:数据库用户
  • * KINETICA_PASSWD:安全密码。

如果可以创建 KineticaChatLLM 的实例,则表示您已成功连接。

from langchain_kinetica import ChatKinetica

kinetica_llm = ChatKinetica()

# Test table we will create
table_name = "demo.user_profiles"

# LLM Context we will create
kinetica_ctx = "demo.test_llm_ctx"
2026-02-02 19:39:09.975 INFO     [GPUdb] Connected to Kinetica! (host=http://localhost:19191 api=7.2.3.3 server=7.2.3.5)

创建测试数据

在生成 SQL 之前,我们需要创建一个 Kinetica 表和一个可以推理该表的 LLM 上下文。

创建一些假用户资料

我们将使用 faker 包创建一个包含 100 个假资料的数据框。

from collections.abc import Generator

from faker import Faker

Faker.seed(5467)
faker = Faker(locale="en-US")


def profile_gen(count: int) -> Generator:
    for p_id in range(count):
        rec = dict(id=p_id, **faker.simple_profile())
        rec["birthdate"] = pd.Timestamp(rec["birthdate"])
        yield rec


load_df = pd.DataFrame.from_records(data=profile_gen(100), index="id")
print(load_df.head())
            username             name sex  \
id
0       eduardo69       Haley Beck   F
1        lbarrera  Joshua Stephens   M
2         bburton     Paula Kaiser   F
3       melissa49      Wendy Reese   F
4   melissacarter      Manuel Rios   M

                                                address                    mail  \
id
0   59836 Carla Causeway Suite 939\nPort Eugene, I...  meltondenise@yahoo.com
1   3108 Christina Forges\nPort Timothychester, KY...     erica80@hotmail.com
2                    Unit 7405 Box 3052\nDPO AE 09858  timothypotts@gmail.com
3   6408 Christopher Hill Apt. 459\nNew Benjamin, ...        dadams@gmail.com
4    2241 Bell Gardens Suite 723\nScottside, CA 38463  williamayala@gmail.com

    birthdate
id
0  1999-08-22
1  1926-04-17
2  1935-08-19
3  1990-07-10
4  1932-11-30

从数据框创建 Kinetica 表

from gpudb import GPUdbTable

gpudb_table = GPUdbTable.from_df(
    load_df,
    db=kinetica_llm.kdbc,
    table_name=table_name,
    clear_table=True,
    load_data=True,
)

# See the Kinetica column types
print(gpudb_table.type_as_df())
        name    type   properties
0   username  string     [char32]
1       name  string     [char32]
2        sex  string      [char2]
3    address  string     [char64]
4       mail  string     [char32]
5  birthdate    long  [timestamp]

创建 LLM 上下文

您可以使用 Kinetica Workbench UI 创建 LLM 上下文,也可以使用 CREATE OR REPLACE CONTEXT syntax.

这里我们从引用我们创建的表的 SQL 语法创建一个上下文。

from gpudb import GPUdbSamplesClause, GPUdbSqlContext, GPUdbTableClause

table_ctx = GPUdbTableClause(table=table_name, comment="Contains user profiles.")

samples_ctx = GPUdbSamplesClause(
    samples=[
        (
            "How many users born after 1970 are there?",
            f"""
            select count(1) as num_users
                from {table_name}
                where birthdate > '1970-01-01';
            """,
        )
    ]
)

context_sql = GPUdbSqlContext(
    name=kinetica_ctx, tables=[table_ctx], samples=samples_ctx
).build_sql()

print(context_sql)
count_affected = kinetica_llm.kdbc.execute(context_sql)
count_affected
CREATE OR REPLACE CONTEXT "demo"."test_llm_ctx" (
    TABLE = "demo"."user_profiles",
    COMMENT = 'Contains user profiles.'
),
(
    SAMPLES = (
        'How many users born after 1970 are there?' = 'select count(1) as num_users
    from demo.user_profiles
    where birthdate > ''1970-01-01'';' )
)

1

使用 LangChain 进行推理

在下面的示例中,我们将从之前创建的表和 LLM 上下文创建一个链。这个链将生成 SQL 并将结果数据作为 dataframe 返回。

从 kinetica 数据库加载聊天提示

load_messages_from_context() 函数将从数据库中检索上下文并将其转换为我们用于创建 ChatPromptTemplate.

from langchain_core.prompts import ChatPromptTemplate

# load the context from the database
ctx_messages = kinetica_llm.load_messages_from_context(kinetica_ctx)

# Add the input prompt. This is where input question will be substituted.
ctx_messages.append(("human", "{input}"))

# Create the prompt template.
prompt_template = ChatPromptTemplate.from_messages(ctx_messages)
print(prompt_template.pretty_repr())
================================ System Message ================================

CREATE TABLE demo.user_profiles AS
(
    username VARCHAR (32) NOT NULL,
    name VARCHAR (32) NOT NULL,
    sex VARCHAR (2) NOT NULL,
    address VARCHAR (64) NOT NULL,
    mail VARCHAR (32) NOT NULL,
    birthdate TIMESTAMP NOT NULL
);
COMMENT ON TABLE demo.user_profiles IS 'Contains user profiles.';

================================ Human Message =================================

How many users born after 1970 are there?

================================== Ai Message ==================================

select count(1) as num_users
    from demo.user_profiles
    where birthdate > '1970-01-01';

================================ Human Message =================================

{input}

创建链

这个链的最后一个元素是 KineticaSqlOutputParser ,它将执行 SQL 并返回一个 dataframe。这是可选的,如果我们省略它,则只返回 SQL。

from langchain_kinetica import (
    KineticaSqlOutputParser,
    KineticaSqlResponse,
)

chain = prompt_template | kinetica_llm | KineticaSqlOutputParser(kdbc=kinetica_llm.kdbc)

生成 SQL

我们创建的链将一个问题作为输入并返回一个 KineticaSqlResponse ,其中包含生成的 SQL 和数据。该问题必须与我们用来创建提示的 LLM 上下文相关。

# Here you must ask a question relevant to the LLM context provided in the
# prompt template.
response: KineticaSqlResponse = chain.invoke(
    {"input": "What users were born after 1990?"}
)

print(f"SQL: {response.sql}")
print(response.dataframe.head())
SQL: SELECT *
FROM demo.user_profiles
WHERE birthdate > '1990-01-01';
        username             name sex  \
0      eduardo69       Haley Beck   F
1      melissa49      Wendy Reese   F
2        james26  Patricia Potter   F
3    mooreandrew    Wendy Ramirez   F
4  melissabutler      Alexa Kelly   F

                                                address                    mail  \
0  59836 Carla Causeway Suite 939\nPort Eugene, I...  meltondenise@yahoo.com
1  6408 Christopher Hill Apt. 459\nNew Benjamin, ...        dadams@gmail.com
2          7977 Jonathan Meadow\nJerryside, OH 55205      jpatrick@gmail.com
3        8089 Gonzalez Fields\nJordanville, KS 22824    mathew05@hotmail.com
4              1904 Burke Roads\nPort Anne, DE 81252     douglas38@yahoo.com

    birthdate
0 1999-08-25
1 1990-07-13
2 2010-03-21
3 2000-03-25
4 2023-02-01