当前位置: 首页 > article >正文

基于RAG的智能客服系统实战:从架构设计到生产环境优化

最近在做一个智能客服系统的升级项目之前用规则引擎维护起来太痛苦了纯用大模型又贵又不准。经过一番折腾最终用RAG检索增强生成技术搞定了效果提升非常明显。今天就来分享一下从架构设计到上线优化的完整实战经验希望能帮到有类似需求的同学。一、为什么选RAG先聊聊传统方案的坑在动手之前我们得先搞清楚为什么要用RAG。我们之前的客服系统主要经历了两个阶段痛点都很明显。规则引擎时代这是最开始的方案靠人工写大量的if-else规则。用户问“怎么退货”我们就匹配关键词“退货”然后返回预设好的答案。这种方案的缺点是维护成本高公司业务一变产品一更新规则库就得跟着大改费时费力。灵活性差用户稍微换个问法比如“商品不想要了能退吗”可能就匹配不上规则了。知识更新慢新政策、新功能上线后需要人工将知识录入规则库存在延迟。纯LLM大语言模型时代后来我们尝试直接把用户问题扔给像GPT-4这样的模型。效果确实更智能了能理解更复杂的表述。但新问题来了“幻觉”问题模型可能会一本正经地胡说八道编造一些我们公司根本不存在的政策或服务。知识滞后模型训练数据有截止日期无法获取最新的、公司内部特定的知识比如昨天刚上线的活动规则。成本高昂每次对话都调用GPT-4token消耗大长期下来是一笔不小的开销。不可控回答内容完全由模型决定难以确保100%符合公司规范。RAG正好能解决这些痛点。它的核心思想是“先检索后生成”。当用户提问时系统先从我们自己的、最新的知识库比如产品文档、客服QA对里找到最相关的几段资料然后把“问题相关资料”一起交给大模型让它基于这些靠谱的资料来生成答案。这样既保证了答案的准确性和时效性又利用了模型的自然语言理解能力。二、技术选型平衡性能、成本与控制力确定了RAG路线接下来就是挑“兵器”了。主要在两个层面做选择向量数据库和生成模型。1. 向量数据库FAISS vs. 云端服务如PineconeFAISS (Facebook AI Similarity Search)这是Meta开源的库特点是高性能、可本地部署。它提供了多种索引算法如IVF, HNSW能在大规模向量上实现快速近似最近邻搜索。选择它主要是因为数据隐私所有数据都在自己服务器上安全可控。零网络延迟检索过程在本地内存或磁盘进行速度快。成本固定没有按查询次数收费的云服务成本。缺点是需要自己维护索引的构建和更新有一定工程复杂度。Pinecone / Weaviate 等云端服务它们是托管的向量数据库开箱即用免运维。对于初创团队或不想在基础设施上投入太多的项目来说很友好。我们最终选择了FAISS因为客服系统对响应延迟要求高目标500ms内且知识库规模初期约10万条FAISS完全可以轻松应对自建方案长期来看成本更低也更符合我们的数据安全策略。2. 生成模型GPT-4 vs. 开源模型如 Llama 3, QwenGPT-4 (ChatGPT API)能力最强生成答案的流畅度和逻辑性通常最好但API调用成本高且存在数据出境风险根据公司合规要求评估。开源大模型如 Llama 3-70B, Qwen-72B可以部署在私有GPU集群上数据完全私有单次调用成本随着规模摊薄会降低。但需要较强的工程能力进行部署、优化和蒸馏。我们的混合策略线上服务为了保障核心体验我们仍然使用GPT-3.5-Turbo作为生成引擎。它在成本、速度和效果上取得了很好的平衡。对于绝大多数客服场景它的能力已经足够。知识检索与冷备检索部分文本转向量我们使用了开源的text-embedding-ada-002的替代方案如BAAI/bge-large-zh模型本地部署效果不错且免费。同时我们也准备好了Qwen-7B的本地部署版本作为在API服务异常或需要极端成本控制时的降级方案。三、核心架构设计让系统跑起来确定了组件我们来设计一个能协同工作的系统架构。整个流程可以概括为“索引构建”和“问答服务”两条线。1. 知识库的实时增量更新机制客服知识是常新的我们的架构必须支持动态更新。监听与抓取我们建立了一个“知识管道”监控内部Confluence、GitHub Wiki等知识源的文件变动。一旦有文档更新或新增系统会自动触发处理流程。文本处理与分块原始文档PDF、Word、Markdown经过解析后被切割成大小适中的“文本块”例如500-1000字符。分块时采用重叠滑动窗口比如重叠100字符防止答案被切碎。向量化与索引更新每个文本块通过嵌入模型转化为向量然后增量更新到FAISS索引中。FAISS不支持真正的增量添加我们的做法是定期如每小时将新向量和原有索引合并重建一个全新的索引文件然后热切换。对于实时性要求极高的场景可以维护一个小的临时索引用于最新数据。2. 检索-生成协同工作流这是用户每次提问时发生的核心流程如下图所示此处用文字描述流程用户提问 - 接收问题 - 将问题转化为向量 - 在FAISS索引中检索Top-K个最相似的文本块 - 将“问题检索到的相关文本”组合成Prompt - 发送给LLM生成答案 - 返回答案给用户检索优化单纯用余弦相似度可能不够。我们引入了MMR (Maximal Marginal Relevance) 排序。它不仅能保证检索到的文本与问题相关还能让这些文本之间具有一定的多样性避免给模型提供重复冗余的信息从而提升生成答案的信息覆盖度。Prompt工程这是提升效果的关键。我们采用n-shot prompting少样本提示在Prompt中给模型几个“问题-检索内容-答案”的例子让它更好地理解任务。同时严格指令模型“仅根据提供的上下文回答问题”并在最后加上“如果上下文没有相关信息请回答‘我不知道’”这能有效减少幻觉。3. 多轮对话状态管理设计客服对话往往是多轮的。用户可能会说“帮我订一张票”然后接着说“明天早上的”。上下文窗口管理我们将整个对话历史包括用户的问题和系统的回答都维护在内存如Redis中并设定一个最大token数限制例如4096。当新的问题到来时我们将最近N轮的历史对话也作为上下文一起输入模型让模型具备“记忆”能力。对话状态追踪对于更复杂的场景如转人工、填写表单我们设计了一个简单的状态机。系统可以识别用户的意图通过分类模型或关键词并切换到相应的处理流程比如收集必要信息后再调用RAG进行回答。四、关键代码实现与优化理论说完了上点干货看看核心部分代码怎么写。1. 核心检索逻辑Python示例这里展示使用sentence-transformers和faiss进行检索的关键代码。import faiss import numpy as np from sentence_transformers import SentenceTransformer from typing import List, Tuple class RAGRetriever: def __init__(self, embedding_model_path: str, faiss_index_path: str): 初始化检索器 :param embedding_model_path: 嵌入模型本地路径如 BAAI/bge-large-zh :param faiss_index_path: 已构建的FAISS索引文件路径 # 加载嵌入模型 self.embedder SentenceTransformer(embedding_model_path) # 加载FAISS索引 self.index faiss.read_index(faiss_index_path) # 假设我们有一个列表存储了所有文本块索引id与之一一对应 self.text_chunks self._load_text_chunks() def retrieve(self, query: str, top_k: int 5) - List[Tuple[str, float]]: 检索与问题最相关的文本块 :param query: 用户问题 :param top_k: 返回最相关的K个结果 :return: 返回文本内容相似度得分的列表 # 1. 将用户问题转化为向量 query_vector self.embedder.encode([query], normalize_embeddingsTrue) # 2. 在FAISS索引中搜索 distances, indices self.index.search(query_vector, top_k) # 3. 组装结果 results [] for idx, distance in zip(indices[0], distances[0]): # FAISS返回的距离是L2距离越小越相似。可以转化为相似度分数可选 score 1 / (1 distance) # 简单转换仅供参考 results.append((self.text_chunks[idx], score)) return results def _load_text_chunks(self) - List[str]: # 这里应从数据库或文件加载所有文本块返回一个列表 # 示例return [文本块1内容, 文本块2内容, ...] pass # 使用示例 retriever RAGRetriever(./models/bge-large-zh, ./data/faiss_index.bin) relevant_docs retriever.retrieve(请问你们的退货政策是什么) for doc, score in relevant_docs: print(f相似度{score:.4f}, 内容{doc[:100]}...)嵌入优化技巧normalize_embeddingsTrue非常重要它会对向量进行归一化此时余弦相似度等价于内积而FAISS的L2距离在归一化后也与余弦相似度单调相关能保证检索质量。2. FastAPI接口的异步化改造为了应对高并发我们必须用异步。from fastapi import FastAPI, BackgroundTasks from pydantic import BaseModel import asyncio from your_rag_module import RAGRetriever, LLMGenerator # 假设的模块 app FastAPI() retriever RAGRetriever(...) generator LLMGenerator(...) # 封装了调用LLM的逻辑 class QueryRequest(BaseModel): question: str session_id: str None # 用于多轮对话 class QueryResponse(BaseModel): answer: str session_id: str sources: List[str] # 可返回引用的知识片段来源 app.post(/ask, response_modelQueryResponse) async def ask_question(request: QueryRequest, background_tasks: BackgroundTasks): 处理用户提问的异步接口 # 1. 异步检索I/O密集型适合异步 loop asyncio.get_event_loop() # 将同步的检索函数放到线程池中执行避免阻塞事件循环 relevant_docs await loop.run_in_executor(None, retriever.retrieve, request.question) # 2. 异步生成调用外部API也是I/O密集型 answer await generator.generate_async(request.question, relevant_docs, request.session_id) # 3. 可选后台任务例如记录日志、更新对话历史到Redis background_tasks.add_task(log_interaction, request.question, answer, request.session_id) return QueryResponse( answeranswer, session_idrequest.session_id or generate_session_id(), sources[doc[0][:200] for doc in relevant_docs] # 截取部分作为来源展示 ) def log_interaction(question: str, answer: str, session_id: str): # 模拟一个耗时的日志写入操作 time.sleep(0.01) # 实际应写入数据库或日志文件 print(fLogged: {session_id}, Q: {question}, A: {answer})五、生产环境考量稳定与安全系统能跑起来只是第一步要上线还得过稳定和安全这两关。1. 负载测试方案我们用Locust来模拟大量用户并发提问确保系统扛得住压力。# locustfile.py from locust import HttpUser, task, between class RAGUser(HttpUser): wait_time between(1, 3) # 用户等待1-3秒后执行下一个任务 host http://your-api-server:8000 task def ask_question(self): sample_questions [ 怎么修改密码, 运费是多少, 支持哪些支付方式, 订单多久能发货 ] import random question random.choice(sample_questions) self.client.post(/ask, json{question: question})通过调整用户数和孵化速率我们可以找到系统的瓶颈是CPU、内存还是网络I/O并据此进行优化比如增加GPU资源、优化索引加载方式、对API进行限流等。2. 敏感信息过滤客服知识库中可能包含用户手机号、订单号等敏感信息不能直接通过模型泄露。预处理策略在文档进入向量库之前我们使用正则表达式或NER命名实体识别模型识别并脱敏敏感信息。例如将“请联系13800138000”替换为“请联系[电话]”。在生成答案后如果需要可以在一个安全的内部环境中将脱敏标记替换回真实信息如果需要的话或者直接告知用户通过安全渠道联系。六、避坑指南我们踩过的那些雷冷启动阶段的数据准备一开始知识库空空如也RAG根本无从检索。我们的做法是人工种子优先整理出最高频的100个QA对确保基础问题能答好。日志挖掘从历史客服聊天记录中提取出真实用户问法及其对应的优秀客服回答进行清洗后入库。合成数据对于长尾问题可以用LLM根据产品文档自动生成一些可能的用户问法和答案作为补充但需要人工审核。对话上下文窗口的最佳实践不是越长越好把全部历史对话都塞给模型会消耗大量token贵也可能引入无关信息干扰模型。我们只保留最近3轮对话作为上下文。关键信息摘要对于需要跨多轮对话记忆的信息如用户提到的订单号可以设计一个“信息槽”机制主动提取并存储这些关键实体在后续提问时显式地加入Prompt。成本控制方案缓存层对高频且答案固定的问题如“公司地址”将其问答对直接缓存如Redis命中缓存直接返回绕过检索和生成极大节省成本与时间。API调用优化使用GPT-3.5-Turbo而非 GPT-4 作为主力。精心设计Prompt力求简洁明确减少不必要的token。设置速率限制和预算告警防止意外流量或程序bug导致“破产”。定期评估开源模型的能力进展在效果可接受的前提下逐步将部分流量迁移到成本更低的私有模型上。写在最后通过这一套RAG方案的落地我们的智能客服在回答准确率上提升了约40%大部分问题的响应时间都压到了500毫秒以内。更重要的是知识更新变成了一个相对自动化的过程运维同事终于不用半夜起来改规则了。当然系统还有很大的优化空间。最后留三个问题也是我们团队正在思考的方向欢迎大家一起讨论检索质量当知识库文档非常长比如整本产品手册时简单的文本分块可能会把关键信息切断。如何设计更智能的文档切分Chunking策略或者引入层次化检索先检索章节再检索段落生成可控性尽管有检索到的资料约束模型偶尔还是会“自由发挥”。如何进一步通过强化学习或更精细的Prompt工程让模型的回答风格和边界更可控评估体系上线的系统如何自动化地评估其效果除了人工抽查能否设计一套自动化的评估指标如答案相关性、事实准确性、流畅度来持续监控和迭代模型希望这篇长文能为你构建自己的RAG应用提供一些切实可行的思路。这条路我们也是摸着石头过河共勉

