游乐游手机版
首页/AI热点日报/热点详情

Hologres AI Function文本分类实战:提示词设计到KV-Cache调优全程SQL

类型:热点整理2026-07-08
HologresAIFunction将大模型推理能力嵌入数据库,无需Python脚本或服务部署,仅用SQL即可完成文本分类。以豆瓣影评情感分类为例,通过提示词表设计与KV-Cache优化,准确率从83 5%提升至95%,200条影评成本仅0 1元,兼具高效与低成本。
不写一行 Python,不部署一个服务,不训练一个模型。一条 SQL 语句就能直接调用大模型完成文本分类——听上去有点“黑科技”,但 Hologres AI Function 真的把这事儿变成了现实。

传统 ML 做文本分类,到底有多累?

过去做文本分类,那可真是一套让人头大的流程:数据清洗、分词、特征工程、模型选型、训练调参、部署上线、推理服务维护……任何一个环节出问题就得重来。换一个业务场景?好,再训一个模型。从数据准备到最终上线,少则几天,多则几周。这还不算跑出来的效果不理想、需要反复试错的成本。 Hologres AI Function 文本分类实战:从提示词设计到 KV-Cache 调优,全程 SQL 搞定 **有没有一种方式,让文本分类像查数据一样简单?** 答案就在 Hologres AI Function 身上:**SQL 即 AI,数据在哪,智能就在哪。**

什么是 Hologres AI Function?

简单讲,Hologres AI Function 把大模型的推理能力直接塞进了数据库引擎里。你完全不需要额外部署什么推理服务,只需要通过 SQL 函数(比如 ai_gen_structured),就能在查询过程中直接调用大模型,完成分类、摘要、信息抽取这些 AI 任务。 核心优势一句话就能说清楚:**数据不出库,推理即查询。**

实战:用 SQL 对豆瓣影评做情感分类

下面用一个完整的例子,带大家走一遍如何用 Hologres AI Function 对豆瓣影评做情感分类(正向 / 负向 / 中性),并且一步步把准确率从 83.5% 拉到 95%。

Step 1:准备数据

这次用的数据集是豆瓣影评数据集,从中取了 200 条记录。数据来源链接在这里:豆瓣影评数据集。 先在 Hologres 里创建一张表:
CREATE TABLE movie_reviews_200(
    cn_name         text,
    review          text,
    stars           bigint,
    sentiment_label text
);
sentiment_label 是人工标注的情感标签,后面用来评估模型效果。数据通过 psql 导入:
psql -U  -p 80 -h xxx.hologres.aliyuncs.com -d ai_test1 
  -c "COPY movie_reviews_200 FROM STDIN WITH DELIMITER ',' CSV HEADER;" 
  < ~/Downloads/movie_reviews_200.csv
数据准备就绪,接下来就该干正事儿了。

Step 2:创建提示词表

Hologres 支持把提示词当数据存在表里,通过 prompt() 函数动态拼装变量。这种方式的好处是版本管理和迭代非常灵活,改个字段就行,不用动代码。
CREATE TABLE ai_prompts(
    name        text PRIMARY KEY,
    prompt_text text
);

INSERT INTO ai_prompts VALUES(
    'classify_prompt1',
    $$
    你是一名专业的电影评论情感分析专家。你的任务是根据输入的**电影名称、用户影评和 stars 评分**,
    判断该影评对电影整体的情感倾向,并输出唯一结果。

    ## 输出要求
    仅输出以下 3 个值之一:
    - 正向
    - 负向
    - 中性

    除上述 3 个标签外,**不要输出任何其他内容**,包括解释、分析过程、标点、前缀、空格或重复输入。

    下面是本次判定的输入:
    - 电影名称:{0}
    - 用户影评:{1}
    - stars:{2}
    $$
);
这种“提示词即数据”的玩法,让你随时可以新增、修改、对比不同版本的提示词,比在代码里改字符串方便太多了。

