☰
基于 Spring AI + Skill 工程 + MCP 技术方案研究:用 TaoToken 统一 Key 打通通义千问法律知识库
2026/9/28 19:40:19 网站建设 项目流程

1. 法律知识库问答为什么需要 Spring AI + Skill + MCP 三层配合

法律知识库问答和普通文档问答最大的区别在于:答案必须可追溯、条款必须准确、工具调用必须可控。我见过不少团队直接用一段 Prompt 把法条塞进上下文,结果模型把《民法典》第 584 条和第 577 条混着说,用户一问细节就露馅。真正能上生产的方案,需要把「模型能力」「领域技能」「外部工具」拆成三层来管。

Spring AI 负责的是模型抽象层。它把 ChatModel、EmbeddingModel、VectorStore 这些接口统一起来,你换模型时不用改业务代码。Skill 工程负责的是领域能力层,把「合同条款提取」「法条检索」「风险评估」这些动作封装成可被模型按需加载的技能,而不是一股脑塞进系统提示。MCP 负责的是工具调用层,让模型通过标准协议去调用 OCR、向量检索、图数据库查询这些外部能力。

这三层配合起来,法律知识库问答才能做到:模型知道什么时候该查法条、查哪个库、查到之后怎么组织答案。而 TaoToken 在这里的角色是统一 Key 和 API 通道——你不需要为通义千问、Embedding 模型、OCR 工具分别维护不同的鉴权配置,一个 Key 走同一个通道,配置和排障都简单很多。

这篇会给出 application.yml 的可复制配置骨架、MCP Server 注册与 Skill 编排示例,以及一次法律条文检索问答的完整验证动作。目标是你照着跑一遍,端到端链路能通。

2. TaoToken 前置:统一 Key 与 API 通道准备

在写 Spring AI 配置之前,先把 Key 和通道准备好。TaoToken 的定位是统一 API 通道,你可以在控制台创建 Key,然后所有模型调用都走同一个 base-url。这样做的好处是:Spring AI 里只需要配一份 api-key,不用为每个模型单独管理凭证。

具体操作路径:访问官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册后进入控制台,在 API Keys 页面创建一个新 Key。创建时建议按项目命名,比如legal-kb-dev,方便后续区分环境。

拿到 Key 之后,API 通道地址是 https://taotoken.net/api(注意这个地址不加 UTM 参数,直接作为 base-url 使用)。Spring AI 的 OpenAI 兼容模式可以直接对接这个地址,因为 TaoToken 提供的是 OpenAI 兼容接口。

如果你需要确认模型名称和可用列表,可以打开模型对话页面实际发一条消息测试。对于法律知识库场景,通义千问系列的中文理解能力比较适合,Embedding 模型用于向量检索。Coding Plan 更适合长期编码和 Agent 场景,如果你后续要把这套链路做成常驻服务,可以考虑。

注意:Key 不要硬编码在代码里,用环境变量或配置中心注入。下面 application.yml 里我用${TAOTOKEN_API_KEY}占位。

3. 可复制配置:application.yml 与 Spring AI 接入骨架

先给出完整的 application.yml 配置骨架。这份配置的核心是把 TaoToken 作为统一通道,同时配置 Chat 模型和 Embedding 模型。

spring: ai: openai: api-key: ${TAOTOKEN_API_KEY} base-url: https://taotoken.net/api chat: options: model: qwen-plus temperature: 0.3 max-tokens: 2048 embedding: options: model: text-embedding-v3 vectorstore: type: simple simple: initialize-schema: true mcp: server: name: legal-kb-mcp version: 1.0.0 transport: sse endpoint: /mcp/sse legal: kb: top-k: 5 similarity-threshold: 0.72 max-context-chars: 6000

这里有几个参数需要解释。temperature设成 0.3 是因为法律问答需要稳定输出,不能太发散。top-k: 5表示每次检索召回 5 条法条或案例,similarity-threshold: 0.72是相似度阈值,低于这个值的召回结果会被过滤掉,避免无关法条污染上下文。max-context-chars: 6000控制注入模型的法律上下文长度,防止超出模型窗口。

接下来是 Spring AI 的 ChatClient 配置类。这里我把 Skill 的提示增强和 MCP 工具注册都挂上去。

@Configuration public class LegalAiConfig { @Bean public ChatClient chatClient(ChatModel chatModel, SkillRegistry skillRegistry, McpToolCallbackProvider mcpTools) { return ChatClient.builder(chatModel) .defaultSystem(""" 你是法律知识库问答助手。回答必须基于检索到的法条和案例, 引用时标注法条编号。如果检索结果不足以回答,明确说明。 """) .defaultAdvisors( SkillPromptAugmentAdvisor.builder() .skillRegistry(skillRegistry) .build() ) .defaultTools(mcpTools) .build(); } }

SkillPromptAugmentAdvisor的作用是把 Skill 的元数据注入系统提示,模型在需要时通过read_skill加载完整技能文档。McpToolCallbackProvider负责把 MCP Server 暴露的工具注册成 Spring AI 可调用的 ToolCallback。

Skill 的定义我放在classpath:skills目录下,每个 Skill 一个 Markdown 文件。比如法条检索技能:

--- name: legal_provision_search description: 根据关键词或语义检索法律法规条文 tools: - mcp__legal_kb__search_provisions --- ## 使用场景 当用户询问具体法律条文、合规依据时调用此技能。 ## 执行步骤 1. 提取用户问题中的法律概念关键词 2. 调用 search_provisions 工具,传入关键词和 top_k 3. 对返回结果按相似度排序,过滤低于阈值的条目 4. 将法条原文和编号组织成回答