相关文章:

基于RAG的智能客服系统实战:从架构设计到生产环境优化

最近在做一个智能客服系统的升级项目,之前用规则引擎维护起来太痛苦了,纯用大模型又贵又不准。经过一番折腾,最终用RAG(检索增强生成)技术搞定了,效果提升非常明显。今天就来分享一下从架构设计到上线优化的…...

ComfyUI实战:如何加载基于Flux.1微调的LoRA模型并优化推理流程

最近在项目里用 ComfyUI 部署基于 Flux.1 微调的 LoRA 模型,踩了不少坑。从模型加载失败到推理时显存爆炸,问题层出不穷。经过一番折腾,总算梳理出一套比较稳定的流程,这里把实战经验记录下来,希望能帮到有同样需求的同…...

Frida安装后别急着‘玩’!这5个必做的环境验证与排错步骤你做了吗?

Frida安装后必做的5个环境验证与排错步骤 当你兴冲冲地按照教程安装完Frida和Server,准备开始"玩耍"时,却发现frida-ps -U毫无反应,或者遇到各种连接失败的问题。这种"安装成功却用不了"的尴尬,往往源于环境…...

Llama-3.2V-11B-cot惊艳效果:多对象遮挡场景下的因果关系链推演

Llama-3.2V-11B-cot惊艳效果:多对象遮挡场景下的因果关系链推演 1. 视觉推理新标杆 在计算机视觉领域,多对象遮挡场景下的因果关系推演一直是个技术难题。传统方法往往只能识别可见部分,而无法理解遮挡背后的逻辑关系。Llama-3.2V-11B-cot的…...

