news 2026/5/12 5:33:33

SAP CAP框架集成RAG架构:企业级生成式AI应用实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SAP CAP框架集成RAG架构:企业级生成式AI应用实战指南

1. 项目概述:当企业级SAP CAP框架遇上生成式AI

如果你是一位SAP开发者,或者正在用SAP Cloud Application Programming (CAP) 模型构建企业级应用,那么最近一年来,你肯定被一个词反复“轰炸”——生成式AI。从智能客服到自动报告生成,从代码辅助到知识问答,GenAI的潜力毋庸置疑。但问题来了:如何将这股强大的、有时甚至显得有些“天马行空”的新兴力量,安全、可靠、且符合企业数据治理规范地,集成到我们严谨的SAP CAP应用架构中?特别是,如何让AI模型理解并利用企业内部的私有知识库(比如产品手册、服务协议、内部流程文档),而不是仅仅基于公开的通用信息给出答案?

这正是SAP官方示例仓库SAP-samples/btp-cap-genai-rag要解决的核心命题。这个项目不是一个简单的“Hello World”演示,而是一个面向生产级思考的、完整的参考实现(Reference Implementation)。它展示的是一种被称为“检索增强生成”(Retrieval-Augmented Generation, RAG)的架构模式,如何与SAP BTP(业务技术平台)的CAP模型深度结合。简单来说,RAG就像给大语言模型(LLM)配了一个“超级外脑”和“严格质检员”。当用户提问时,系统不是让LLM凭空想象,而是先从你指定的企业知识库(如SAP HANA Cloud数据库)中精准检索出最相关的文档片段,然后将这些“证据”和问题一起交给LLM,让它基于这些确凿的材料生成答案。这极大地提升了答案的准确性、时效性,并确保了信息源的可追溯性,完美契合了企业对数据安全与合规性的严苛要求。

这个示例项目为你铺平了一条从零到一的实践路径。它涵盖了从后端CAP服务的数据建模、文档嵌入(Embedding)与向量存储,到前端的Fiori Elements UI交互,再到利用SAP BTP AI Core和AI Launchpad服务进行AI推理集成的全链路。无论你是想构建一个智能的产品问答助手、一个高效的内部政策查询系统,还是一个能解析复杂合同条款的智能工具,这个项目都提供了可复用的代码范式和架构设计。接下来,我将带你深入拆解这个项目的每一层设计,分享在复现和拓展过程中可能遇到的“坑”以及我的实战心得。

2. 架构核心:理解CAP与RAG的融合设计

2.1 为什么是CAP + RAG?

在SAP的生态体系中,CAP框架已经成为构建云原生、领域驱动型应用的事实标准。它通过CDS(Core Data Services)语言统一了数据模型、服务定义和业务逻辑,极大地提升了开发效率和应用的内聚性。而RAG架构,则是当前将大语言模型与企业私有数据结合的最实用、最受推崇的模式。两者的结合,可以看作是“企业级结构化工程能力”与“前沿AI非结构化理解能力”的一次强强联合。

这个示例项目的架构清晰体现了分层思想。最底层是数据持久层,这里通常使用SAP HANA Cloud,因为它不仅支持传统的关系型数据存储,其原生的向量引擎(Vector Engine)更能高效处理文档嵌入(Embeddings)后的高维向量数据,执行快速的相似性搜索。中间层是CAP业务服务层,它通过CDS模型定义知识库(如Documents实体)、问答记录等,并暴露OData服务。这一层也包含了核心的RAG逻辑服务:负责将上传的文档进行分块、调用嵌入模型转换为向量,并触发向量存储。最上层是AI集成层与表示层。AI集成通过SAP AI Core服务来托管和调用开源的嵌入模型(如all-MiniLM-L6-v2)和生成模型(如gpt-3.5-turbo),确保企业级的部署、监控与生命周期管理。表示层则通常是一个Fiori Elements应用,提供友好的文档管理和问答界面。

这种设计的优势在于,它将AI能力作为一种“服务”来消费,而非硬编码在应用里。CAP应用通过REST API调用AI Core中部署的模型,实现了业务逻辑与AI模型的解耦。未来若要更换为更强大的模型(如GPT-4或Claude),只需在AI Core中重新部署并更新服务端点,CAP应用层的代码几乎无需改动。

2.2 关键组件交互流程解析