MCP Server 的注册配置如下。这里用 SSE 传输方式,Spring AI 的 MCP 客户端会自动发现工具列表。

spring: ai: mcp: client: sse: connections: legal-kb: url: http://localhost:8081/mcp/sse sse-endpoint: /mcp/sse

MCP Server 端我用一个简化的 Controller 暴露法条检索工具:

@RestController public class LegalKbMcpController { private final LegalKnowledgeBase knowledgeBase; public LegalKbMcpController(LegalKnowledgeBase knowledgeBase) { this.knowledgeBase = knowledgeBase; } @Tool(name = "search_provisions", description = "根据关键词检索法律法规条文,返回法条编号、内容和相似度") public List<ProvisionResult> searchProvisions( @ToolParam("keyword") String keyword, @ToolParam("topK") int topK) { return knowledgeBase.semanticSearch(keyword, topK); } @Tool(name = "search_cases", description = "检索与问题相关的司法案例") public List<CaseResult> searchCases( @ToolParam("caseType") String caseType, @ToolParam("facts") String facts) { return knowledgeBase.searchSimilarCases(caseType, facts); } }

4. 验证请求:一次法律条文检索问答的完整动作

配置写完之后,最关键的是验证端到端链路能不能通。我设计了一个最小验证场景:用户问「服务合同违约金过高可以调整吗」,系统应该检索到《民法典》第 585 条,并给出可追溯的回答。

先写一个测试 Controller:

@RestController @RequestMapping("/api/legal") public class LegalQaController { private final ChatClient chatClient; public LegalQaController(ChatClient chatClient) { this.chatClient = chatClient; } @PostMapping("/ask") public QaResponse ask(@RequestBody QaRequest request) { String answer = chatClient.prompt() .user(request.question()) .call() .content(); return new QaResponse(answer); } }

启动应用后,用 curl 发一条请求:

curl -X POST http://localhost:8080/api/legal/ask \ -H "Content-Type: application/json" \ -d '{"question":"服务合同约定的违约金过高,可以请求调整吗?"}'

预期返回应该包含几个关键要素:引用《民法典》第 585 条关于违约金调整的规定,说明「约定的违约金过分高于造成的损失的,人民法院或者仲裁机构可以根据当事人的请求予以适当减少」,并且标注法条编号。

实际跑下来,模型会先调用legal_provision_search技能,通过 MCP 工具检索到相关法条,然后组织回答。如果你在日志里看到 MCP 工具调用记录和法条召回结果,说明链路是通的。

验证成功的标志有三个:第一,回答里出现了具体的法条编号而不是泛泛而谈;第二,日志里有 MCP 工具调用记录;第三,检索到的法条相似度分数在阈值以上。如果这三点都满足,端到端链路就跑通了。

5. 本篇常见错排查

5.1 401 鉴权失败或 base-url 配错

最常见的问题是 api-key 没注入成功,或者 base-url 写成了带路径的地址。检查两点:环境变量TAOTOKEN_API_KEY是否在启动时生效,base-url 是否严格是https://taotoken.net/api。如果用了 IDE 启动,确认 Run Configuration 里加了环境变量。

5.2 MCP 工具注册不上,模型不调用

如果模型回答时完全不调用工具,先检查 MCP Server 是否正常启动,SSE 端点是否可访问。可以在浏览器直接打开http://localhost:8081/mcp/sse看是否有事件流返回。另外确认McpToolCallbackProvider是否被正确注入到 ChatClient,工具名称是否和 Skill 文档里声明的一致。

5.3 检索结果不相关或法条召回为空

这通常是 Embedding 模型配置问题或相似度阈值设太高。先把similarity-threshold降到 0.6 测试,如果还是召回为空,检查向量库是否已经写入了法条数据。另外确认 Embedding 模型名称和 TaoToken 通道支持的模型一致,模型名写错会导致向量维度不匹配。

5.4 回答超出上下文长度被截断

法律问答容易召回大量法条,如果max-context-chars设太大,会挤占模型输出空间。建议控制在 6000 字符以内,同时对召回结果做去重和排序,只保留最相关的 top-k 条。如果单条法条太长,可以在 Skill 里做摘要预处理。

5.5 Skill 加载失败或提示注入无效

检查classpath:skills目录下的 Markdown 文件格式,front matter 的name和description必须存在。如果 Skill 没被加载,模型就不知道有这个技能可用。可以在启动日志里搜索 SkillRegistry 的加载记录,确认技能数量符合预期。

6. 继续接入与长期运行的建议

如果你要把这套链路做成长期运行的服务,建议把 Coding Plan 用起来,它更适合常驻 Agent 和编码场景,Key 管理和额度控制也更清晰。接入文档在 https://taotoken.net/api-keys 和 https://taotoken.net/doc 可以查到完整的参数说明和错误码对照。

模型对话页面适合快速验证模型可用性和回答质量,在正式接入前先用它测几条法律问题,确认通义千问在你这个领域的表现符合预期。控制台的 API Keys 页面可以创建多个 Key 做环境隔离,开发、测试、生产各用一个,排障时不会互相干扰。

实测下来,法律知识库问答的难点不在模型本身,而在检索质量和工具调用的可控性。Skill 工程把领域逻辑从 Prompt 里抽出来,MCP 把外部工具标准化,Spring AI 把模型调用统一起来,这三层各司其职,链路才稳定。你可以先从一条法条检索跑通,再逐步加案例检索和风险评估技能,不要一上来就铺大摊子。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询