Spring Ai 集成 DashScope 多模态模型实现身份证信息识别

Spring Ai 集成 DashScope 多模态模型实现身份证信息识别

背景

用户上传身份证图片,自动提取姓名、性别、民族、出生日期、住址、身份证号等信息。如果上传的不是身份证图片,返回"图片不合法"。

项目技术栈:Spring Boot 3.4.5 + Spring AI 1.1.2 + DashScope(通义千问)。之前只用了纯文本模型 qwen-flash,这次需要引入多模态能力。

踩坑记录

第一次尝试:Spring AI ChatClient + qwen-vl-plus

一开始想沿用项目中已有的 ChatClient 模式,只是在请求时通过 DashScopeChatOptions 把模型切换为 qwen-vl-plus,图片用 ByteArrayResource 传进去:

java 复制代码
chatClient.prompt()
    .system(prompt)
    .user(u -> u.text("请识别图片中的身份证信息。")
            .media(mimeType, new ByteArrayResource(imageBytes)))
    .options(DashScopeChatOptions.builder().withModel("qwen-vl-plus").build())
    .call()
    .content();

结果报错:HTTP 400 - url error。原因是 Spring AI AlibabaDashscopeChatModel 内部走的依然是 chat/completions 端点,这个端点不支持多模态输入。ByteArrayResource 传到内部后被当成 URL 去解析,自然失败。

第二次尝试:直接调用 multimodal-generation HTTP 端点

WebClient 直接调 DashScope 的多模态生成端点:

复制代码
POST https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation

请求体按 JSON 格式手动拼接,图片以 base64 data URI 形式传进去。这个方式能工作,但代码里手动拼接 JSON、解析响应,比较原始,也没有 SDK 带来的类型安全和异常处理。

最终方案:DashScope Java SDK

引入官方 SDK com.alibaba:dashscope-sdk-java:2.15.1,用 MultiModalConversation.call() 方法:

java 复制代码
MultiModalMessage systemMsg = MultiModalMessage.builder()
    .role("system")
    .content(List.of(Map.of("text", systemPrompt)))
    .build();

MultiModalMessage userMsg = MultiModalMessage.builder()
    .role("user")
    .content(List.of(
        Map.of("text", userText),
        Map.of("image", dataUri)))
    .build();

MultiModalConversationParam param = MultiModalConversationParam.builder()
    .model("qwen-vl-plus")
    .apiKey(apiKey)
    .message(systemMsg)
    .message(userMsg)
    .build();

MultiModalConversation conv = new MultiModalConversation();
MultiModalConversationResult result = conv.call(param);

SDK 自动处理了 API 路由、认证、请求序列化和响应反序列化,代码干净很多。

架构设计

复制代码
Controller (Web)
    ↓ ApiResult<T>
Service (IdCardRecognitionService)
    ↓ MultiModalConversation.call()
DashScope multimodal-generation API (qwen-vl-plus)
  • Controller : POST /api/id-card/recognize,接收 MultipartFile,service 返回 null 时返回 code=402, msg="图片不合法"
  • Service: 校验图片格式 → base64 编码 → 构造 MultiModalMessage(system + user, text + image)→ 调用 SDK → 解析 JSON 响应 → 校验字段合法性
  • DTO : IdCardRecognitionResponse record,6 个字段

Prompt 设计关键

  1. 明确字段定义:姓名、性别、民族、出生日期、住址、身份证号,每个字段都给了中文说明和格式要求
  2. 验证规则:必须有姓名 + 身份证号才算合法
  3. 输出格式约束:两个明确示例(合法/不合法),禁止 markdown 围栏
  4. 结构化输出{"valid":true,...} / {"valid":false},便于代码解析

响应格式

合法身份证:

json 复制代码
{"code":200,"msg":"ok","data":{"name":"张三","gender":"男","ethnicity":"汉","birthDate":"1990年01月01日","address":"北京市朝阳区...","idNumber":"11010119900101001X"}}

非身份证图片:

json 复制代码
{"code":402,"msg":"图片不合法","data":null}

一点体会

Spring AI Alibaba 的 DashscopeChatModel 虽然方便,但只适用于纯文本 chat/completions 端点。多模态场景需要用官方的 MultiModalConversation SDK 或直接调 multimodal-generation 端点。如果两种场景都有,建议各走各的路------纯文本继续用 ChatClient,多模态走 SDK。

相关推荐
不爱土豆唯爱马铃薯1 小时前
MONKEYCODE 教程系列MC-029 | 积分体系
人工智能
东方佑1 小时前
分形递归状态机 (FRSM) 实验报告-或将实现llm无限上下文
人工智能·语言模型·自然语言处理
其实防守也摸鱼1 小时前
Claude 大模型新手入门与实战指南
人工智能·python·功能测试·ai·大模型·测评
jinxindeep1 小时前
中科院DexJoCo:面向灵巧操作的基准测试与工具集
人工智能
Dust-Chasing1 小时前
Claude Code源码剖析 - 权限系统
人工智能·python·ai
甲维斯1 小时前
Fable5是真·神!用canvas手搓超级玛丽无bug!
人工智能·游戏开发
lulu12165440781 小时前
大模型API聚合平台技术架构深度对比:六大平台协议转换、路由调度与安全治理全解析 - 微元算力(weytoken)
java·人工智能·安全·架构·ai编程
米小虾1 小时前
我与AI的对话:从大模型的知识本质,到具身智能能否催生真正的知识创造者,再到人的教育与成长
人工智能·aigc
测试者家园1 小时前
用 Skills 自动生成测试用例:一套可落地方案
人工智能·测试用例·持续测试·职业和发展·ai赋能·智能化测试