尧图精选

【必学收藏】Java + Spring AI构建多模态智能交互:从文档解析到知识图谱实战指南(TaoToken统一Key接入版)

🕒 发布时间:2026/10/2 12:00:41 📁 来源:尧图网络
1. 为什么 Java 开发者需要一条多模态文档解析到知识图谱的链路很多 Java 团队手里已经有一堆 Spring Boot 服务业务数据散落在 PDF 合同、扫描件、Excel 报表和图片里。传统做法是写正则、写 POI、写 OCR 后处理规则一多就维护不动。现在更省事的思路是把文档解析、实体关系抽取、知识图谱写入、多模态问答串成一条链路让模型负责“理解”Java 负责“编排”。这条链路能做什么简单说三件事。第一把 PDF、图片、表格里的文字和结构读出来第二从文本里抽人名、公司、金额、时间、条款这类实体和关系写进图数据库第三用户用自然语言提问时先检索图谱和向量库再让模型生成回答。适合谁适合已经会 Spring Boot、想快速把 AI 能力接进现有系统的 Java 后端也适合做企业知识库、合同审查、报表问答的团队。我试过用纯手写规则做合同抽取字段一改就崩。换成 Spring AI 加统一模型通道后解析和抽取的代码量下降明显重点变成调提示词和校验图谱结构。下面按“环境准备 → 文档解析 → 图谱写入 → 模型接入 → 验证 → 排障”的顺序走一遍代码都可以直接复制改。核心检索词先明确Java、Spring AI、多模态、文档解析、知识图谱。这几个词会贯穿全文你按标题场景一步步跟做即可。2. TaoToken 统一 Key 接入 Spring AI 的前置准备与依赖配置Spring AI 的好处是模型调用被抽象成 ChatModel、EmbeddingModel 这些接口换模型不用改业务代码。但多模态场景往往要调不同能力的模型解析图片要视觉模型抽实体要文本模型做向量要 embedding 模型。如果每个模型都单独申请 Key、单独配地址配置会非常散。统一 Key 通道的价值就在这里一个 Base URL、一个 API Key通过 model 参数切换不同模型。TaoToken 提供的就是这种 OpenAI 兼容风格的入口Spring AI 的 OpenAI starter 可以直接对接。你需要准备三样东西Base URL、API Key、Model ID。Base URL 用https://taotoken.net/apiAPI Key 在控制台创建Model ID 按你实际要用的模型填。先建一个 Spring Boot 3.x 项目JDK 17 以上。pom.xml 里加这些依赖版本按你项目实际调整dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version1.0.0-M6/version /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-pdf-document-reader/artifactId version1.0.0-M6/version /dependency dependency groupIdorg.apache.pdfbox/groupId artifactIdpdfbox/artifactId version3.0.3/version /dependency dependency groupIdorg.neo4j.driver/groupId artifactIdneo4j-java-driver/artifactId version5.26.0/version /dependency /dependencies注意 Spring AI 的版本迭代较快M6 之后包名和配置项可能有变化遇到类找不到先核对官方迁移说明。依赖装好后配置文件里把统一通道写进去。application.yml 示例spring: ai: openai: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} chat: options: model: gpt-4o-mini temperature: 0.2 embedding: options: model: text-embedding-3-small这里把 Key 放到环境变量里别硬编码进仓库。启动前设置export TAOTOKEN_API_KEY你的Key。Model ID 按你控制台里可用的模型填文本、视觉、embedding 各选一个。这样 Spring AI 会自动注入 OpenAiChatModel 和 OpenAiEmbeddingModel后面解析、抽取、问答都用同一套通道。如果你更习惯用 coding plan 做长期编码任务也可以在控制台里看对应套餐但本文聚焦 API 接入先把 Key 和 Base URL 跑通。3. 可复制的文档解析与知识图谱写入配置片段这一节是重点给你能直接落地的配置和代码。文档解析分两类文本型 PDF 用 PdfDocumentReader 直接读扫描件和图片要先走视觉模型做 OCR 或描述再进文本链路。表格单独处理因为 PDF 表格抽出来容易串行。先看 PDF 解析。Spring AI 的 DocumentReader 把每页读成 Document 对象带 metadataConfiguration public class DocumentConfig { Bean public PdfDocumentReader pdfDocumentReader() { return new PdfDocumentReader( classpath:/docs/sample-contract.pdf, new ParagraphPdfDocumentReaderConfig() ); } }实际项目里路径是动态的建议封装成服务方法传入 InputStream。解析出来的 Document 列表每页文本送进实体抽取。抽取用 ChatClient 加结构化输出提示词要求返回 JSONService public class EntityExtractionService { private final ChatClient chatClient; public EntityExtractionService(ChatClient.Builder builder) { this.chatClient builder.build(); } public GraphPayload extract(String text) { String prompt 从下面文本中抽取实体和关系只返回 JSON不要解释。 格式{entities:[{name:,type:}], relations:[{source:,target:,type:}]} 文本 text; return chatClient.prompt() .user(prompt) .call() .entity(GraphPayload.class); } }GraphPayload 用 record 或普通类定义字段和 JSON 对齐。拿到实体关系后写 Neo4j。配置片段neo4j: uri: bolt://localhost:7687 username: neo4j password: ${NEO4J_PASSWORD}写入代码用 MERGE 避免重复节点public void save(GraphPayload payload) { try (Session session driver.session()) { for (Entity e : payload.entities()) { session.run( MERGE (n:Entity {name: $name}) SET n.type $type, Map.of(name, e.name(), type, e.type()) ); } for (Relation r : payload.relations()) { session.run( MATCH (a:Entity {name: $source}) MATCH (b:Entity {name: $target}) MERGE (a)-[rel:REL {type: $type}]-(b) , Map.of(source, r.source(), target, r.target(), type, r.type()) ); } } }图片和表格怎么接图片走视觉模型把图片转 base64 或传 URL提示词要求“描述图片内容并抽取其中文字”。表格建议先用 PDFBox 的表格提取或 Tabula 转成 CSV再按行拼成文本送抽取比直接让模型读整页 PDF 稳。多模态的关键是不同模态先归一化成文本或结构化数据再进同一条图谱链路。配置里还有几个参数值得调temperature 设 0.1 到 0.2抽取任务要稳定max-tokens 按文档长度设太长会截断embedding 维度要和向量库一致。这些都在 application.yml 的 chat.options 和 embedding.options 下。4. 验证多模态问答链路从请求到成功结果配置写完要验证别等全写完再跑。分三步验证先验证模型通道通不通再验证解析抽取最后验证图谱问答。第一步写一个最小 Controller 测模型RestController public class PingController { private final ChatModel chatModel; public PingController(ChatModel chatModel) { this.chatModel chatModel; } GetMapping(/ping) public String ping() { return chatModel.call(用一句话说明什么是知识图谱); } }启动后访问http://localhost:8080/ping能返回中文句子就说明 Base URL、Key、Model ID 三件套正确。如果返回 401先查 Key如果连接超时查 Base URL 是否写成了带路径的错误形式。第二步验证解析和抽取。放一个测试 PDF 到 resources/docs调抽取服务打印 GraphPayload。成功结果是 entities 里出现公司名、金额、日期relations 里出现“签署”“属于”这类关系。如果 entities 为空多半是提示词太宽松或文本太长被截断把文本按页切分再抽。第三步验证图谱问答。用户问“这份合同里甲方是谁”链路是问题先做 embedding去向量库或图谱检索相关实体再把检索结果拼进提示词让模型回答。检索部分可以用 Neo4j 全文索引也可以把实体描述做向量存起来。问答接口示例PostMapping(/ask) public String ask(RequestBody String question) { ListString context graphRetriever.retrieve(question); String prompt 根据以下资料回答不知道就说不知道\n String.join(\n, context) \n问题 question; return chatModel.call(prompt); }成功结果是回答里引用了图谱中的实体名而不是泛泛而谈。如果模型开始编造把 temperature 降到 0并在提示词里强调“只依据资料”。验证时建议用 curl 或 Postman 固定请求体方便复现curl -X POST http://localhost:8080/ask \ -H Content-Type: application/json \ -d {question:合同金额是多少}返回 JSON 里能看到答案和命中的实体。到这一步多模态问答链路就算跑通了。5. 本篇常见报错排查401、local proxy failed 与 reading choices接入过程里报错集中在几个地方逐个说。401 Unauthorized。最常见原因是 Key 没设进环境变量或者 application.yml 里写了占位符没替换。检查echo $TAOTOKEN_API_KEY是否有值再确认 base-url 是https://taotoken.net/api不要多加/v1或结尾斜杠。Spring AI 的 OpenAI starter 会自己拼路径多写反而 404 或 401。local proxy failed。这个报错通常出现在本机网络环境有额外代理设置时Java 进程读到了系统代理变量。检查HTTP_PROXY、HTTPS_PROXY是否被设置必要时在启动参数里排除或确认本机网络能直连目标地址。注意不要用任何非正规网络工具企业环境走正规出口即可。reading choices 相关报错比如Cannot deserialize value of type ... from Object value (token JsonToken.START_OBJECT)或reading choices失败。这多半是模型返回的 JSON 结构和你的实体类不匹配。比如模型返回了 markdown 代码块包裹的 JSON或者字段名对不上。解决办法提示词里明确“只返回 JSON不要 markdown”实体类字段用JsonProperty对齐必要时加容错解析先取choices[0].message.content再二次解析。OAuth 或 token 过期类报错。如果你用的是需要刷新 token 的通道检查 Key 是否过期重新在控制台生成。Spring AI 默认用静态 Key不处理刷新过期就换。还有一类是 Neo4j 连接失败报Unable to connect to bolt://localhost:7687。确认 Neo4j 已启动密码对端口没被占。图谱写入失败时先单独跑一条 MERGE 语句验证连接。排查顺序建议先 ping 模型再测解析再测图谱最后测问答。哪一步断就在哪一步查别一次改多处。6. 把链路接进现有 Spring Boot 服务的下一步链路跑通后下一步是工程化。把解析、抽取、写入做成异步任务用消息队列解耦避免大文件阻塞请求线程。图谱查询加缓存热点实体不用每次查库。提示词抽到配置中心方便按业务调不用重新发版。模型通道方面统一 Key 的好处是换模型只改配置。文本模型、视觉模型、embedding 模型各留一个 Model ID 配置项按场景切换。长期做编码和 Agent 任务的话可以在控制台看 coding plan 是否合适只是验证模型效果用模型对话页面快速试提示词更省事。接入文档和 API Key 管理都在控制台里建议把 Key 按环境分开测试和生产的 Key 不要混用。文档解析的边界情况很多扫描件质量差、表格跨页、字体嵌入异常都会影响抽取实际项目里要留人工校验入口别全自动写库。最后给一个实用技巧抽取结果先落一张中间表人工确认后再写图谱。这样即使模型抽错也不会污染图谱。等准确率稳定了再逐步放开自动写入。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →