3. LangChain 视觉理解
LangChain4j 视觉理解入门指南 - AI 也能看懂图片了前言你有没有想过AI 能不能像人类一样看图说话“这张 K 线图走势怎么样”这个报错信息是什么意思LangChain4j 的多模态能力让 Java 应用也能实现这些功能。本文基于实战项目详细解析如何让大模型看懂图片。一、什么是视觉理解Vision传统大模型只能处理文字输入和输出视觉大模型可以理解图片内容实现图文对话比如你给一张上证指数截图它可以告诉你从图片来看上证指数近期呈现震荡上行态势...成交量明显放大显示资金活跃度高...MACD 指标金叉向上趋势偏乐观...这就是所谓的“多模态”—— 图像 文本的混合输入输出。二、项目结构概览2.1 pom.xml —— 依赖与基础版相同?xml version1.0 encodingUTF-8?projectxmlnshttp://maven.apache.org/POM/4.0.0modelVersion4.0.0/modelVersionparentgroupIdcom.study.ai/groupIdartifactIdstudy-ai/artifactIdversion1.0-SNAPSHOT/version/parentartifactIdlangchain4j-04-chatapi-image/artifactIddependencies!-- Spring Boot 基础 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependency!-- LangChain4j 核心与 OpenAI 适配器 --dependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j/artifactId/dependencydependencygroupIddev.langchain4j/groupIdartifactIdlangchain4j-open-ai/artifactId/dependency!-- Lombok --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdscopecompile/scope/dependency/dependencies/project说明视觉理解和纯文本对话的依赖完全一致因为底层模型本身就支持多模态。三、核心原理图片怎么传给大模型3.1 为什么需要 Base64 编码网络传输数据都是二进制流但 JSON 协议只认文本格式。所以必须把图片转换成字符串才能打包发送原始图片 (PNG) → 字节数组 → Base64 编码 → 字符串Base64 是什么一种编码方式能把任何二进制数据转成A-Za-z0-9/组成的 ASCII 字符类似 URL 编码把空格变成%20但专门用于图片等二进制数据解码后能恢复成原始文件不会丢失数据类比就像快递要把易碎品打包到纸箱里——图片本身是玻璃杯Base64 就是把玻璃杯放进泡沫箱再贴上标签的过程。四、关键代码逐行详解4.1 ChatConfig.java —— 超长等待时间设置packagecom.study.ai.config;importcom.study.ai.service.ChatAssistant;importdev.langchain4j.model.chat.ChatModel;importdev.langchain4j.model.openai.OpenAiChatModel;importdev.langchain4j.service.AiServices;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjava.time.Duration;ConfigurationpublicclassChatConfig{Value(${langchain4j.open-ai.chat-model.api-key})privateStringapiKey;Value(${langchain4j.open-ai.chat-model.model-name})privateStringmodelName;Value(${langchain4j.open-ai.chat-model.base-url})privateStringbaseUrl;BeanpublicChatModelchatModel(){returnOpenAiChatModel.builder().apiKey(apiKey).modelName(modelName).baseUrl(baseUrl)// 视觉场景的关键配置关闭重试.maxRetries(0)// ❗ 关闭自动重试视觉请求耗时长重试会成倍增加总等待时间// 超时时间大幅延长至 5 分钟.timeout(Duration.ofMinutes(5))// 图像处理需要上传 推理默认 60 秒远远不够.build();}BeanpublicChatAssistantchatAssistant(ChatModelchatModel){returnAiServices.create(ChatAssistant.class,chatModel);}}为什么要特殊处理超时和重试参数默认值视觉场景调整原因maxRetries2改成 0图片分析通常要几十秒第一次失败就立刻重试会让总等待时间翻倍不如慢工出细活直接单次完成timeout60 秒改成 5 分钟上传图片后需要额外时间①网络传输耗时 ②模型解析像素 ③生成分析结果总共可能超过 2 分钟⚠️重要经验很多初学者做多模态时报 TimeoutException就是因为用了默认 60 秒超时4.2 ApplicationTests.java —— 测试代码全解析这是本次学习的核心我们逐行拆解packagecom.study.ai;importdev.langchain4j.data.message.ImageContent;importdev.langchain4j.data.message.TextContent;importdev.langchain4j.data.message.UserMessage;importdev.langchain4j.model.chat.ChatModel;importdev.langchain4j.model.chat.response.ChatResponse;importlombok.SneakyThrows;importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.core.io.Resource;importjava.util.Base64;SpringBootTestclassApplicationTests{AutowiredprivateChatModelchatModel;Value(image/上证指数.png)// 重点从 resources 目录读取图片资源privateResourceimage;字段说明Autowired chatModel注入已配置的 ChatModel BeanValue(image/上证指数.png)Spring 的资源注入从src/main/resources/image/文件夹加载图片为什么用 Resource 而不是 File方式优点缺点Resource跨平台兼容IDE 和 JAR 包都能运行需要先 read 成 byte[]File简单直观Windows/Linux 路径不同容易出错✅最佳实践Spring Boot 项目推荐用Resource读取静态资源。Step 1把图片转成 Base64 字符串SneakyThrows// ❗ Lombok 注解自动抛出异常不用写 try-catchTestvoidtestImg(){// base64DataStringbase64DataBase64.getEncoder().encodeToString(image.getContentAsByteArray());// mimeTypeStringmimeTypeimage/png;每步解释①SneakyThrows是啥Lombok 提供的语法糖自动把方法声明的throws IOException隐藏起来否则你得写TestvoidtestImg()throwsException{// 烦不烦...}②image.getContentAsByteArray()调用 Spring 的Resource接口把图片转成字节数组二进制相当于file.jpg → byte[]③Base64.getEncoder().encodeToString(...)Java 自带的 Base64 工具类把字节数组转成 ASCII 字符串便于 JSON 传输④String mimeType image/pngMIME 类型告诉接收方这是什么格式的文件常见值image/pngimage/jpeg/image/jpgimage/gifimage/webp类比就像寄快递时填写包裹类型——“这是衣服还是这是电子产品”防止运输中损坏。Step 2构建混合消息文字 图片UserMessageuserMessageUserMessage.from(TextContent.from(这是上证指数的截图我需要你从该图片中观察量价信息判断后续走势),ImageContent.from(base64Data,mimeType));核心类解析TextContent.from(...)创建纯文本内容对象你的问题“从图片中观察量价信息…”ImageContent.from(...)创建一个图片对象包含base64Data图片的 Base64 编码mimeType图片格式如image/pngUserMessage.from(...)关键点可以一次性塞入多个内容文字、图片、甚至未来还有音频/视频顺序很重要先文字后图片更符合阅读逻辑内部结构示意UserMessage{contents:[TextContent(text这是上证指数的截图...),ImageContent(dataiVBORw0KGgoAAAANSUhh...,typeimage/png)]}Step 3发送并获取回答ChatResponsechatchatModel.chat(userMessage);System.out.println(结果chat.aiMessage().text());}返回对象解析chatModel.chat(...)→ 同步等待 AI 分析完成ChatResponse包含 AI 的所有回复内容chat.aiMessage().text()提取纯文本部分预期输出示例结果从这张上证指数截图中我观察到以下关键技术特征 1. **价格走势**近期呈现震荡上行态势从约 3050 点逐步攀升至当前 3120 点左右... 2. **成交量变化**今日成交额显著放大约为 XXXX 亿元高于前几日均值... 3. **均线系统**日线级别的 MA5/MA10/MA20 呈多头排列... 4. **MACD 指标**快线DIF上穿慢线DEA形成金叉形态... 综合判断短期走势偏乐观但需注意上方套牢盘压力建议关注量能持续性...五、常见问题解答FAQQ1为什么不能直接用 File.path 读图片A在 IDEA 开发环境运行时资源文件可能在target/classes目录下但在打包后的 JAR 文件中会变成压缩状态无法直接用new File()访问。Resource接口会自动适配这两种情况。Q2如果图片太大怎么办A压缩使用javax.imageio缩放图片裁剪只截取关键区域如 K 线图主体阿里云百炼限制单张图片最大 2MB超过会被拒绝Q3支持 JPG 吗A支持只需要改两件事准备.jpg图片放到image/目录mimeType改为image/jpegQ4可以同时传多张图吗A可以只要重复添加ImageContentUserMessageuserMessageUserMessage.from(TextContent.from(对比这两张图表...),ImageContent.from(base64Data1,image/png),ImageContent.from(base64Data2,image/jpeg));Q5为什么我的程序卡住不动了A最常见的原因是超时时间不够确保设置.timeout(Duration.ofMinutes(5))// 至少 2 分钟以上六、进阶思考如何优化体验6.1 异步流式输出目前我们是阻塞式等待——用户得盯着控制台看半天。可以考虑改成流式打字机效果类似之前的 StreamingChatLanguageModel。6.2 前端集成将本模块封装为 RESTful APIPostMapping(/analyze)publicStringanalyzeImage(RequestParamMultipartFilefile){// 读取图片 - Base64 - 调用 chatModel}前端用户上传图片后端实时返回分析结果。6.3 结构化解析如果你只需要特定数据如股票价格可以让 AI 返回 JSON 格式方便进一步处理。七、总结与下一步通过这篇博客你已经掌握了✅ 视觉理解的基本原理为什么需要 Base64✅ Spring Resource 读取静态资源✅ 构建UserMessage混合图文内容✅ 超长短重试配置的重要性接下来你可以尝试OCR 识别让 AI 提取图片中的文字表格、代码、公式目标检测识别图片中的物体人脸、商品、动物图像描述自动生成一段话总结图片内容多轮对话基于图片继续追问细节八、参考资料LangChain4j 官方文档学习来源JavaAI pig4cloud 中文文档感谢大佬的学习资料大家一起进步我的项目源码本文档基于实际项目实战编写所有代码均已测试通过。作者8 年 Java 开发者自学转型 AI Agent专注 Java/Spring AI LangChain4j 技术栈。如有问题欢迎讨论交流

