尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Java Agent项目创建与学习:用TaoToken统一Key接入LangChain4j的AiService与ChatMemory

发布时间:2026/9/27 18:34:43

资讯中心
01
ARTICLE

Java Agent项目创建与学习:用TaoToken统一Key接入LangChain4j的AiService与ChatMemory

Java Agent项目创建与学习:用TaoToken统一Key接入LangChain4j的AiService与ChatMemory
1. Java Agent 项目从零起步为什么我建议先用 TaoToken 统一 Key如果你是一名 Java 后端最近想动手做一个 AI Agent 项目大概率会卡在第一步模型 API 怎么接。LangChain4j 本身是 Java 生态里做 AI 应用最顺手的框架AiService声明式接口、ChatMemory对话记忆、RAG 检索增强这几块拼起来就是一个能用的智能体骨架。但真正落地时你会发现每个模型厂商的 Key、Base URL、模型名都不一样项目里散落一堆配置换个模型就要改代码。我这次的做法是用 TaoToken 作为统一的 API 通道把 Key 和 Base URL 收敛成一份配置LangChain4j 只认 OpenAI 兼容协议底层换什么模型对业务代码透明。这样AiService和ChatMemory的写法完全不变RAG 的 Embedding 也能走同一条通道。适合谁适合已经会 Spring Boot、想用 Java 而不是 Python 做 Agent 的开发者也适合团队里需要统一模型接入层、不想每个项目重复造轮子的场景。这篇会交付四样东西可复制的pom.xml依赖、application.yml配置骨架、最小可运行的 Agent 示例含AiServiceChatMemory以及 RAG 检索结果的验证动作。全程按「能跑起来」的标准写不堆概念。2. TaoToken 前置准备拿 Key、认通道、配环境TaoToken 在这里扮演的角色是「统一入口」你只需要一个 Key就能通过 OpenAI 兼容协议访问背后的模型能力。对 LangChain4j 来说它就是一个标准的 OpenAI 端点所以langchain4j-open-ai-spring-boot-starter可以直接用不需要额外的适配器。第一步去控制台创建 API Key。地址是https://taotoken.net/console登录后在 API Keys 页面新建一个复制出来先存好后面配置里要用。注意 Key 只在创建时完整显示一次丢了就重新建。第二步确认 API 通道地址。TaoToken 的 API 根地址是https://taotoken.net/api在 LangChain4j 里配置base-url时填这个。模型名按你实际要用的填比如gpt-4o-mini这类 OpenAI 兼容命名具体以控制台模型列表为准。第三步环境准备。JDK 17 或以上Maven 3.8IDEA 或 VS Code 都行。我试过用 Spring Initializr 生成骨架勾选 Spring Web 和 Lombok 就够剩下的依赖手动加。如果你习惯命令行也可以直接mvn archetype:generate但 Initializr 更省事。注意Key 不要硬编码进代码提交到仓库本地用application-local.yml或者环境变量注入生产环境走配置中心。3. 可复制配置pom 依赖与 application.yml 骨架3.1 pom.xml 依赖清单LangChain4j 的版本迭代比较快这里用0.35.0作为基线Spring Boot 用3.2.x。核心依赖就四个Web、LangChain4j 核心 starter、OpenAI 兼容 starter、以及测试。properties java.version17/java.version langchain4j.version0.35.0/langchain4j.version /properties dependencies !-- Spring Boot Web -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- LangChain4j 核心 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-spring-boot-starter/artifactId version${langchain4j.version}/version /dependency !-- OpenAI 兼容通道TaoToken 走这个 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-open-ai-spring-boot-starter/artifactId version${langchain4j.version}/version /dependency !-- 本地 Embedding 模型RAG 用不依赖外部服务 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-embeddings-all-minilm-l6-v2/artifactId version${langchain4j.version}/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies这里有个坑langchain4j-embeddings-all-minilm-l6-v2会下载一个几十 MB 的本地模型文件第一次构建会慢但之后离线也能用适合学习阶段。3.2 application.yml 配置骨架配置分三块服务端口、TaoToken 通道、LangChain4j 的 OpenAI 参数。注意base-url填 TaoToken 的 API 地址api-key填你控制台拿到的 Key。server: port: 8080 langchain4j: open-ai: chat-model: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} model-name: gpt-4o-mini temperature: 0.7 timeout: PT60S streaming-chat-model: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} model-name: gpt-4o-miniTAOTOKEN_API_KEY通过环境变量注入IDEA 里在 Run Configuration 的 Environment variables 里加一行就行。这样配置的好处是以后要换模型只改model-nameAiService和ChatMemory的代码一行不动。4. 最小可运行 AgentAiService ChatMemory RAG4.1 定义 AiService 接口AiService是 LangChain4j 最舒服的地方你只写接口框架自动生成实现。加上SystemMessage设定角色加上MemoryId让对话记忆按用户隔离。package com.example.agent.service; import dev.langchain4j.service.MemoryId; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.UserMessage; import dev.langchain4j.service.spring.AiService; AiService public interface AgentAssistant { SystemMessage(你是一个 Java AI 助手回答简洁、专业涉及代码时给出可运行示例。) String chat(MemoryId String userId, UserMessage String message); }4.2 配置 ChatMemoryProviderChatMemory的本质是保存历史对话下一次提问时一起发给模型。MessageWindowChatMemory.withMaxMessages(10)表示保留最近 10 条消息超出就丢弃最早的。多用户场景下用memoryId区分不同会话。package com.example.agent.config; import dev.langchain4j.memory.chat.ChatMemoryProvider; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class MemoryConfig { Bean public ChatMemoryProvider chatMemoryProvider() { return memoryId - MessageWindowChatMemory.withMaxMessages(10); } }4.3 挂载 RAG 知识库RAG 的流程是文档切块 → 向量化 → 存向量库 → 用户提问时检索最相似片段 → 拼进 Prompt。这里用内存向量库和本地 Embedding 模型学习阶段够用不用额外服务。package com.example.agent.config; import dev.langchain4j.data.document.Document; import dev.langchain4j.data.document.loader.FileSystemDocumentLoader; import dev.langchain4j.data.document.parser.TextDocumentParser; import dev.langchain4j.data.document.splitter.DocumentSplitters; import dev.langchain4j.data.embedding.Embedding; import dev.langchain4j.data.segment.TextSegment; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.embedding.AllMiniLmL6V2EmbeddingModel; import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever; import dev.langchain4j.store.embedding.EmbeddingStore; import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.nio.file.Paths; import java.util.List; Configuration public class RagConfig { Bean public EmbeddingStoreTextSegment embeddingStore() { return new InMemoryEmbeddingStore(); } Bean public EmbeddingModel embeddingModel() { return new AllMiniLmL6V2EmbeddingModel(); } Bean public EmbeddingStoreContentRetriever contentRetriever( EmbeddingStoreTextSegment store, EmbeddingModel model) { return EmbeddingStoreContentRetriever.builder() .embeddingStore(store) .embeddingModel(model) .maxResults(3) .minScore(0.6) .build(); } Bean public Void initRag(EmbeddingStoreTextSegment store, EmbeddingModel model) { Document doc FileSystemDocumentLoader.loadDocument( Paths.get(documents/my-info.txt), new TextDocumentParser()); ListTextSegment segments DocumentSplitters.recursive(300, 30).split(doc); ListEmbedding embeddings model.embedAll(segments).content(); store.addAll(embeddings, segments); System.out.println(RAG 初始化完成片段数 segments.size()); return null; } }documents/my-info.txt放在项目根目录内容随便写几段你的业务说明比如产品 FAQ、接口文档摘要。maxResults(3)表示每次检索返回最相似的 3 个片段minScore(0.6)过滤掉相似度太低的避免无关内容污染 Prompt。4.4 Controller 暴露接口package com.example.agent.controller; import com.example.agent.service.AgentAssistant; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; RestController public class AgentController { private final AgentAssistant assistant; public AgentController(AgentAssistant assistant) { this.assistant assistant; } GetMapping(/chat) public String chat(RequestParam String userId, RequestParam String msg) { return assistant.chat(userId, msg); } }5. 验证请求对话记忆与 RAG 检索是否生效5.1 验证 ChatMemory启动项目先发两条消息看第二条能不能记住第一条的内容。curl http://localhost:8080/chat?userIduser1msg我叫张三在做Java Agent项目 curl http://localhost:8080/chat?userIduser1msg我叫什么在做什么预期第二条返回里包含「张三」和「Java Agent」。如果返回的是「我不知道」说明ChatMemoryProvider没生效检查MemoryId参数名和ChatMemoryProviderBean 是否都被 Spring 扫描到。再换一个userIduser2问同样的问题应该答不出来说明记忆是按用户隔离的。5.2 验证 RAG 检索在documents/my-info.txt里写一句独特的内容比如「本项目的内部代号是 BlueWhale部署端口是 18080」。然后提问curl http://localhost:8080/chat?userIduser1msg本项目的内部代号是什么如果返回「BlueWhale」说明 RAG 链路通了文档被切块、向量化、存入内存库提问时检索到了相关片段并拼进了 Prompt。如果答不出来先看启动日志里「RAG 初始化完成片段数N」的 N 是不是 0是 0 说明文件路径不对或文件为空。5.3 验证模型通道单独发一条不依赖记忆和 RAG 的问题确认 TaoToken 通道本身是通的curl http://localhost:8080/chat?userIdtestmsg用一句话解释什么是向量数据库能正常返回就说明 Key、Base URL、模型名三者匹配。如果报 401检查 Key报 404检查base-url和model-name。6. 本篇常见错排查报错一No AiService bean found。通常是AiService注解的包不在 Spring 扫描范围内。把接口放在启动类同级或子包下或者用AiService的scan属性指定包名。报错二Connection refused或超时。检查base-url是不是https://taotoken.net/api注意结尾不要多斜杠。如果公司网络有出口限制确认能访问该域名。报错三ChatMemory 不生效每次都是新对话。最常见的原因是MemoryId参数没加或者ChatMemoryProviderBean 没定义。LangChain4j 只有在检测到MemoryId且存在ChatMemoryProvider时才会启用记忆。报错四RAG 检索结果不相关。调minScore默认 0.6 偏高可以降到 0.5 试试或者调maxResults从 3 加到 5。另外文档切块大小300和重叠30也要根据文档类型调技术文档可以小一点FAQ 可以大一点。报错五本地 Embedding 模型下载失败。第一次构建需要联网下载模型文件如果卡住检查 Maven 仓库配置或者手动下载后放到本地仓库。这个模型只有几十 MB正常网络几分钟就好。报错六流式输出没反应。如果用FluxString做 SSEController 的produces必须是MediaType.TEXT_EVENT_STREAM_VALUE且前端要用EventSource接收。普通curl看不到流式效果用浏览器或curl -N才行。7. 下一步把 Key 管好把 Agent 跑远项目跑通之后真正要长期维护的是接入层。TaoToken 在这里的价值不是「多一个通道」而是把 Key 管理、模型切换、用量查看收敛到一个地方。你可以在控制台看到每个 Key 的调用情况换模型时只改application.yml里的model-nameAiService、ChatMemory、RAG 的代码完全不用动。如果你准备把这个 Agent 用到长期编码或自动化任务里可以看看 Coding Plan它更适合持续性的开发场景如果只是想先验证模型对话效果模型对话页面可以直接试接入过程中遇到 Key 或通道问题API Keys 页面和接入文档里有完整的参数说明。先把最小闭环跑起来再逐步加 Function Calling 和 MCP这条路我走过顺序对了就不容易卡住。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。