让我们通过一个用户提问的完整流程,来理解各组件如何协同工作:

  1. 知识库准备阶段:管理员通过前端应用上传一份PDF格式的产品手册。CAP后端服务接收到文件后,首先将其文本内容提取出来。
  2. 文档处理与向量化:CAP服务中的RAG逻辑将长文本按语义切割成大小适中的“块”(Chunking,例如每块500字符)。然后,它调用部署在AI Core上的嵌入模型API,将每一个文本块转换为一个高维向量(例如768维)。这个向量就像是文本的“数学指纹”,语义相近的文本,其向量在空间中的距离也更近。
  3. 向量存储:生成的文本块及其对应的向量,被一同存储到HANA Cloud的表中。文本块存于NVARCHAR列,向量存于REAL_VECTOR列。HANA的向量引擎会为这个向量列创建特定的索引,以加速后续的相似度搜索。
  4. 用户问答阶段:用户在前端界面提问:“产品X的保修期是多久?”
  5. 问题向量化与检索:CAP服务将用户的问题同样通过嵌入模型转换为向量。随后,它向HANA Cloud数据库发起一个向量相似度查询(例如使用COSINE_SIMILARITY函数),寻找与问题向量最接近的Top K个(比如3个)文本块向量。这步操作,就是从海量知识库中“检索”出与问题最相关的证据片段。
  6. 提示工程与生成:CAP服务将检索到的文本块作为上下文,与用户原始问题一起,精心构造成一个提示(Prompt),例如:“请基于以下上下文回答问题。上下文:{检索到的文本块1}...{文本块2}...{文本块3}。问题:{用户问题}。答案:”。然后,它将这个提示发送给AI Core上部署的生成模型(如GPT-3.5)。
  7. 答案生成与返回:生成模型基于提供的上下文生成答案,例如:“根据手册第5.2节,产品X的标准保修期为自购买之日起24个月。” CAP服务收到答案后,可能将其与问题、引用来源一同记录到数据库,最后返回给前端界面呈现给用户。

注意:整个流程中,用户的私有数据(文档内容)和问题始终在SAP BTP的信任边界内流转,不会发送给如OpenAI这样的公有云API(除非你主动配置)。这是企业级应用必须考虑的数据主权和安全合规生命线。

3. 实操部署与核心配置详解

3.1 环境准备与项目初始化

首先,你需要一个可用的SAP BTP账号(试用版或付费版),并创建好一个子账户(Subaccount)和空间(Space)。核心服务需要提前启用并配置:

  • SAP HANA Cloud:作为主数据库和向量存储。
  • SAP AI Core&AI Launchpad:用于托管和运行AI模型。
  • SAP Business Application Studio或本地VS Code:作为开发环境。

从GitHub克隆示例仓库后,第一步是安装项目依赖。使用npm install安装CAP层所需的Node.js包。这里的关键依赖包括@sap/cds(CAP核心)、@sap/cds-dk(开发工具包),以及用于文档处理的pdf-parsemammoth(处理docx)等库。

接下来是配置.env文件,这是连接所有BTP服务的枢纽。你需要仔细配置以下关键连接信息:

# HANA Cloud 连接 HC_HOST=your-hana-host.hanacloud.ondemand.com HC_PORT=443 HC_USER=YOUR_DB_USER HC_PASSWORD=your_secure_password # AI Core 连接 AICORE_AUTH_URL=https://your-region.authentication.sap.hana.ondemand.com/oauth/token AICORE_CLIENT_ID=sb-your-client-id!t12345 AICORE_CLIENT_SECRET=your-client-secret AICORE_RESOURCE_GROUP=your-resource-group AICORE_BASE_URL=https://api.ai.core.sap.com/v2 # 嵌入模型和生成模型的部署ID,需要在AI Core中创建部署后获取 EMBEDDING_DEPLOYMENT_ID=all-minilm-deployment COMPLETION_DEPLOYMENT_ID=gpt35-deployment

实操心得:在试用账户中,配额限制是需要时刻关注的。特别是AI Core的推理资源(GPU/CPU)和HANA Cloud的内存。建议在开发初期,为HANA Cloud启用“向量引擎”时,选择最小的配置起步。AI Core的模型部署会消耗大量资源,在非活跃期记得通过AI Launchpad停止部署以节省配额。

