尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Spring AI Alibaba OpenManus 代码示例:把 Base URL 改到 TaoToken 的完整配置

Spring AI Alibaba OpenManus 代码示例:把 Base URL 改到 TaoToken 的完整配置 1. 从零跑通 Spring AI Alibaba 与 OpenManus 的联调链路Spring AI Alibaba 是阿里云把 Spring 生态和通义千问系列模型接起来的一套脚手架OpenManus 则是把「任务规划 分步执行」这套多智能体思路落到代码里的一个轻量实现。把两者拼在一起你得到的是一个能自己拆任务、自己调工具、最后产出结果的 Java 服务。适合谁适合已经会写 Spring Boot、想给项目加一个「会思考的执行器」的后端同学也适合想拿 Java 而不是 Python 做 Agent 实验的团队。真正卡人的地方往往不是业务代码而是模型请求到底发到哪个地址。默认配置会指向阿里云百炼的官方端点但很多团队希望统一走一个兼容 OpenAI 协议的网关把 Key 管理、额度、日志收口到一处。这篇就干一件事把 Spring AI Alibaba 和 OpenManus 的 Base URL 一起改到 TaoToken从 pom 依赖、application.yml、多智能体实现到一次真实对话请求的返回对照全部给成可复制的片段。我试过直接照搬官方示例结果发现 access-key / secret-key 那套签名方式和 OpenAI 兼容协议不是一回事改起来要动底层。所以下面走的是「OpenAI 兼容」这条路把 base-url 指向https://taotoken.net/api用 API Key 鉴权模型 ID 显式写清楚。这样 Spring AI Alibaba 的 OpenAI starter 和 OpenManus 里手写的 HTTP 调用能共用同一套配置链路只有一条排障也只看一个地方。先明确目标产物一个 Spring Boot 工程暴露POST /api/manus/process收到一句自然语言任务后PlanningAgent 拆成步骤ManusAgent 逐步执行FileUtils 负责落盘最后返回多步结果。整条链路里所有模型调用都打到 TaoToken。下面按「依赖 → 配置 → 代码 → 验证 → 排错」推进每一步都能单独复制运行。2. TaoToken 前置准备拿到 Base URL、API Key 和模型 ID在写代码之前先把三样东西备齐后面所有配置都围绕它们展开。这三样是Base URL、API Key、Model ID。缺任何一个请求都会在鉴权或路由阶段挂掉。Base URL 用https://taotoken.net/api注意不要带任何查询参数Spring 的base-url拼接时会把/v1/chat/completions这类路径接在后面多一个斜杠或少一个斜杠都可能 404。API Key 在控制台的 API Keys 页面创建形如sk-开头的一串字符创建后只显示一次记得当场复制到安全的地方。Model ID 要和你实际开通的模型对齐比如通义千问系列或其它兼容模型写错模型名会直接返回 model not found。创建 Key 的入口在这里https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys 。进去后点新建命名随意建议按项目区分比如spring-ai-manus-dev方便后面按项目看用量。创建完把 Key 存到环境变量别硬编码进 yml 提交到仓库。注意API Key 等同于账号凭证不要贴到 issue、群聊或前端代码里。本地开发用环境变量线上用配置中心或密钥管理服务。如果你还没确认模型是否可用可以先到模型对话页面发一条测试消息确认账号和模型都正常再去写 Java 代码。这样能把「账号问题」和「代码问题」分开排障时少绕路https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel_chat 。三样东西备齐后把它们写进环境变量后面 yml 里用占位符引用export TAOTOKEN_BASE_URLhttps://taotoken.net/api export TAOTOKEN_API_KEYsk-你的真实Key export TAOTOKEN_MODELqwen-plusWindows PowerShell 用$env:TAOTOKEN_API_KEYsk-...IDEA 里则在 Run Configuration 的 Environment variables 里填。这一步做完配置层就不会再出现明文密钥。3. 可复制配置pom.xml 依赖与 application.yml 完整片段先看依赖。Spring AI Alibaba 的 starter 负责把模型客户端自动装配好我们额外引入 OpenAI 兼容的 starter因为要走 TaoToken 的 OpenAI 协议端点。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 groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-ai/artifactId version2023.0.1/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies版本号按你工程的 Spring Boot 版本对齐M6 是里程碑版本若你用的是正式版把版本换成对应 GA 即可。依赖冲突最常见的是 spring-ai 各模块版本不一致建议用 dependencyManagement 统一锁版本。接下来是 application.yml这是整篇的核心Base URL、Key、Model ID 三件套都在这里server: port: 8080 spring: ai: openai: base-url: ${TAOTOKEN_BASE_URL} api-key: ${TAOTOKEN_API_KEY} chat: options: model: ${TAOTOKEN_MODEL} temperature: 0.7 cloud: ai: alibaba: # 走 OpenAI 兼容协议时下面这组签名配置留空即可 access-key: secret-key: region: cn-hangzhou manus: model: base-url: ${TAOTOKEN_BASE_URL} api-key: ${TAOTOKEN_API_KEY} model-id: ${TAOTOKEN_MODEL}这里有个关键点spring.ai.openai.base-url指向 TaoToken 后Spring AI 自动装配的 ChatClient 就会把请求发到 TaoToken而不是默认的 OpenAI 官方地址。manus.model这组是给 OpenManus 里手写 HTTP 调用用的保证两条路径指向同一个网关。三件套Base URL Key Model ID在 yml 里各出现一次改的时候只改环境变量配置本身不动。如果你用 Cline MCP 或 Codex 的 auth.json 做本地辅助调试思路一样Base URL 填https://taotoken.net/apiKey 填同一个Model ID 保持一致。三件套对齐跨工具才不会出现「这个工具能通、那个工具 401」的怪现象。提示yml 里用${VAR}占位符时如果环境变量没设Spring 启动会直接报 placeholder 解析失败。启动前先echo $TAOTOKEN_API_KEY确认非空。配置写完先别急着写业务代码跑一次mvn spring-boot:run看启动日志里有没有 OpenAI 客户端初始化的记录。启动成功说明配置层没问题再往下写 Agent。4. 多智能体实现与一次对话请求的验证对照代码部分按职责拆成四块PlanningAgent 负责拆任务ManusAgent 负责执行单步FileUtils 负责落盘Controller 串起来。先看 PlanningAgent它调用模型把一句话拆成步骤列表Service public class PlanningAgent { private final ChatClient chatClient; public PlanningAgent(ChatClient.Builder builder) { this.chatClient builder.build(); } public ListString decomposeTask(String prompt) { String system 你是一个任务规划器把用户任务拆成3到5个可执行步骤 每行一个步骤以 STEP 开头不要输出多余解释。; String content chatClient.prompt() .system(system) .user(prompt) .call() .content(); return Arrays.stream(content.split(\n)) .map(String::trim) .filter(s - s.startsWith(STEP)) .toList(); } }ManusAgent 接收单个步骤调用模型生成该步骤的结果。为了演示可跟做这里保留一个 switch 兜底真实项目里应全部走模型Service public class ManusAgent { private final ChatClient chatClient; public ManusAgent(ChatClient.Builder builder) { this.chatClient builder.build(); } public String executeStep(String step) { return chatClient.prompt() .system(你是一个执行器针对给定步骤输出简洁结果不超过80字。) .user(step) .call() .content(); } }Controller 把两者串起来并调用 FileUtils 落盘RestController RequestMapping(/api/manus) public class OpenManusController { private final PlanningAgent planner; private final ManusAgent executor; private final FileUtils fileUtils; public OpenManusController(PlanningAgent planner, ManusAgent executor, FileUtils fileUtils) { this.planner planner; this.executor executor; this.fileUtils fileUtils; } PostMapping(/process) public String processTask(RequestBody String prompt) { StringBuilder result new StringBuilder(); ListString steps planner.decomposeTask(prompt); for (String step : steps) { result.append(step).append( - ) .append(executor.executeStep(step)).append(\n); } result.append(fileUtils.generateReport(result.toString())); return result.toString(); } }FileUtils 简单写一个落盘方法即可Component public class FileUtils { public String generateReport(String content) { String path /tmp/reports/ UUID.randomUUID() .txt; // 真实项目写文件这里返回路径示意 return 报告已生成 path; } }启动服务后用 curl 发一次请求curl -X POST http://localhost:8080/api/manus/process \ -H Content-Type: text/plain \ -d 分析一下当前新能源行业的趋势预期返回是多行「STEP - 结果」最后一行是报告路径。如果返回里出现了模型生成的中文步骤描述说明 PlanningAgent 的请求已经打到 TaoToken 并成功返回如果返回 401 或连接超时问题在配置层往下看排错章节。成功结果对照HTTP 200body 里至少包含 3 个 STEP 行且没有异常堆栈。这一步通了整条链路就算打通。5. 本篇常见错排查401、local proxy failed 与 reading choices排错按「报错原文 → 原因 → 处理」来都是实际会撞到的。401 Unauthorized / invalid api key最常见。原因通常是 Key 没设进环境变量、Key 复制时带了空格、或者 yml 里写的是占位符但环境变量为空。处理echo $TAOTOKEN_API_KEY确认非空且以sk-开头检查 yml 里是${TAOTOKEN_API_KEY}而不是硬编码的旧 Key重启服务让新环境变量生效。如果用的是 IDEA注意 Run Configuration 里的环境变量和系统环境变量是两套。local proxy failed / connection refused请求根本没发出去。原因多是 base-url 写错比如漏了/api、多了结尾斜杠、或者写成了带 UTM 的完整链接。处理base-url 严格用https://taotoken.net/api不带查询参数。另外检查本机网络是否能正常访问该域名公司网络若有出站限制需要放行。reading choices / Cannot deserialize请求发出去了但返回体解析失败。原因通常是模型 ID 写错网关返回了错误结构而客户端按正常 chat completion 结构去解析choices字段自然读不到。处理确认TAOTOKEN_MODEL是你账号下真实可用的模型名先用模型对话页面发一条消息验证该模型可用再检查 yml 里 model 字段有没有拼写错误。OAuth / token expired如果你混用了需要 OAuth 的鉴权方式会出现这类报错。TaoToken 走的是 API Key 鉴权不需要 OAuth 流程。处理确认没有引入额外的 OAuth 拦截器yml 里 access-key / secret-key 留空只保留 api-key。启动报 placeholder 解析失败环境变量没设Spring 解析${TAOTOKEN_API_KEY}失败。处理补齐三个环境变量再启动或者临时在 yml 里写死测试测完记得改回占位符。排错时建议打开 Spring AI 的 debug 日志能看到实际请求的 URL 和返回码logging: level: org.springframework.ai: DEBUG日志里如果看到请求 URL 是https://taotoken.net/api/v1/chat/completions说明 base-url 拼接正确如果看到的是别的域名说明配置没生效回去检查 yml 层级是否写对。6. 把链路固定下来接入文档与后续调试入口链路跑通之后建议把三件套固化到配置中心本地只保留占位符避免 Key 泄露。后续要加新模型、调温度、换模型 ID都只改环境变量代码和 yml 不动。这套结构的好处是Spring AI Alibaba 的自动装配和 OpenManus 的手写调用共用同一个网关日志、额度、鉴权都在一处出问题只看一个地方。接入过程中如果遇到协议细节、参数含义、返回结构的问题可以对照接入文档逐项核对https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc 。文档里有完整的请求示例和字段说明比对着改比盲试快得多。如果你打算把这个示例往长期编码或 Agent 方向扩展比如让 PlanningAgent 调用更多工具、让 ManusAgent 支持多轮反思可以考虑用 Coding Plan 来管理额度和模型避免开发阶段频繁切换 Keyhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding_plan 。最后给一个实用技巧把 curl 验证脚本存成verify.sh每次改完配置先跑脚本再启动服务能第一时间发现 Key 或 base-url 的问题比等服务起来再调快很多。脚本里只读环境变量不写死任何密钥团队里谁都能用。
返回列表