Step 3:一条 SQL 完成批量分类

这是最核心的一步。用 ai_gen_structured 函数,在 SQL 查询中直接调用大模型,对 200 条影评逐条分类,结果直接写进新表。
-- 创建分类结果表
CREATE TABLE movie_reviews_predict(
    cn_name         text,
    reivew          text,
    stars           bigint,
    sentiment_label text,
    predict_label   text,
    usage           jsonb
);

-- 批量分类并写入结果
WITH prompts AS(
    SELECT cn_name, review, stars,
        prompt(prompt_text, cn_name, review, stars)::text AS prompt,
        sentiment_label
    FROM movie_reviews_200
    LEFT JOIN ai_prompts ON ai_prompts.name = 'classify_prompt1'
),
gen_data AS(
    SELECT
        cn_name, review, stars, sentiment_label,
        ai_gen_structured(
            model_name      => 'qwen37-plus',
            message         => prompt,
            response_format => $${
                "type": "json_schema",
                "schema": {
                    "type": "object",
                    "properties": {
                        "label": {"type": "string"}
                    }
                }
            }$$,
            params => '{"show_details": true}'
        ) AS result
    FROM prompts
),
per_row AS (
    SELECT cn_name, review, stars, sentiment_label,
        result->'output'->>'label' AS predict_label,
        result->'usage' AS usage
    FROM gen_data
)
INSERT INTO movie_reviews_predict SELECT * FROM per_row;
**没有 Python 脚本,没有推理服务,没有数据搬迁——一条 SQL 搞定全部。**

Step 4:效果评估

分类完成,算一下准确率:
SELECT
    COUNT(*) AS total_count,
    SUM(CASE WHEN predict_label = sentiment_label THEN 1 ELSE 0 END) AS correct_count,
    ROUND(
        SUM(CASE WHEN predict_label = sentiment_label THEN 1 ELSE 0 END)::numeric
        / COUNT(*) * 100, 2
    ) AS predict_accuracy
FROM movie_reviews_predict;
首轮结果:**准确率 83.50%**。效果还不错,但距离可用还有差距。关键在哪?不需要重新训练模型,只需优化提示词。

Step 5:提示词调优——准确率飙升至 95%