3.2 数据模型与CDS定义剖析

项目的核心数据模型定义在db/schema.cds文件中。理解这个模型是理解整个应用的基础。

namespace sap.cap.rag; // 知识文档实体 entity Documents : managed, cuid { key ID : UUID; title : String(255); fileName : String(500); fileType : String(50); // e.g., 'pdf', 'docx' content : LargeString; // 提取的原始文本 status : String(20) enum { processing; ready; error; }; // 关联的文本块 chunks : Composition of many DocumentChunks on chunks.document = $self; } // 文档分块实体,用于存储向量 entity DocumentChunks : cuid { key ID : UUID; document : Association to Documents; chunkIndex : Integer; // 块序号 chunkText : LargeString; // 文本块内容 embedding : Vector(768); // 关键!HANA Cloud的向量类型字段 // 元数据,便于过滤 docTitle : String(255); } // 问答历史记录 entity QnAHistory : managed, cuid { key ID : UUID; question : LargeString; answer : LargeString; sessionId : String(100); // 可以关联到检索到的具体块,实现答案溯源 sourceChunks: Association to many DocumentChunks; }

关键点解析

  1. Vector(768)类型:这是HANA Cloud支持的特殊列类型,用于存储浮点数向量。768是所选嵌入模型all-MiniLM-L6-v2的输出维度。如果你换用其他模型(如text-embedding-ada-002是1536维),此处必须同步修改。
  2. 组合关系(Composition)DocumentsDocumentChunks之间是组合关系,这意味着文档的生命周期管理着其下所有文本块。删除一个文档,其对应的所有块也会被级联删除,这保证了数据的一致性。
  3. 状态管理Documents实体的status字段非常重要。它标识了文档的处理状态(处理中、就绪、错误),前端可以根据这个状态显示不同的UI(如进度条、错误提示),这是一个非常实用的生产级设计模式。

3.3 AI Core模型部署与场景配置

这是集成中最具SAP BTP特色的一环。你不需要自己搭建GPU服务器来运行模型,而是通过AI Core以服务化的方式消费。

  1. 准备模型:你需要将开源模型(如从Hugging Face下载的sentence-transformers/all-MiniLM-L6-v2)打包成一个符合AI Core规范的Docker镜像,并推送到你的Docker注册表(如SAP提供的或私有的)。示例项目通常会提供Dockerfile和模型下载脚本。
  2. 创建AI Core资源:在AI Launchpad中,你需要创建:
    • 对象存储(Object Store):用于存储你的模型包(即Docker镜像tar文件)。
    • 场景(Scenario):定义一个AI任务类型,例如“文本嵌入”和“文本生成”。
    • 执行器(Executor):关联你的Docker镜像,并定义其启动命令、输入/输出参数。对于嵌入模型,输入是文本,输出是向量;对于生成模型,输入是提示词(Prompt),输出是生成的文本。
    • 配置(Configuration):为执行器指定运行时参数,如GPU资源类型、实例数量等。
    • 部署(Deployment):基于配置创建一个正在运行的模型服务端点(Endpoint)。部署成功后,你会获得一个唯一的deployment_id,这就是CAP服务在.env文件中需要配置的EMBEDDING_DEPLOYMENT_IDCOMPLETION_DEPLOYMENT_ID

注意事项:AI Core的配置流程步骤较多,且涉及YAML语法。一个常见的错误是Dockerfile中暴露的端口号(默认是5000或8080)与执行器配置中ports字段不匹配,导致部署后健康检查失败。务必仔细对照示例项目的配置模板。另外,生成模型的部署(如使用GPT类模型)可能需要你自行解决模型许可和分发问题,或者选择AI Core已集成的商业模型选项。

3.4 CAP服务层:RAG逻辑的实现

服务层的逻辑主要写在srv/rag-service.js(或.ts)中。我们聚焦两个最核心的方法:processDocumentaskQuestion

processDocument方法: 这个方法处理上传的文档。伪代码逻辑如下:

async function processDocument(documentId) { // 1. 从数据库获取文档实体和原始内容 const doc = await SELECT.one.from(Documents).where({ID: documentId}); if (doc.status !== 'processing') return; // 2. 文本提取与分块 const rawText = await extractTextFromFile(doc.fileName, doc.fileType); // 使用pdf-parse等库 const textChunks = splitTextIntoChunks(rawText, chunkSize=500, overlap=50); // 重叠避免语义割裂 // 3. 批量向量化(为提升效率) const chunkTexts = textChunks.map(c => c.text); const embeddingVectors = await callAICoreEmbedding(chunkTexts, EMBEDDING_DEPLOYMENT_ID); // 4. 存储到DocumentChunks for (let i = 0; i < textChunks.length; i++) { await INSERT.into(DocumentChunks).entries({ document: documentId, chunkIndex: i, chunkText: textChunks[i].text, embedding: embeddingVectors[i], // 这里是向量数组 docTitle: doc.title }); } // 5. 更新文档状态为‘ready’ await UPDATE(Documents).set({status: 'ready'}).where({ID: documentId}); }

关键技巧:分块时设置重叠(overlap)非常重要。比如前一个块的最后50个字符与下一个块的开头50个字符相同,这能确保一个完整的句子或概念不会被生硬地切断,从而在检索时保持上下文的完整性。

askQuestion方法: 这是RAG查询的核心。伪代码逻辑如下:

async function askQuestion(question, topK=3) { // 1. 将问题转换为向量 const questionVector = await callAICoreEmbedding([question], EMBEDDING_DEPLOYMENT_ID); const qVec = questionVector[0]; // 2. 在HANA中执行向量相似度搜索 const relevantChunks = await SELECT.from(DocumentChunks) .columns('chunkText', 'docTitle', 'chunkIndex') .where(`COSINE_SIMILARITY(embedding, :qv) > 0.7`) // 相似度阈值过滤 .orderBy(`COSINE_SIMILARITY(embedding, :qv) DESC`) .limit(topK) .bind({qv: qVec}); // 3. 构建Prompt const context = relevantChunks.map(c => `[来源: ${c.docTitle}, 块: ${c.chunkIndex}]\n${c.chunkText}`).join('\n\n'); const prompt = `你是一个专业的客服助手。请严格根据以下提供的上下文信息来回答问题。如果上下文信息中没有明确答案,请直接回答“根据现有资料,我无法回答这个问题。”,不要编造信息。 上下文: ${context} 问题:${question} 答案:`; // 4. 调用生成模型 const answer = await callAICoreCompletion(prompt, COMPLETION_DEPLOYMENT_ID); // 5. 保存历史并返回 const historyEntry = await INSERT.into(QnAHistory).entries({question, answer, sessionId}); await UPDATE(historyEntry).with({sourceChunks: relevantChunks.map(c => c.ID)}); // 关联溯源 return { answer, sources: relevantChunks }; }

关键技巧:Prompt工程是影响答案质量的决定性因素之一。示例中的Prompt明确限定了AI的角色和回答边界(“严格根据上下文”),并给出了无法回答时的处理指令。在实际应用中,你可能需要根据不同的业务场景(如法律咨询、技术支持)定制更精细的Prompt模板。

4. 前端Fiori Elements应用的快速搭建

得益于CAP框架的全栈一致性,前端UI可以极快地通过Fiori Elements构建。项目中通常包含一个app/目录,其中定义了annotations.cdspages

  1. 服务注解:在srv/的服务定义文件中,使用@odata.draft.enabled等注解为DocumentsQnAHistory实体启用OData V4的草稿(Draft)支持,这是Fiori Elements对象页(Object Page)的标准模式。
  2. UI注解:在app/目录下的annotations.cds中,使用@UI注解定义列表页和对象页的字段排列、表单控件和操作按钮。例如,为Documents实体定义一个“上传”按钮,为QnAHistory实体定义一个“提问”对话框。
  3. 自动生成UI:运行cds watchcds build后,CAP会自动生成Fiori Elements所需的元数据。通过cds add frontendcds add fiori等命令,可以快速搭建一个基于Fiori Elements的React应用。前端应用通过@ui5/webcomponentsODataModel与后端CAP服务通信。

前端开发心得:对于RAG应用,一个重要的UI优化点是“答案溯源”的展示。在返回答案的同时,将检索到的sourceChunks(包含文档标题和具体文本块)一并返回,并在前端以折叠面板、脚注或侧边栏的形式清晰展示出来。这不仅能增加用户信任,也方便用户快速核查答案的准确性。你可以通过扩展QnAHistory实体的OData响应,或者创建一个自定义的CAP动作(Action)来返回包含溯源信息的复合数据。

5. 进阶优化与生产级考量

当基本流程跑通后,为了提升系统的可用性和性能,需要考虑以下优化点:

  1. 分块策略优化

    • 递归分块:尝试不同的分块方法,如按段落、按句子分割,或者使用更智能的递归字符分割,确保语义单元的完整性。
    • 元数据增强:在分块时,除了文本内容,还可以附加元数据,如所属章节、页码、文档类型等。在向量检索时,可以结合元数据进行过滤(例如,只搜索“保修章节”的块),提升检索精度。
  2. 检索策略优化

    • 混合搜索(Hybrid Search):结合向量相似度搜索和传统的关键词全文搜索(BM25)。HANA Cloud同时支持这两种搜索。可以先通过关键词快速筛选出候选文档集,再在候选集内做精确的向量相似度排序,兼顾召回率和准确率。
    • 重排序(Re-ranking):在初步检索出Top K(例如10个)块后,使用一个更小、更精确的交叉编码器(Cross-Encoder)模型对这10个块与问题的相关性进行重新打分和排序,选取Top 3作为最终上下文。这能显著提升上下文质量,但会增加一次模型调用开销。
  3. 性能与成本

    • 批处理与缓存:对于文档处理,采用批量调用嵌入模型API,而非逐条调用,能大幅减少网络开销。对于常见问题,可以引入缓存机制(如Redis),将“问题-答案”对缓存一段时间。
    • 异步处理:文档上传和向量化是一个耗时操作,务必设计为异步任务。CAP框架可以结合@sap/cds/tx和消息队列(如SAP Event Mesh)或简单的后台作业来处理,避免阻塞HTTP请求。
  4. 可观测性与评估

    • 日志与监控:在CAP服务和AI Core的模型部署中,加入详细的日志记录,特别是输入/输出、耗时和错误信息。利用SAP BTP的监控服务(如Application Logging)进行集中查看。
    • 答案质量评估:建立一个简单的评估机制。可以记录每次问答的用户反馈(“有帮助”/“无帮助”),或者定期用一组标准问题测试系统,跟踪答案准确率的变化,作为迭代优化模型和Prompt的依据。

6. 常见问题与故障排查实录

在复现和扩展这个项目的过程中,我遇到并总结了一些典型问题:

问题1:文档向量化过程非常慢,甚至超时。

  • 排查:首先检查AI Core中嵌入模型部署的资源配置。试用账户的默认配置(如CPU: 0.2)可能过低。其次,检查是否在单次请求中发送了过多的文本块(例如超过100个)。嵌入模型对输入令牌数有限制。
  • 解决:1) 在AI Core配置中增加CPU/内存配额。2) 在CAP服务中实现分批处理,例如每20个文本块调用一次API。3) 优化文本分块大小,避免单个块过长。