一种路径优化和速度优化算法实现(仿照百度Apollo方案),只提供代码,有相关的readme文...

一种路径优化和速度优化算法实现(仿照百度Apollo方案),只提供代码,有相关的readme文件。 自动驾驶 ,路径优化,速度优化,pnc。 的代码最近在折腾自动驾驶的路径规划模块,发现实际落地…...

MAAAssistantArknights:智能自动化的明日方舟游戏助手解决方案

MAAAssistantArknights:智能自动化的明日方舟游戏助手解决方案 【免费下载链接】MaaAssistantArknights 一款明日方舟游戏小助手 项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights 价值解析:如何通过三大核心技术解决玩家…...

isac毕设选题效率提升实战:从任务调度到自动化部署的全流程优化

最近在忙 ISAC 相关的毕业设计选题,和不少同学交流后发现,大家的时间很大一部分都耗在了“重复劳动”上:环境配半天跑不起来,代码改一点就要手动重启服务测试,版本一多自己都忘了哪个是能用的。这哪是做毕设&#xff0…...

零基础入门:时空预测的系统化学习笔记

零基础入门:时空预测的系统化学习笔记 很多刚接触时序与时空预测领域的朋友,常常会陷入两个极端:要么一上来就硬啃复杂的 SOTA 模型,连基础算子都没搞懂就想复现顶会成果,最后处处碰壁;要么只停留在基础概…...