在提示词里加入更精细的分类规则,比如明确输入含义、设定判定优先级、处理特殊表达(反讽、转折句、欲扬先抑、比较句式),以及模糊时兜底为"中性"。
INSERT INTO ai_prompts VALUES(
    'classify_prompt_opt',
    $$
    你是一名专业的电影评论情感分析专家。你的任务是根据输入的**电影名称、用户影评和 stars 评分**,判断该影评对电影整体的情感倾向,并输出唯一结果。

    ## 输入说明

    你将收到以下 3 项内容:

    1. **电影名称**  
       用于辅助理解影片题材、风格和评论语境,但不能脱离影评内容单独判断情感。

    2. **用户影评**  
       这是最主要的判断依据。评论可能很短,也可能包含口语、吐槽、反问、玩梗、引用、夸张、反讽、阴阳怪气等表达。你需要理解其真实语义,而不是只看字面词汇。

    3. **stars 评分**  
       范围为 0~5 的整数。通常分数越高越偏正向,越低越偏负向,但它只能作为辅助信息。**当 stars 与评论内容冲突时,必须以评论文本为准。**

    ---

    ## 判定原则

    ### 1. 以评论文本为核心依据
    判断的是**用户对电影整体的态度**,不是对某个演员、镜头、宣传或观影环境的单独情绪。只要评论文本能体现明确立场,就优先按文本判断。

    ### 2. stars 仅作辅助
    当评论很短、态度模糊时,可以参考 stars;但若评论文字和 stars 冲突,一律以文字真实含义为准。

    ### 3. 关注整体语义,不机械看单个词
    不要因为出现“好”就判正向,也不要因为出现“差”就判负向。要结合上下文、语气、转折、结论和整体情绪来判断。

    ### 4. 无法确定时优先中性
    如果评论信息不足、态度不明、褒贬难分或语义模糊,不要强行判断,优先输出“中性”。

    ---

    ## 标签判定标准

    ### 正向
    当评论整体明确表达喜欢、认可、推荐、满意、惊喜、感动等态度时,判为**正向**。

    常见情况:
    - 明确夸电影好看、精彩、感人、值得看、超出预期
    - 表达“喜欢”“推荐”“没白看”“后劲很大”
    - 虽有小缺点,但总体肯定

    例如:
    - “比预期好很多”
    - “虽然节奏慢一点,但真的很好看”
    - “有瑕疵,不过整体很打动我”

    ### 负向
    当评论整体明确表达失望、不满、否定、不推荐、厌烦等态度时,判为**负向**。

    常见情况:
    - 明确说难看、无聊、尴尬、拖沓、失望、看不下去
    - 认为剧情、演技、节奏、逻辑等问题严重
    - 虽承认局部优点,但总体否定

    例如:
    - “太无聊了,看得想走”
    - “演员不错,但电影真的很难看”
    - “本来很期待,结果特别失望”

    ### 中性
    当评论无法体现明确正负态度时,判为**中性**。

    常见情况:
    - 评论过短,如“还行”“一般”“就那样”
    - 只复述剧情,没有评价
    - 只提问、引用台词、玩梗,未表达明确好恶
    - 褒贬都有,但无法判断最终倾向
    - 重点不在电影本身

    例如:
    - “所以最后他到底死没死?”
    - “看过”
    - “有优点也有问题”

    ---

    ## 特殊表达处理

    ### 1. 反讽和阴阳怪气
    要按真实语义判断,不按字面判断。  
    例如:“真是神作,看得我快睡着了” → **负向**

    ### 2. 转折句
    重点关注“但是、不过、然而、可惜”等转折后的内容。  
    例如:“前面还行,但是后面崩了” → **负向**

    ### 3. 欲扬先抑 / 欲抑先扬
    看最终落点。  
    例如:“本来没期待,结果意外好看” → **正向**

    ### 4. 比较表达
    通过与前作、同类片比较来表达态度时,提取真实倾向。  
    例如:“比上一部强太多” → 多数为**正向**  
    “还不如网大” → **负向**

    ---

    ## 冲突信息优先级

    当信息不一致时,按以下顺序判断:

    **评论文本真实语义 > 明确结论句 > 整体语气 > stars 评分 > 电影名称**

    ---

    ## 输出要求

    仅输出以下 3 个值之一:

    - 正向
    - 负向
    - 中性

    除上述 3 个标签外,**不要输出任何其他内容**,包括解释、分析过程、标点、前缀、空格或重复输入。


    下面是本次判定的输入:
    - 电影名称:{0}
    - 用户影评:{1}
    - stars:{2}
    $$
);
换上新提示词,重新跑一遍——只需要把 SQL 里的提示词 name 改成 'classify_prompt_opt'
-- 清除上次数据
TRUNCATE TABLE movie_reviews_predict;

-- 使用优化后的提示词重新分类
WITH prompts AS(
    SELECT cn_name, review, stars,
        prompt(prompt_text, cn_name, review, stars)::text AS prompt,
        sentiment_label
    FROM movie_reviews_200
    LEFT JOIN ai_prompts ON ai_prompts.name = 'classify_prompt_opt'
),
gen_data AS(
    SELECT
        cn_name, review, stars, sentiment_label,
        ai_gen_structured(
            model_name      => 'qwen37-plus',
            message         => prompt,
            response_format => $${
                "type": "json_schema",
                "schema": {
                    "type": "object",
                    "properties": {
                        "label": {"type": "string"}
                    }
                }
            }$$,
            params => '{"show_details": true}'
        ) AS result
    FROM prompts
),
per_row AS (
    SELECT cn_name, review, stars, sentiment_label,
        result->'output'->>'label' AS predict_label,
        result->'usage' AS usage
    FROM gen_data
)
INSERT INTO movie_reviews_predict SELECT * FROM per_row;
再来一次评估:
SELECT
    COUNT(*) AS total_count,
    SUM(CASE WHEN predict_label = sentiment_label THEN 1 ELSE 0 END) AS correct_count,
    ROUND(
        SUM(CASE WHEN predict_label = sentiment_label THEN 1 ELSE 0 END)::numeric
        / COUNT(*) * 100, 2
    ) AS predict_accuracy