相关新闻

STM32驱动SG90舵机:PWM原理、接线与实战指南

STM32驱动SG90舵机:PWM原理、接线与实战指南

简介:本资源面向嵌入式初学者与STM32入门开发者,聚焦SG90舵机的硬件控制实践,解决从理论到实操的关键断层问题——如何基于STM32生成符合规范的50Hz PWM信号以精确驱动舵机实现0–180角度调节。压缩包共205个文件,含34个C源文件&a…

2026/10/26 10:48:27 阅读更多 →
DeepSeek API 返回 401 时如何排查:密钥配置、请求头与最小复现

DeepSeek API 返回 401 时如何排查:密钥配置、请求头与最小复现

当 HTTP 接口返回 401 Unauthorized 时,服务端只传递了一个信息:请求没有通过身份认证。至于问题是出在密钥本身、密钥加载过程、请求头拼装还是中间链路改写,服务端并不会额外告诉你。对调用 DeepSeek API 的开发者来说,401 的排…

2026/10/26 10:48:36 阅读更多 →
网易测开笔试全解析:从题型拆解到备战策略

网易测开笔试全解析:从题型拆解到备战策略

2022年8月,网易2023届校招提前批笔试通道开放,我蹲到了测试开发岗位的笔试邀请。严格说,这不是我第一次参加大厂测开笔试,但网易这一场给我的印象特别深——题量不大,看着也不难,考完却让人心里没底。一位学…

2026/11/1 15:04:03 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/8 1:19:03 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/7 12:08:40 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/8 1:35:05 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/8 1:38:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/7 12:08:40 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/8 1:23:14 阅读更多 →

日新闻

周新闻

月新闻