问题2:检索到的上下文与问题不相关,导致生成答案胡言乱语。

  • 排查:检查HANA Cloud中COSINE_SIMILARITY函数的相似度阈值。示例中> 0.7可能不适合你的数据。检查嵌入模型是否适用于你的领域(例如,通用模型对专业金融/法律术语的编码效果可能不佳)。
  • 解决:1) 调整相似度阈值,可以通过人工评估一批查询结果来确定最佳值。2) 考虑使用在特定领域(如医学、法律)微调过的嵌入模型。3) 实施上文提到的“混合搜索”或“重排序”策略。

问题3:前端上传大文件失败。

  • 排查:默认的CAP/Express服务器对请求体大小有限制。
  • 解决:在CAP服务器的自定义引导文件(server.js)中,增加bodyParserlimit配置。
    const cds = require('@sap/cds'); cds.on('bootstrap', (app) => { const bodyParser = require('body-parser'); app.use(bodyParser.json({ limit: '50mb' })); app.use(bodyParser.urlencoded({ limit: '50mb', extended: true })); }); module.exports = cds.server;

问题4:AI Core模型部署状态一直为“未知”或“失败”。

  • 排查:这是部署阶段最常见的问题。首先在AI Launchpad中查看部署的日志(Logs),错误信息通常很明确。
  • 常见原因与解决
    • Docker镜像拉取失败:检查镜像地址是否正确,网络是否通畅,以及你的BTP子账户是否有对应容器注册表的读取权限。
    • 健康检查失败:检查你的模型服务在Docker容器内是否在正确的端口(如5000)启动,并且/v1/health/v2/health端点返回了正确的HTTP 200状态码。AI Core会定期调用此端点。
    • 资源不足:错误信息可能提示“Insufficient CPU/Memory”。需要在配置中申请更大的资源。