FROM movie_reviews_predict;
**优化后准确率:95.00%!** 一切只发生在提示词里。不需要调整模型参数,不需要重新训练,几分钟就见效。
阶段准确率提升
基础提示词83.50%
优化提示词95.00%+11.5%

Step 6:成本分析——200 条影评仅花 1 毛钱

分类完成后还可以通过 SQL 查看 Token 消耗和缓存命中情况:
SELECT
    SUM((usage::jsonb ->> 'input_tokens')::int)  AS total_input_tokens,
    SUM((usage::jsonb ->> 'cached_tokens')::int)  AS total_cached_tokens,
    ROUND(
        SUM((usage::jsonb ->> 'cached_tokens')::int)::numeric
        / NULLIF(SUM((usage::jsonb ->> 'input_tokens')::int), 0) * 100, 2
    ) AS cache_hit_rate
FROM movie_reviews_predict;
结果令人惊喜:
指标数值
总输入 Token~25.8 万
缓存命中 Token~23.4 万
缓存命中率90%
Hologres 针对数据库批量推理的负载特征,对大模型 KV-Cache 命中率做了深度优化。命中缓存的 Token 仅按 **1~2 折** 计费,成本直接打到了地板价。 **最终成本明细:** - 缓存命中部分:2.4 元/百万 Token × 10% × 0.23 百万 = **0.055 元** - 未命中部分:2.4 元/百万 Token × 0.024 百万 = **0.057 元** - **总计:0.11 元** **200 条影评,情感分类准确率 95%,成本仅 0.11 元。** 小贴士:怎么让 cached token 命中率更高? - 提示词中把固定不变的部分放在顶端; - 变化的部分放到末尾; - 推荐用 prompt() 函数做提示词拼装,比如本文的示例那样。

三大核心优势总结

1. SQL 即 AI,零门槛上手

不需要 Python,不需要部署推理服务,不需要搭建 ML Pipeline。会写 SQL 的数据分析师,就能直接调用大模型完成文本分类任务。

2. 提示词即数据,迭代快如闪电

提示词存在数据表里,版本管理和 A/B 对比就像改一行 SQL。效果不好?换提示词,重新跑一遍——几分钟搞定,完全不用重训模型。

3. 智能缓存加持,成本降到极致

最高 90% 的 Cache 命中率意味着绝大部分 Token 只按 1~2 折计费。就算把数据量扩大到上万条,成本依然可控。

适用场景

- **舆情监控:** 电商评论、社交媒体的情感分析与趋势洞察 - **内容审核:** UGC 内容的自动分类与合规检测 - **客服质检:** 对话文本的意图识别与满意度评估 - **数据标注:** 海量文本的自动化打标,替代高成本人工标注 - **行业分析:** 金融资讯、医疗文本、法律文书的智能分类

写在最后

Hologres AI Function 让大模型走进了数据库,也让文本分类变成了一条 SQL 的事。从数据准备到推理分类,从效果评估到成本优化,全程 SQL 搞定,全程数据不出库。 **一条 SQL,从数据到智能。** > 本文采用通义千问 qwen3.7-plus 模型,搭配 Hologres 4.2 完成全部推理任务。
来源:https://segmentfault.com/a/1190000047982080

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。