华为光猫配置解密工具全解析:从加密破解到网络运维实战指南

华为光猫配置解密工具全解析:从加密破解到网络运维实战指南 【免费下载链接】HuaWei-Optical-Network-Terminal-Decoder 项目地址: https://gitcode.com/gh_mirrors/hu/HuaWei-Optical-Network-Terminal-Decoder 在网络运维工作中,光猫设备的配置…...

5大突破:抖音音乐批量下载与智能管理解决方案

5大突破:抖音音乐批量下载与智能管理解决方案 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 在数字内容创作与音乐收藏领域,高效获取和管理抖音平台的音频资源一直是用户面临的核心挑…...

ChatGPT订阅接口开发实战:从零搭建到生产环境部署

ChatGPT订阅接口开发实战:从零搭建到生产环境部署 最近在做一个需要集成智能对话能力的项目,自然而然地想到了ChatGPT的订阅接口。本以为调用个API是分分钟的事,结果一脚踩进了坑里。403鉴权失败、消息顺序错乱、突如其来的配额限制……这些…...

SpringBoot+Vue 毕业设计效率提升实战:从脚手架到自动化部署的全链路优化

SpringBootVue 毕业设计效率提升实战:从脚手架到自动化部署的全链路优化 毕业设计是每个计算机相关专业学生必须跨越的一道坎。回想我自己的经历,以及身边同学的故事,一个普遍的现象是:大家往往在技术选型和环境搭建上就耗费了大量…...