问题5:生成的答案总是以“根据上下文…”开头,显得生硬。

  • 排查:这是Prompt设计导致的。系统指令过于刻板。
  • 解决:优化你的Prompt模板。可以尝试更自然的指令,例如:“你是一个乐于助人的专家。请参考以下资料来回答用户的问题。如果资料中有答案,请用友好、专业的口吻总结出来;如果资料中没有明确信息,请礼貌地告知用户你无法从现有资料中找到答案,并建议他咨询其他渠道。” 多进行几次A/B测试,找到最适合你业务语气的Prompt。

这个SAP-samples/btp-cap-genai-rag项目就像一张精心绘制的地图,为你指明了在企业级SAP环境中落地生成式AI应用的方向。它提供的不是一堆碎片化的代码,而是一个完整的、可演进的架构范式。从我个人的实践来看,最大的收获不在于照搬代码,而在于理解其背后的设计哲学:以企业级的数据安全和工程规范为前提,将前沿的AI能力作为可插拔的组件进行集成。当你吃透了这套架构,你就可以举一反三,将其应用到更复杂的业务场景中,比如连接S/4HANA的实时业务数据,或者构建跨多个知识库的联合检索系统。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 5:25:49

从臃肿到轻快:zim+powerlevel10k打造高效美观的现代终端环境

1. 为什么你应该放弃Oh My Zsh转向Zim 如果你是个终端重度用户&#xff0c;大概率已经用过Oh My Zsh。这个流行的框架确实提供了丰富的插件和主题&#xff0c;但用久了就会发现它越来越慢——特别是当你装了十几个插件却只用其中两三个的时候。我自己就经历过这种痛苦&#xff…

作者头像 李华
网站建设 2026/5/12 5:20:52

AI模型训练的环境影响与优化策略

1. AI模型训练的环境影响全景分析 在深度学习模型训练过程中&#xff0c;GPU集群的能源消耗构成了环境影响的主要来源。以Moshi语音模型为例&#xff0c;其研发过程消耗了300万GPU小时&#xff08;相当于372个GPU全年无间断运行&#xff09;&#xff0c;产生了以下环境指标&…

作者头像 李华
网站建设 2026/5/12 5:16:48

MCP协议实践:构建AI助手与IDE间的通信中继

1. 项目概述&#xff1a;IDE与AI助手间的“通信中继”最近在折腾AI编程助手时&#xff0c;发现一个挺有意思的痛点&#xff1a;像Cursor、Claude Desktop这类IDE插件或独立应用&#xff0c;它们内置的AI助手能力很强&#xff0c;但很多时候我们希望能让它们访问到IDE之外的一些…

作者头像 李华
网站建设 2026/5/12 5:15:15

Parsimonious高级应用:构建领域特定语言的完整流程

Parsimonious高级应用&#xff1a;构建领域特定语言的完整流程 【免费下载链接】parsimonious The fastest pure-Python PEG parser I can muster 项目地址: https://gitcode.com/gh_mirrors/pa/parsimonious Parsimonious是一个纯Python实现的高效PEG解析器&#xff0c…

作者头像 李华
网站建设 2026/5/12 5:15:02

GrandNode入门指南:如何快速搭建开源无头电商平台

GrandNode入门指南&#xff1a;如何快速搭建开源无头电商平台 【免费下载链接】grandnode Open source, headless, multi-tenant eCommerce platform built with .NET Core, MongoDB, AWS DocumentDB, Azure CosmosDB, Vue.js. 项目地址: https://gitcode.com/gh_mirrors/gr…

作者头像 李华
网站建设 2026/5/12 5:12:34

Azure Quickstart Templates监视器模板:终极监控解决方案完整指南

Azure Quickstart Templates监视器模板&#xff1a;终极监控解决方案完整指南 【免费下载链接】azure-quickstart-templates Azure Quickstart Templates 项目地址: https://gitcode.com/gh_mirrors/az/azure-quickstart-templates Azure Quickstart Templates提供了丰富…

作者头像 李华