跳到主要内容
Vane Data / 核心概念

AI 函数

Vane AI 函数支持在 SQL 或 Python 中生成文本、结构化结果和向量。每个输入行都会在同一行得到一个结果。

本页只介绍 Expression UDF 接口。SQL 和 Python 都可以构建保持行数不变的操作,执行语义相同。

Python 与 SQL 的完整签名、Relation 重载、Provider 选项和失败语义,见 AI 函数 API 参考。

1. 选择操作

Vane 目前提供以下两种 AI 操作:

操作SQL ExpressionPython Expression结果支持的 Provider
生成文本或结构化输出ai_prompt(messages, ...)vane.ai.prompt(expression, ...)每个输入行得到一个 VARCHAR 或原生 STRUCTopenai、google、anthropic、vllm
生成向量ai_embed(text, ...)vane.ai.embed(expression, ...)每个输入行得到一个定长 FLOAT[n]openai、google、transformers

两种操作都保持输入行数不变。在投影中保留后续需要的输入列,使用 SQL AS 或 Python .alias() 命名生成列,并携带稳定 ID,以便将每个结果追溯到对应输入。

Provider、模型和操作设置对整个操作生效,不能逐行变化。在 SQL 中,顶层设置使用命名参数,Provider 请求参数和执行设置放在 options := struct_pack(...) 中。

2. Provider

请根据所需操作和模型运行位置选择 Provider。Vane 只在使用时加载相应集成,因此只需安装所选 Provider 的可选依赖。

shell
uv pip install vane-ai
ProviderPromptEmbed运行时与配置
openai支持支持OpenAI API 或 OpenAI 兼容端点;安装 vane-ai[openai],并在 worker 环境设置 OPENAI_API_KEY
google支持支持Google Generative AI;安装 vane-ai[google],并在 worker 环境设置 GOOGLE_API_KEY
anthropic支持不支持Anthropic Messages API;安装 vane-ai[anthropic],并在 worker 环境设置 ANTHROPIC_API_KEY
vllm支持不支持本地或远程 vLLM 引擎;安装 vane-ai[vllm],确保运行环境能够访问模型;需要 GPU Actor 时使用 Ray
transformers不支持支持本地 SentenceTransformers 模型;安装 vane-ai[transformers]

需要可复现结果时,请显式设置 provider 和 model。可用的模型 ID 及其限制由所配置的端点决定。

3. 配置 OpenAI

下面的示例使用 OpenAI Provider。先安装客户端,并把凭证提供给实际执行查询的进程:

shell
uv pip install 'vane-ai[openai]'
export OPENAI_API_KEY="<your-token>"

OpenAI 客户端在 worker 上创建时读取 OPENAI_API_KEY。该变量既可以保存 OpenAI API 密钥,也可以保存兼容服务签发的令牌。Vane 默认使用 OpenAI 官方 API 根地址。对于 Ray 作业,每个可能执行 Expression 的 worker 都必须安装客户端并配置该变量。

使用兼容端点时,需要像下面的示例一样,在 struct_pack(...) 中或以 Python 关键字参数显式传入非敏感的 base_url。该值应为通常以 /v1 结尾的 API 根地址,而不是 /chat/completions 这样的具体接口路径。如果兼容端点实现了 Chat Completions,但没有实现 OpenAI Responses API,还要在 SQL 中设置 use_chat_completions := true,或在 Python 中设置 use_chat_completions=True。

令牌应始终保存在 OPENAI_API_KEY 中。不要把它放进 SQL、Python 选项、notebook 输出或已提交文件;Vane 会拒绝疑似凭证的选项字段。

4. SQL Expression

如果上下游转换以查询为主,可以直接使用 SQL。Vane 连接会注册 ai_prompt 和 ai_embed。Provider、模型和操作设置使用命名参数,Provider 请求参数和执行设置放在 options Struct 中。

Ray 是 Vane 的默认 runner,调用 show() 时会用它执行示例。如果已有配置选择了本地 runner,请在创建连接前调用 vane.configure(runner="ray")。

使用 ai_prompt 生成文本

example.py
import vane


con = vane.connect()
documents = con.sql("""
    SELECT *
    FROM (VALUES
        (1, 'The customer asked for a refund after a duplicate charge.'),
        (2, 'The shipment is delayed because the address is incomplete.')
    ) AS t(document_id, text)
""")


prompted = con.sql("""
    SELECT
        document_id,
        text,
        ai_prompt(
            text,
            system_message := 'Write one short support summary. Return plain text only.',
            provider := 'openai',
            model := 'gpt-4o-mini',
            options := struct_pack(
                base_url := 'https://api.openai.com/v1',
                timeout := 60.0,
                actor_number := 1,
                max_concurrency_per_actor := 4,
                max_output_tokens := 64,
                temperature := 0.0
            )
        ) AS summary
    FROM documents
    ORDER BY document_id
""")


prompted.show()

actor_number 用于设置 Provider Actor 数量。对于 Prompt 调用,max_concurrency_per_actor 限制每个 Actor 内同时进行的 API 请求数。建议从保守值开始,只在端点的速率与容量限制内提高任一参数。

使用 ai_embed 生成向量

example.py
embedded = con.sql("""
    SELECT
        document_id,
        text,
        ai_embed(
            text,
            provider := 'openai',
            model := 'text-embedding-3-small',
            options := struct_pack(
                base_url := 'https://api.openai.com/v1',
                encoding_format := 'float',
                normalize := true,
                actor_number := 1
            )
        ) AS embedding
    FROM documents
    ORDER BY document_id
""")


embedded.show()

每个 Embed Expression 都返回定长 FLOAT[n]。Vane 为支持的默认模型提供维度元数据。使用 OpenAI 兼容端点、未知模型或支持缩短输出维度的模型时,应显式传入正整数 dimensions := n。normalize := true 会对每个非 NULL 向量执行 L2 归一化。

5. Python Expression

Python Expression 与 SQL 遵循相同的行数和返回结果规则。Provider 请求参数和执行设置通过关键字参数传入;未知选项会被拒绝。

example.py
import vane


con = vane.connect()
documents = con.sql("""
    SELECT *
    FROM (VALUES
        (1, 'The customer asked for a refund after a duplicate charge.'),
        (2, 'The shipment is delayed because the address is incomplete.')
    ) AS t(document_id, text)
""")


prompted = documents.select(
    vane.col("document_id"),
    vane.col("text"),
    vane.ai.prompt(
        vane.col("text"),
        provider="openai",
        model="gpt-4o-mini",
        base_url="https://api.openai.com/v1",
        timeout=60.0,
        actor_number=1,
        max_concurrency_per_actor=4,
        max_output_tokens=64,
        temperature=0.0,
        system_message="Write one short support summary. Return plain text only.",
    ).alias("summary"),
).order("document_id")


embedded = documents.select(
    vane.col("document_id"),
    vane.col("text"),
    vane.ai.embed(
        vane.col("text"),
        provider="openai",
        model="text-embedding-3-small",
        base_url="https://api.openai.com/v1",
        timeout=60.0,
        actor_number=1,
        encoding_format="float",
        normalize=True,
    ).alias("embedding"),
).order("document_id")


prompted.show()
embedded.show()

同一组关键字参数也适用于返回 Relation 的调用,例如 vane.ai.prompt(documents, vane.col("text"), ...)。凭证应保留在 worker 环境中,不要作为函数选项传入。