
不写 Python不搭服务不训模型。一条 SQL 调用大模型文本分类从未如此简单。传统 ML 做文本分类到底有多累数据清洗、分词、特征工程、模型选型、训练调参、部署上线、推理服务维护……一套流程走下来少则数天多则数周。模型效果不好重新来过。换个场景再训一个。有没有一种方式让文本分类像查数据一样简单Hologres AI Function 给出了答案SQL 即 AI数据在哪智能就在哪。什么是 Hologres AI FunctionHologres AI Function 将大模型推理能力直接内置于数据库引擎。你无需部署任何推理服务只需通过 SQL 函数如ai_gen_structured就能在查询过程中直接调用大模型完成分类、摘要、抽取等 AI 任务。核心优势一句话概括数据不出库推理即查询。实战用 SQL 对豆瓣影评做情感分类下面我们用一个完整的例子展示如何用 Hologres AI Function 对豆瓣影评进行情感分类正向 / 负向 / 中性并一步步调优到 95% 准确率。Step 1准备数据本文使用的数据集来自 豆瓣影评数据集取其中 200 条记录。豆瓣影评数据集 https://www.kaggle.com/datasets/utmhikari/doubanmovieshortcomments首先在 Hologres 中创建数据表CREATE TABLE movie_reviews_200( cn_name text, review text, stars bigint, sentiment_label text );其中sentiment_label是人工标注的情感标签用于后续评估模型效果。通过 psql 将 CSV 数据导入 Hologrespsql -U db_user_name -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效果评估分类完成后用一条简单的 SQL 即可计算准确率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 评分** 范围为 05 的整数。通常分数越高越偏正向越低越偏负向但它只能作为辅助信息。**当 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%仅通过调整提示词准确率提升了 11.5 个百分点。阶段准确率提升基础提示词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 仅按12 折计费大幅降低推理成本。最终成本明细缓存命中部分2.4 元/百万 Token × 10% × 0.23 百万 0.055 元未命中部分2.4 元/百万 Token × 0.024 百万 0.057 元总计0.11 元200 条影评情感分类准确率 95%成本仅 0.11 元。TIPS如何提升 cached token 的命中率提示词中尽量将固定不变的部分置于提示词顶端变化的部分放到提示词末尾推荐使用 prompt()函数做提示词拼装可参考本文的提示词示例。三大核心优势总结1. SQL 即 AI零门槛上手不需要 Python不需要部署推理服务不需要搭建 ML Pipeline。会写 SQL 的数据分析师就能直接调用大模型完成文本分类任务。2. 提示词即数据迭代快如闪电提示词存在数据表里版本管理和 A/B 对比像改一行 SQL 一样简单。效果不好换个提示词重新跑一遍——几分钟搞定无需重训模型。3. 智能缓存加持成本降到极致最高 90% 的 Cache 命中率意味着绝大部分 Token 仅按 12 折计费。即便数据量扩大到上万条成本依然可控。适用场景舆情监控电商评论、社交媒体的情感分析与趋势洞察内容审核UGC 内容的自动分类与合规检测客服质检对话文本的意图识别与满意度评估数据标注海量文本的自动化打标替代高成本人工标注行业分析金融资讯、医疗文本、法律文书的智能分类写在最后Hologres AI Function 让大模型走进了数据库让文本分类变成了一条 SQL 的事。从数据准备到推理分类从效果评估到成本优化全程 SQL 搞定全程数据不出库。一条 SQL从数据到智能。本文采用通义千问 qwen3.7-plus 模型搭配 Hologres 4.2 完成全部推理任务。