Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型"答错一句话",而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gemini API 的 Structured Outputs 能按 JSON Schema 生成结果;本篇用 Python 把退款、账号和普通咨询分流,并在模型输出越界时拒绝自动流转。你会得到一条能复制、能超时、能降级的最小链路。

为什么不直接解析一段自然语言

结构化输出的作用是规定"输出长什么样",不是保证事实正确。Schema 让字段和枚举更稳定;业务规则仍要由服务端负责。本文把 priority 限在 low、normal、high,把 queue 限在三个队列。模型若返回未知值,程序转到人工队列。当前官方文档把它用于抽取、分类和 Agent 工作流,并通过 response_format 的 application/json 与 schema 配置。

flowchart LR A[工单文本] --> B[Gemini JSON Schema] B --> C[解析JSON] C --> D{枚举与业务规则} D -->|通过| E[进入对应队列] D -->|失败/超时| F[人工复核队列]

环境准备

使用 Python 3.10+。安装依赖:python -m pip install google-genai。把密钥放入环境变量:export GEMINI_API_KEY='你的密钥'。模型名示例为文档中的 gemini-3.8-flash;你的账号可用模型与配额仍需在控制台确认。保存为 ticket_router.py,运行 python ticket_router.py。示例未在本次任务中实际调用线上 API;本地仅完成语法检查,目标环境安装依赖后应再作一次无敏感数据的联调。

python 复制代码
import json
import os
from google import genai

ALLOWED_QUEUES = {"refund", "account", "general"}
ALLOWED_PRIORITY = {"low", "normal", "high"}
SCHEMA = {"type": "object", "properties": {
    "queue": {"type": "string", "enum": sorted(ALLOWED_QUEUES)},
    "priority": {"type": "string", "enum": sorted(ALLOWED_PRIORITY)},
    "reason": {"type": "string"}},
    "required": ["queue", "priority", "reason"]}

def safe_route(raw: str) -> dict:
    try:
        data = json.loads(raw)
    except json.JSONDecodeError:
        return {"queue": "human_review", "reason": "JSON无法解析"}
    if data.get("queue") not in ALLOWED_QUEUES:
        return {"queue": "human_review", "reason": "未知队列"}
    if data.get("priority") not in ALLOWED_PRIORITY:
        return {"queue": "human_review", "reason": "未知优先级"}
    return data

def classify(ticket: str) -> dict:
    if not os.getenv("GEMINI_API_KEY"):
        return {"queue": "human_review", "reason": "缺少GEMINI_API_KEY"}
    client = genai.Client()
    try:
        result = client.interactions.create(
            model="gemini-3.8-flash", input=ticket,
            response_format={"type": "text", "mime_type": "application/json",
                             "schema": SCHEMA}, timeout=20)
        return safe_route(result.output_text)
    except Exception as exc:
        return {"queue": "human_review", "reason": f"调用失败: {type(exc).__name__}"}

if __name__ == "__main__":
    print(classify("订单重复扣款,请尽快退款"))
    assert safe_route('{"queue":"refund","priority":"high","reason":"重复扣款"}')["queue"] == "refund"

代码分两层:SCHEMA 提前缩小模型输出空间;safe_route 再做独立验证,不能因为 API 承诺 JSON 就省略它。timeout=20 是为了不让一个慢请求占住 Web 工作线程;生产环境还应设置 HTTP 客户端级超时、重试次数和熔断。genai.Client() 从环境读取密钥,不要把密钥写进仓库。

预期输出(有密钥且调用成功时)类似 {'queue': 'refund', 'priority': 'high', 'reason': '...'};没配密钥则是人工复核。最常见的坑有:一,Schema 只约束格式,不会自动核验订单真伪;二,枚举改了却没同步服务端白名单;三,超时后盲目重试,造成同一工单被重复创建;四,把模型理由直接展示给用户而泄露内部规则。

适合把"先分给谁处理"自动化,不适合直接批准退款或关闭投诉。工程化时,把原始文本、模型版本、schema 版本、路由结果和人工改判一起记录;每周抽样计算错分率。5分钟实践:新增 security 队列,并写一个断言确保模型返回 delete_database 时永远进入 human_review。

你的工单里,哪一个字段一旦分类错就不该自动流转?

关注「蜗牛聊AI」,一起看懂技术变化背后的真正机会。


本文首发于 java4u.cn,转载请注明出处。

相关推荐
fly-iot11 分钟前
【FDE知识库】(1):AI 编程时代开发语言选型分析,云使用go,企业用java,算法python,底层c
开发语言·人工智能·golang
郝学胜-神的一滴16 分钟前
游戏设计:原型与开发 17:数字化系统里的思维体操
人工智能·游戏·游戏程序·游戏策划·游戏设计
腾讯云大数据26 分钟前
腾讯云发布一站式多模态数据处理与模型训推方案,助力Physical AI释放生产力
大数据·人工智能·云计算·腾讯云
GitCode官方1 小时前
从大语言模型到具身智能:百度百舸 LoongForge 入驻 AtomGit
人工智能·react native·百度·harmonyos·atomgit
Easy_API8 小时前
2.8万亿参数,编程反超GPT-6 Astra:Kimi K3.1 Pro把开源模型推到了哪一步
大数据·人工智能·gpt·深度学习
GlobalInfo9 小时前
2026年机器人多指灵巧手市场分析报告——涵盖行业调查、趋势分析与发展前景
大数据·人工智能·microsoft·微服务·机器人
紧跟先前的步伐9 小时前
Go AI Agent 实战 24|工具系统工程化收尾与阶段验收
人工智能·ai·golang·1024程序员节
释厄6239 小时前
AI学习层更新与跨体转移律——人类社会同构·不缺理解缺 U
人工智能·学习
老金带你玩AI10 小时前
集万家所长,一键复制的Agent.md!
人工智能
ZhuoAIStage10 小时前
舞台工艺多专业审图提速:用 AI 智能体编排 A+B+C+G 四段读图流水线
人工智能·自动化·工作流编排·舞台工艺·审图智能体