FlexASIO:打破专业音频壁垒的通用驱动解决方案

FlexASIO:打破专业音频壁垒的通用驱动解决方案 【免费下载链接】FlexASIO A flexible universal ASIO driver that uses the PortAudio sound I/O library. Supports WASAPI (shared and exclusive), KS, DirectSound and MME. 项目地址: https://gitcode.com/gh_…...

Element React深度解析:企业级React组件库的架构设计与实战应用

Element React深度解析:企业级React组件库的架构设计与实战应用 【免费下载链接】element-react Element UI 项目地址: https://gitcode.com/gh_mirrors/el/element-react Element React是一款基于React框架构建的企业级UI组件库,它为开发者提供了…...

用格子玻尔兹曼方法 - 浸没边界法模拟圆柱绕流(LBM - IBM in C++)

格子玻尔兹曼方法-浸没边界法模拟圆柱绕流 LBM- IBM (C)在计算流体力学(CFD)的领域里,格子玻尔兹曼方法(Lattice Boltzmann Method, LBM)和浸没边界法(Immersed Boundary Method, IB…...

双模型混搭方案:OpenClaw同时接入百川2-13B与Qwen的实操演示

双模型混搭方案:OpenClaw同时接入百川2-13B与Qwen的实操演示 1. 为什么需要多模型混搭? 去年冬天,当我第一次尝试用OpenClaw自动化处理技术文档时,发现一个有趣的现象:同一个模型在不同任务上的表现差异巨大。Qwen在…...

ChatTTS在政务热线场景落地:拟真语音提升市民服务体验真实案例

ChatTTS在政务热线场景落地:拟真语音提升市民服务体验真实案例 1. 项目背景与价值 政务热线是政府与市民沟通的重要桥梁,但传统语音系统存在明显痛点:机械化的语音播报缺乏人情味,长时间等待的提示音让市民感到烦躁,…...

OpenMemories-Tweak完整指南:如何安全解锁索尼相机的隐藏功能

OpenMemories-Tweak完整指南:如何安全解锁索尼相机的隐藏功能 【免费下载链接】OpenMemories-Tweak Unlock your Sony cameras settings 项目地址: https://gitcode.com/gh_mirrors/op/OpenMemories-Tweak OpenMemories-Tweak是一款专为索尼相机设计的开源解…...

效率直接起飞!盘点2026年全网顶尖的AI论文工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂的AI论文工具,实测提速效果惊人,覆盖选题构思、文献整理、内容生成、格式排版全流程,让你高效搞定论文,告别熬夜赶工。 一、全流程王者:一站式搞定论文全链路&…...

如何高效优化多语言模型:专业部署的完整策略

如何高效优化多语言模型:专业部署的完整策略 【免费下载链接】paraphrase-multilingual-MiniLM-L12-v2 项目地址: https://ai.gitcode.com/hf_mirrors/ai-gitcode/paraphrase-multilingual-MiniLM-L12-v2 你是否在部署多语言文本嵌入模型时遭遇过"显存…...

Chatbot Arena排行榜单实战指南:从数据采集到模型优化

Chatbot Arena排行榜单实战指南:从数据采集到模型优化 在构建和优化自己的对话AI时,我们常常面临一个核心问题:如何客观、全面地评估它的性能?闭门造车式的测试往往带有主观偏见,而Chatbot Arena这类公开的排行榜单&a…...

SEO_移动端SEO优化的关键步骤与注意事项介绍

<h1 id"seo">移动端SEO优化的关键步骤与注意事项介绍</h1> <p>在互联网时代&#xff0c;移动端已经成为用户访问网站的主要途径。因此&#xff0c;移动端SEO优化变得尤为重要。本文将详细介绍移动端SEO优化的关键步骤与注意事项&#xff0c;帮助你…...

基于AI多因子与流动性模型的黄金再定价分析:4500关口修复后的“黄金坑”是否成立?

摘要&#xff1a;本文通过引入AI多因子定价模型&#xff0c;结合流动性压力识别算法、资金流向追踪系统与宏观变量建模&#xff0c;对黄金从5602美元回落至4099美元后的市场行为进行分析&#xff0c;重点解析抛售驱动逻辑、相关性漂移及4500美元关口的再定价机制。一、AI趋势重…...

红外遥控技术原理与实现方案详解

红外遥控技术原理与实现方案1. 红外遥控技术概述红外遥控技术是一种利用红外光波进行短距离无线通信的技术方案&#xff0c;主要应用于家电控制领域。该技术通过调制红外光波来传输控制信号&#xff0c;具有成本低、实现简单、抗干扰能力强等特点。1.1 技术特点与应用场景红外遥…...

智能客服方案库物流JSON格式优化:从数据冗余到高效解析

在智能客服系统中&#xff0c;物流信息的查询与展示是高频核心功能。随着业务增长&#xff0c;我们方案库中存储和传输的物流JSON数据日益庞大。最初为了图省事&#xff0c;我们采用了“全量字段”的设计&#xff0c;即每次接口返回都包含物流单号、状态、时间、承运商、路由节…...

ICRS-101机器人手动控制API协议设计与嵌入式实现

1. ICRS_101_API 项目概述ICRS_101_API 是一套面向教育与科研场景的机器人手动控制接口规范&#xff0c;专为 ICRS-101 型教学机器人平台设计。该 API 并非独立运行的固件或中间件&#xff0c;而是一组定义清晰、硬件无关的通信协议与软件抽象层&#xff0c;其核心目标是为上位…...

从座舱芯片到指尖触控:聊聊高通8155/8295上那个你可能没注意到的Virtio Touch框架

从座舱芯片到指尖触控&#xff1a;高通8155/8295中的Virtio Touch框架解析 当你的手指在车载中控屏上滑动时&#xff0c;一组坐标数据正以微秒级速度穿越两个操作系统——这背后是高通座舱芯片中鲜为人知的Virtio Touch框架在发挥作用。作为连接QNX Hypervisor与Android系统的神…...

Selenium爬虫被检测?3种隐藏WebDriver属性的实战技巧(附最新ChromeDriver配置)

Selenium爬虫被检测&#xff1f;3种隐藏WebDriver属性的实战技巧&#xff08;附最新ChromeDriver配置&#xff09; 在数据采集领域&#xff0c;Selenium一直是处理动态渲染页面的利器。但近年来&#xff0c;越来越多的网站开始部署针对自动化工具的检测机制&#xff0c;使得传统…...

java的for循环

public class Demo6 {public static void main(String[] args) {for (int money1;money<10;money){System.out.println("换一元纸币"money"张。换5角硬币"(10-money)*2"个");}} }public class Demo8 {public static void main(String[] args)…...

League-Toolkit完全指南:高效BP策略与全方位战绩分析实战应用

League-Toolkit完全指南&#xff1a;高效BP策略与全方位战绩分析实战应用 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 功能解析…...