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。

相关推荐
冬奇Lab2 小时前
Workflow 系列(04):Multi-Agent 协调——编排器边界、并发控制与上下文隔离
人工智能·工作流引擎
冬奇Lab2 小时前
每日一个开源项目(第147篇):HyperGraphRAG - 用超图表示 N 元关系,RAG 的第三代范式
人工智能·开源·graphql
甲维斯3 小时前
Github + 阿里云oss实现类似codex的自动更新!
人工智能
阿里云大数据AI技术4 小时前
光轮智能 × 阿里云:共建 Physical AI 云上数据、评测与持续学习基础设施
人工智能·机器学习
机器之心4 小时前
实锤了:Claude Code偷查用户,时区、中国AI实验室全是关键词
人工智能·openai
网易云信4 小时前
Cursor点燃个人开发者,企业级AI为何频频受挫?Agent工厂从提效工具到AI员工的跃迁
人工智能·开源
网易云信5 小时前
解锁触手可及的温暖:网易智企 x Wander Puffs AI 云游泡芙
人工智能
转转技术团队5 小时前
从 PRD 到可验证代码:AI 需求开发闭环实践
人工智能