首页 文章 精选 留言 我的

精选列表

搜索[genai],共191篇文章
优秀的个人博客,低调大师

Elastic 和 AWS 合作将 GenAI 引入 DevOps、安全和搜索领域

作者:来自 ElasticEddie Xu,Brian Bergholm 我们很高兴庆祝 Elastic 和AWS签署五年战略合作协议(strategic collaboration agreement - SCA)。我们的合作强调了 Elastic 和 AWS 在你采用生成式 AI 技术过程中,为你带来更高速度和更大灵活性的努力。 合作概览 在过去十年里,Elasticsearch 成为最受欢迎的开源项目之一,让你能够进行全文搜索、语义搜索、自然语言处理和多模态搜索。随着越来越多的应用构建在云端,我们与 AWS 合作以满足你在扩展性、性能和创新方面的需求。 这项新协议建立在双方长期合作的基础上,帮助你更快构建基于生成式 AI 的应用,同时减少复杂性。Elastic 和 AWS 将持续投入技术集成,帮助你推动 AI 创新。我们的合作已经在实际商业价值中体现,例如支持 Adobe Commerce 在其平台上交付由 AI 驱动的体验。 我们也认识到某些行业需要应对各种政府法规、合规标准、数据处理协议等。因此,Elastic 和 AWS 将在特定行业(包括公共部门)投资行业化的市场推广方法,构建可在你组织各层级保护数据的解决方案。 这对你意味着什么? 让一切变得更简单 你已经在使用 Elasticsearch 作为你的向量数据库。我们的推理 API 允许你快速创建连接 Amazon Bedrock 的推理端点,让你无需额外管道即可访问最先进的基础模型,例如 Anthropic Claude、Llama、Cohere Commend 和 DeepSeek R1。根据你的使用场景,你可以轻松比较模型的性能和大小。例如,你可以将 Amazon 的 AI 模型系列Amazon Nova 与 Elasticsearch 搭配使用,实现高性能和成本效益。 现在你已经构建了应用,那么该如何监控和管理模型的使用和性能?谁在监控你的 AI?我们投资于与 Amazon Bedrock 的集成,不只是为了更轻松地构建你的 RAG 应用,还为了管理和运行它。Elastic 原生收集 Amazon Bedrock 的指标和日志,使你更容易理解模型行为、优化和排查大语言模型(LLM)应用的问题。了解更多内容:Elastic AI Assistant for Observability 和 Amazon Bedrock。 随着你的 AI 工作流变得更加复杂,你会发现你的 LLM 应用需要与其他应用通信。Elastic 已发布我们的 MCP 服务器,因此你可以将代理连接到 Elasticsearch 数据,并通过自然语言进行交互。请记住,目前我们仍处于早期阶段。但我们已经发布了一个教程供你试用:Model Context Protocol 服务器,用于在 Elasticsearch 中与数据对话。 降低成本 如果你已经使用 Elastic 一段时间,可能注意到我们经常发布新功能、能力和安全更新。这正是我们作为开源公司的魅力 —— 创新速度快。为了帮助你加速组织的创新,我们在 AWS re:Invent 2024 上推出了 Elastic Cloud Serverless。 Elastic Cloud Serverless 不仅免去了你管理基础设施、容量规划、升级和扩展的管理任务,而且运行成本非常低。使用 Serverless,你只为使用的部分付费。Elastic Cloud Serverless 会在闲置时自动缩减规模,其无状态架构还依赖于价格实惠的对象存储,将节省的成本回馈给你。 此外,通过新的 SCA,Elastic 和 AWS 在你探索和采用的每个阶段提供支持。我们投入资源为开发者提供更多动手体验,尤其是关于我们在生成式 AI 方面的联合创新。AWS 还为像你这样的客户提供资金支持,帮助他们在 AWS 环境中试点 Elastic。对于无法体验 AWS 上最新 Elastic 功能的客户,我们也提供资金支持,帮助你迁移到 Elastic Cloud。 最后,我们知道许多用户喜欢通过 AWS Marketplace 购买 Elastic 的体验和好处。除了通过 Elastic 和 AWS 承诺计划获得的成本节省和可预测性外,我们还合作为 AWS Marketplace 上的新客户和月度客户提供激励。更多信息请联系buy-on-marketplace@elastic.co。 增强安全性 如果你每天需要处理数百条警报,你需要帮助。Elastic 是业内首批推出安全用例 AI 助手的公司之一。利用 Amazon Bedrock 和 LLM,Elastic AI Assistant 快速帮助你查明攻击来源。 作为 AWS 安全能力合作伙伴,Elastic 致力于为我们的联合客户提供先进的安全能力。我们重点投入的一个重要集成是AWS PrivateLink,直接将 Elastic Cloud 连接到你的 AWS VPC,仅允许你信任的来源的入站流量。你可以放心数据在传输过程中不会被泄露。对于在高度监管行业运营的用户,Elastic Cloud获得了 Moderate Impact 级别的 FedRAMP 授权,并可在 AWS GovCloud 上使用。Elastic 也提供自管理解决方案。我们相信应在任何你所在的位置为你服务。 今天就开始免费试用 想知道如何加速实现重要成果吗?对于尚未成为客户的你,可以通过AWS Marketplace注册,开始为期7 天的免费试用,并在全球任何AWS 上的 Elastic Cloud 区域内快速启动部署。你在 AWS Marketplace 购买的 Elastic 会包含在你的月度合并账单中,并从你与 AWS 的承诺支出中扣除。在 AWS Marketplace 自信购买,并通过 Search AI 发现实时洞察。 本博客中描述的任何功能或特性的发布时间和内容均由 Elastic 全权决定。当前不可用的功能或特性可能无法按时或根本无法交付。 本博客可能使用或提及第三方生成式 AI 工具,这些工具由其各自所有者拥有和运营。Elastic 无法控制这些第三方工具,对其内容、操作或使用不承担任何责任,也不对因你使用这些工具可能产生的任何损失或损害负责。请在使用 AI 工具处理个人、敏感或机密信息时谨慎。你提交的任何数据可能被用于 AI 训练或其他用途。无法保证你提供的信息会被安全或保密。你应在使用前了解任何生成式 AI 工具的隐私政策和使用条款。 Elastic、Elasticsearch 及相关标志是 Elasticsearch N.V. 在美国及其他国家的商标、标识或注册商标。所有其他公司和产品名称均为其各自所有者的商标、标识或注册商标。

优秀的个人博客,低调大师

深入浅出 GenAI 关键概念—— 从 RAG、Function Calling、MCP 到 AI Agent

简介 随着大语言模型飞速演进,其在知识时效、生成准确性以及与外部系统交互方面的局限也愈发显现。 为此,检索增强生成(RAG)、函数调用(Function Calling)、模型上下文协议(MCP)与 AI 智能体(AI Agent)等一系列技术相继涌现,为模型补足"知识新鲜度"与"操作执行力"。 近期 CloudCanal 也推出了 RagApi 功能,并引入了 MCP 协议。本文将聚焦 RAG、Function Calling、MCP、AI Agent 等核心概念,并介绍 CloudCanal 在 RAG 架构上的具体实现。 RAG:检索增强生成 RAG(Retrieval-Augmented Generation) 是一种将"检索"与"生成"结合的 AI 架构。与传统大模型直接回答问题不同,RAG 会先从外部知识库(如文档库、数据库、向量数据库)中找到与用户问题相关的上下文信息,再将这些内容作为提示输入给大语言模型,从而生成更加准确的回答。 RAG 的优势 模型不再完全依赖预训练知识,可结合实时或特定领域的信息; 对私有数据支持更强,安全性与定制性更高; 减少模型"胡编乱造"的情况,提高回答可靠性。 RAG 的工作流程 构建知识库:准备大量文本资料,并将其向量化,存储到向量数据库中(如 PGVector)。 相似度检索:用户提问时,问题也会被向量化,然后通过相似度计算检索出最相关的文本段落。 生成回答 :将这些相关内容作为上下文,提供给生成模型,用于回答用户问题。 什么是向量? 在 RAG 的工作流程中,数据向量化是第一步。那么,什么是向量呢? 为了方便理解,让我们来举个例子。对于"苹果"这个概念,人类靠经验理解,但计算机不懂"苹果",它需要一种可以量化的方式来表示这个词。 于是,AI 会用一种叫做嵌入 的方式,把"苹果"变成一个高维度的向量(Embedding),比如: [0.12, 0.85, -0.33, ..., 0.07](假设有 768 维) 你可以理解为:计算机试图用很多个"语义维度"来描述"苹果"这件事。例如: 第 12 维可能代表"是不是水果" 第 47 维可能代表"是不是食物" 第 202 维可能代表"是不是公司名字" 第 588 维可能代表"颜色偏红" 每一维都像是在回答一个隐形的问题,而这个维度上的数值就是模型给出的"打分",越高表示这个特征越明显。 不同的词在这些语义维度上的"打分"不同,最终就构成了不一样的向量。 相似度如何计算? 虽然"苹果"和"香蕉"的词面不同,但它们在语义向量空间中的表示非常相近------因为在很多语义维度上,它们的"打分"都很接近,这就是语义相似性。 我们可以用向量来描述这些词的语义特征。例如,每个词用 [类别, 可食性, 颜色] 三个维度表示如下: 词语 [类别, 食用属性, 颜色] 向量 说明 苹果 食物 + 可食 + 红色 [1.0, 1.0, 0.8] 是食物,能吃,颜色偏红 香蕉 食物 + 可食 + 黄色 [1.0, 1.0, 0.3] 是食物,能吃,颜色偏黄 飞机 交通工具 + 不可食 + 银色 [0.1, 0.1, 0.9] 是交通工具,不能吃,金属色居多 在语义向量中,我们判断两个词是否相似,看的不是它们的数值大小,而是它们"指向的方向"是否一致。为此,我们通常使用 余弦相似度。 cos(θ) = (A · B) / (||A|| × ||B||) 它的核心思想是:比较两个向量之间的夹角。 夹角越小 → 方向越一致 → 语义越相似(cos θ 接近 1) 夹角越大 → 方向越偏离 → 语义差异越大 (cos θ 接近 0,甚至为负) Function Calling:让模型具备调用工具的能力 在日常对话中,大模型通常只需返回文字答案。但当用户提出诸如"帮我查一下明天北京的天气"这类超出模型内置知识范围的问题时,就需要借助 Function Calling,即让 AI 调用外部工具来完成任务。 Function Calling 的核心作用在于让模型具备以下能力: 判断当前问题是否需要使用工具 自动提取参数,并以结构化 JSON 形式生成调用指令 将调用交由程序执行,并接收返回结果,用于后续生成回复。 Function Calling 操作示例 举个例子:用户说 "我明天要去北京旅游,请帮我查天气" AI 会这样处理: 提取参数:城市 "北京",时间 "明天" 制定计划:调用 get_weather 工具获取天气信息 生成调用指令:输出包含一次对 get_weather 的 tool_call,并传入所需参数 "我明天要去北京旅游,请帮我查天气" Function Calling 快速演示 为了让你更直观地理解 Function Calling 的原理和流程,我们准备了一份演示用的 Prompt 模板 。你只需将其复制到 Cherry Studio,即可观察模型如何分析用户请求、提取参数,并生成工具调用指令。 { "role": "AI Assistant", "description": "You are an AI assistant. Your primary goal is to analyze user queries and respond in a structured JSON format. If a query requires a tool and all necessary parameters are present, prepare for tool use. If a query requires a tool but essential parameters are missing, you MUST ask the user for clarification. If no tool is needed, answer directly. Your entire output MUST be a single JSON object at the root level, strictly adhering to the 'response_format'. Ensure all required fields from the schema (like 'requires_tools') are always present in your JSON output.", "capabilities": [ "Analyzing user queries for intent and necessary parameters.", "Identifying when required parameters for a tool are missing.", "Strictly following instructions to set 'requires_tools' to false and use 'direct_response' to ask *only* for the specific missing information required by the tool.", "Remembering the initial query context (e.g., 'weather' intent) when a user provides previously missing information, and then proceeding to tool use if all tool requirements are met.", "Preparing and executing tool calls when the query intent matches a tool and all its defined required parameters are satisfied. Do not ask for details beyond the tool's documented capabilities.", "Formulating direct answers for non-tool queries or clarification questions.", "Detailing internal reasoning in 'thought' and, if calling a tool, a step-by-step plan in 'plan' (as an array of strings)." ], "instructions": [ "1. Analyze the user's query and any relevant preceding conversation turns to understand the full context and intent.", "2. **Scenario 1: No tool needed (e.g., greeting, general knowledge).**", " a. Set 'requires_tools': false.", " b. Populate 'direct_response' with your answer.", " c. Omit 'thought', 'plan', 'tool_calls'. Ensure 'requires_tools' and 'direct_response' are present.", "3. **Scenario 2: Tool seems needed, but *required* parameters are missing (e.g., 'city' for weather).**", " a. **You MUST set 'requires_tools': false.** (Because you cannot call the tool yet).", " b. **You MUST populate 'direct_response' with a clear question to the user asking *only* for the specific missing information required by the tool's parameters.** (e.g., if 'city' is missing for 'get_weather', ask for the city. Do not ask for additional details not specified in the tool's parameters like 'which aspect of weather').", " c. Your 'thought' should explain that information is missing, what that information is, and that you are asking the user for it.", " d. **You MUST Omit 'plan' and 'tool_calls'.** Ensure 'requires_tools', 'thought', and 'direct_response' are present.", " e. **Do NOT make assumptions** for missing required parameters.", "4. **Scenario 3: Tool needed, and ALL required parameters are available (this includes cases where the user just provided a missing parameter in response to your clarification request from Scenario 2).**", " a. Set 'requires_tools': true.", " b. Populate 'thought' with your reasoning for tool use, acknowledging how all parameters were met (e.g., 'User confirmed city for weather query.').", " c. Populate 'plan' (array of strings) with your intended steps (e.g., ['Initial query was for weather.', 'User specified city: Hangzhou.', 'Call get_weather tool for Hangzhou.']).", " d. Populate 'tool_calls' with the tool call object(s).", " e. **If the user just provided a missing parameter, combine this new information with the original intent (e.g., 'weather'). If all parameters for the relevant tool are now met, proceed DIRECTLY to using the tool. Do NOT ask for further, unrelated, or overly specific clarifications if the tool's defined requirements are satisfied by the information at hand.** (e.g., if tool gets 'current weather', don't ask 'which aspect of current weather').", " f. Omit 'direct_response'. Ensure 'requires_tools', 'thought', 'plan', and 'tool_calls' are present.", "5. **Schema and Output Integrity:** Your entire output *must* be a single, valid JSON object provided directly at the root level (no wrappers). This JSON object must strictly follow the 'response_format' schema, ensuring ALL non-optional fields defined in the schema for the chosen scenario are present (especially 'requires_tools'). Respond in the language of the user's query for 'direct_response'." ], "tools": [ { "name": "get_weather", "description": "获取指定城市当前天气 (Gets current weather for a specified city). This tool provides a general overview of the current weather. It takes only the city name as a parameter and does not support queries for more specific facets of weather (e.g., asking for only humidity or only wind speed). Assume it provides a standard, comprehensive current weather report.", "parameters": { "city": { "type": "string", "description": "城市名称 (City name)", "required": true } } } ], "response_format": { "type": "json", "schema": { "requires_tools": { "type": "boolean", "description": "MUST be false if asking for clarification on missing parameters (Scenario 2) or if no tool is needed (Scenario 1). True only if a tool is being called with all required parameters (Scenario 3)." }, "direct_response": { "type": "string", "description": "The textual response to the user. Used when 'requires_tools' is false (Scenario 1 or 2). This field MUST be omitted if 'requires_tools' is true (Scenario 3).", "optional": true// Optional because it's not present in Scenario 3 }, "thought": { "type": "string", "description": "Your internal reasoning. Explain parameter absence if asking for clarification, or tool choice if calling a tool. Generally present unless it's an extremely simple Scenario 1 case.", "optional": true// Optional for very simple direct answers }, "plan": { "type": "array", "items": { "type": "string" }, "description": "Your internal step-by-step plan (array of strings) when 'requires_tools' is true (Scenario 3). Omit if 'requires_tools' is false. Each item MUST be a string.", "optional": true// Optional because it's not present in Scenario 1 or 2 }, "tool_calls": { "type": "array", "items": { "type": "object", "properties": { "tool": { "type": "string", "description": "Name of the tool." }, "args": { "type": "object", "description": "Arguments for the tool." } }, "required": ["tool", "args"] }, "description": "Tool calls to be made. Used only when 'requires_tools' is true (Scenario 3). Omit if 'requires_tools' is false.", "optional": true// Optional because it's not present in Scenario 1 or 2 } } }, "examples": [ // Example for Scenario 3 (direct tool use) { "query": "今天北京天气如何?", "response": { "requires_tools": true, "thought": "User wants current weather for Beijing. City is specified. Use 'get_weather'.", "plan": ["Identified city: 北京.", "Tool 'get_weather' is appropriate.", "Prepare 'get_weather' tool call."], "tool_calls": [{"tool": "get_weather", "args": {"city": "北京"}}] } }, // Multi-turn example demonstrating Scenario 2 then Scenario 3 { "query": "天气如何?", // Turn 1: User asks for weather, no city "response": { // AI asks for city (Scenario 2) "requires_tools": false, "thought": "用户询问天气但未指定城市。'get_weather'工具需要城市名。因此,我必须询问用户城市。", "direct_response": "请问您想查询哪个城市的天气呢?" } }, { "query": "杭州", // Turn 2: User provides city "Hangzhou" "response": { // AI uses tool (Scenario 3) "requires_tools": true, "thought": "The user previously asked for weather and has now provided the city '杭州'. All required parameters for 'get_weather' are met. The tool provides a general current weather report.", "plan": ["Initial query was for weather.", "User specified city: 杭州.", "Call 'get_weather' tool for Hangzhou."], "tool_calls": [{"tool": "get_weather", "args": {"city": "杭州"}}] } }, // Another multi-turn example (English) { "query": "What's the weather like today?", // Turn 1 "response": { // AI asks for city (Scenario 2) "requires_tools": false, "thought": "User wants today's weather but no city provided. 'get_weather' tool needs the city parameter. I must ask for clarification.", "direct_response": "Sure, I can get the weather for you! Which city are you interested in?" } }, { "query": "London", // Turn 2 "response": { // AI uses tool (Scenario 3) "requires_tools": true, "thought": "The user asked about weather and has now specified 'London'. The 'get_weather' tool takes city and provides current weather. Proceeding with tool call.", "plan": ["Original intent was weather.", "City provided: London.", "Call 'get_weather' tool."], "tool_calls": [{"tool": "get_weather", "args": {"city": "London"}}] } }, // Example for Scenario 1 (direct answer) { "query": "你好", "response": { "requires_tools": false, "direct_response": "你好!有什么我可以帮你的吗?" // 'thought' is optional for very simple cases } }, // Example of user being too vague even after specifying city for a non-weather query, but we want to avoid this for weather. // This example is more to ensure the AI understands the "don't ask for unnecessary details for the get_weather tool" instruction. { "query": "告诉我关于巴黎的事情。", // "Tell me about Paris." (General query) "response": { "requires_tools": false, // Assuming no general knowledge tool for this example, or AI should ask for specifics. "thought": "User is asking for general information about Paris. This is too broad. I should ask for more specific interests if no general info tool is available.", "direct_response": "巴黎有很多方面,比如历史、景点、美食等等。您对哪个方面比较感兴趣呢? (Paris has many aspects, like history, attractions, food, etc. Which aspect are you interested in?)" } }, { "query": "查询杭州的天气", // User explicitly states "Hangzhou's weather" "response": { // AI should directly use the tool "requires_tools": true, "thought": "User explicitly asked for Hangzhou's weather. City is clear. The 'get_weather' tool is appropriate and provides a general current weather report.", "plan": ["User query: Hangzhou's weather.", "City: Hangzhou.", "Call 'get_weather' tool."], "tool_calls": [{"tool": "get_weather", "args": {"city": "杭州"}}] } } ] } Function Calling 多轮对话流程 用户提问:"天气如何?"由于未明确城市信息,AI 无法直接调用工具,此时应追问用户所在城市。 用户回复:"杭州"。AI 获取了查询所需的关键信息,提取参数后生成 tool_calls。此时,应用程序识别到 requires_tools: true,根据 tool_calls 调用相应工具函数。 工具执行完成后,结果返回给 AI,AI 再基于结果进行总结并回复用户。 本质上,大模型通过自然语言理解用户意图:要完成什么任务、需要哪些信息。它会自动从对话中提取出关键参数。随后,用户的程序可根据这些参数调用对应的函数完成任务,并将执行结果返回给模型,由模型生成最终回复。 MCP:让模型更好地调用工具 Function Calling 解决了"模型怎么调用自定义函数",但在实际使用中还面临一些问题: 多个工具组成的调用链(先查天气、再发邮件) 工具参数结构的规范与自动注册 不同调用方式的适配(HTTP、本地插件等) 在不同模型间复用统一的工具体系 什么是 MCP? MCP 是由 Anthropic 推出的开放标准协议,旨在为大模型和外部工具之间的通信提供通用接口。 它不是 Function Calling 的替代,而是对其在执行层面 的进一步规范和封装,使工具系统更易接入、更易管理、更易复用。 MCP 核心角色 MCP Client 向 MCP Server 请求工具列表 使用 HTTP 或 stdio 协议发起工具调用请求 MCP Server 接收 tool_calls,根据调用内容执行对应工具 返回统一格式的结构化结果 MCP Server 调用方式 HTTP 模式(StreamableHttp) MCP Server 作为 Web 服务运行,暴露如下接口: /mcp:用于接收工具调用或列出工具列表 支持 Event Stream(流式响应)与 JSON-RPC 协议 以下是一个天气服务的 HTTP 模式演示: cat > streamable_weather.mjs << 'EOF' #!/usr/bin/env node import express from"express"; import { McpServer, ResourceTemplate } from"@modelcontextprotocol/sdk/server/mcp.js"; import { StreamableHTTPServerTransport } from"@modelcontextprotocol/sdk/server/streamableHttp.js"; import { isInitializeRequest } from"@modelcontextprotocol/sdk/types.js"; import { randomUUID } from"node:crypto"; import { StdioServerTransport } from"@modelcontextprotocol/sdk/server/stdio.js"; import { z } from"zod"; const app = express(); app.use(express.json()); function getServer() { const server = new McpServer({ name: "Weather", version: "1.0.0" }); server.resource( "get_weather", new ResourceTemplate("weather://{city}", { list: undefined }), async (uri, { city }) => ({ contents: [{ uri: uri.href, text: `Resource weather for ${city}: 晴,24°C` }] }) ); server.tool( "get_weather", { city: z.string() }, async ({ city }) => ({ content: [{ type: "text", text: `Tool weather for ${city}: 明天晴,最高24°C,微风3km/h` }] }) ); server.prompt( "get_weather", { city: z.string() }, ({ city }) => ({ messages: [{ role: "user", content: { type: "text", text: `请告诉我 ${city} 的天气情况` } }] }) ); return server; } app.post("/mcp", async (req, res) => { try { const server = getServer(); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, }); res.on("close", () => { console.log("Request closed"); transport.close(); server.close(); }); await server.connect(transport); await transport.handleRequest(req, res, req.body); } catch (error) { console.error("Error handling MCP request:", error); if (!res.headersSent) { res.status(500).json({ jsonrpc: "2.0", error: { code: -32603, message: "Internal server error", }, id: null, }); } } }); app.get("/mcp", (req, res) => { console.log("Received GET MCP request"); res.status(405).json({ jsonrpc: "2.0", error: { code: -32000, message: "Method not allowed.", }, id: null, }); }); app.delete("/mcp", (req, res) => { console.log("Received DELETE MCP request"); res.status(405).json({ jsonrpc: "2.0", error: { code: -32000, message: "Method not allowed.", }, id: null, }); }); const PORT = process.env.PORT || 30001; app.listen(PORT, () => { console.log( `MCP Stateless Streamable HTTP Server listening on http://localhost:${PORT}/mcp` ); }); EOF # 安装依赖 npm install express @modelcontextprotocol/sdk zod # 启动服务 node streamable_weather.mjs # 获取工具列表 curl -N -X POST http://localhost:30001/mcp \ -H 'Accept: application/json, text/event-stream' \ -H 'Content-Type: application/json' \ -d '{ "jsonrpc":"2.0", "id":1, "method":"tools/list", "params":{} }' # > 返回工具 event: message data: {"result":{"tools":[{"name":"get_weather","inputSchema":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}}]},"jsonrpc":"2.0","id":1} # 执行工具调用链 curl -N -X POST http://localhost:30001/mcp \ -H 'Accept: application/json, text/event-stream' \ -H 'Content-Type: application/json' \ -d '{ "jsonrpc":"2.0", "id":2, "method":"tools/call", "params":{ "name":"get_weather", "arguments":{ "city":"北京" } } }' # > 返回执行结果 event: message data: {"result":{"content":[{"type":"text","text":"Tool weather for 北京: 明天晴,最高24°C,微风3km/h"}]},"jsonrpc":"2.0","id":2} Stdio 模式(本地插件) Stdio 模式适用于本地运行的插件程序。模型与 MCP Server 通过标准输入输出进行通信,不依赖网络,适合部署在受限环境下。 以下是一个天气服务的 Stdio 模式演示: cat > weather_stdio.mjs << 'EOF' #!/usr/bin/env node import { McpServer, ResourceTemplate } from"@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from"@modelcontextprotocol/sdk/server/stdio.js"; import { z } from"zod"; const server = new McpServer({ name: "Weather", version: "1.0.0" }); server.resource( "get_weather", new ResourceTemplate("weather://{city}", { list: undefined }), async (uri, { city }) => ({ contents: [{ uri: uri.href, text: `Resource weather for ${city}: 晴,24°C` }] }) ); server.tool( "get_weather", { city: z.string() }, async ({ city }) => ({ content: [{ type: "text", text: `Tool weather for ${city}: 明天晴,最高24°C,微风3km/h` }] }) ); server.prompt( "get_weather", { city: z.string() }, ({ city }) => ({ messages: [{ role: "user", content: { type: "text", text: `请告诉我 ${city} 的天气情况` } }] }) ); const transport = new StdioServerTransport(); await server.connect(transport); EOF # 获取工具列表 printf '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}\n' | node weather_mcp.mjs # > 返回工具 {"result":{"tools":[{"name":"get_weather","inputSchema":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}}]},"jsonrpc":"2.0","id":1} # 执行工具调用链:调用 get_weather printf '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"北京"}}}\n' | node weather_mcp.mjs # > 返回执行结果 {"result":{"content":[{"type":"text","text":"Tool weather for 北京: 明天晴,最高24°C,微风3km/h"}]},"jsonrpc":"2.0","id":4} MCP 多轮对话流程 在多轮对话中,当用户输入:"北京天气如何?" AI 会识别出用户意图需要使用工具 get_weather,并生成如下结构化调用指令: { "tool": "get_weather", "args": { "city": "北京" } } 用户的程序会将该调用指令转发至 MCP Server,MCP Server 接收到该调用请求后,执行对应工具,并返回如下结构化结果: 用户的程序从 result.content 中提取文本字段,即 content.text,再进行总结和自然语言生成,最终回复用户: 明天北京天气晴朗,最高气温24°C,微风3km/h。感谢您的咨询!如果还有其他问题,请随时提出。 MCP 为大模型对接外部世界提供了统一且可扩展的执行框架,具备以下优势: 支持多种通信方式(HTTP、Stdio); 支持统一的工具注册与声明; 可复用的跨模型调用协议; 易于本地或远程部署。 它与 Function Calling 搭配使用,为构建模块化、可编排、可维护的 AI Agent 系统打下了基础。 AI Agent:具备认知与行动能力的智能体 AI Agent 是一个具备认知、行动、反思能力的完整智能系统,通常整合了RAG、Function Calling 和 MCP: 用 RAG 获取知识; 用 Function Calling 执行操作; 用 MCP 统一工具调用标准。 一个成熟的 AI Agent 能够: 理解目标:通过自然语言指令(如"帮我查下北京的天气")识别用户意图; 主动拆解任务:将复杂任务拆分为多个可执行步骤,按序执行; 调用外部工具:自动连接 API、数据库、搜索引擎等外部系统; 记忆上下文:理解当前对话历史与任务进展; 自我反思:在执行失败后尝试重试、重新规划或变更路径(部分 Agent 支持)。 相较于传统的聊天式 AI,AI Agent 更像一个"可指挥、可编排"的执行者,具备在真实应用中解决复杂问题的能力,广泛适用于客服、数据处理、自动化办公、个人助理等场景。 概念对比一览 概念 本质 数据来源 适用场景 典型应用 RAG 检索 + 生成 知识库 / 文档 专业问答、动态知识更新 企业知识库、客服机器人 Function Calling 调用外部函数 API / 数据库 实时数据交互、自动化任务 天气查询、订单处理 MCP 标准化工具调用协议 多平台服务(如 GitHub) 跨模型、跨服务协作 智能工作流(如查天气+发邮件) AI Agent 自主规划 + 执行 综合(RAG + 工具调用) 复杂任务自动化 个人助理 CloudCanal RAG 近期 CloudCanal 支持了构建 RagApi 服务,基于标准的 RAG 架构,同时引入了 MCP 协议,实现了向量化、检索、问答生成与工具链调用的端到端闭环。 构建流程 CloudCanal 构建的 RagApi 对外暴露为 OpenAI 格式的 API 接口,可直接对接业务系统或调用方。整体流程分为两个阶段: 阶段一:数据准备与嵌入(File → PostgreSQL 向量库) 数据采集与准备 企业知识来源包括 Markdown、TXT、数据库、内部文档等。用户通过 CloudCanal 创建嵌入任务,配置数据源、模型、目标表等信息。 数据切分与向量化 CloudCanal 自动处理原始文档并生成向量嵌入,写入 pgvector 扩展的向量字段中(如 __vector 列)。 阶段二:API 构建与服务发布(PostgreSQL → RagApi) 查询向量化与语义优化 用户问题进入对话接口后,系统首先会使用相同的嵌入模型将问题向量化。此过程中可启用以下能力模块: 压缩查询(QUERY_COMPRESS):对原始提问进行语义压缩,去除冗余、聚焦核心内容,提高向量匹配精度。 扩展查询(QUERY_EXTEND):自动引入近义词、相关概念或补充说明,扩大匹配范围,提高召回率。 向量检索与知识片段选择 在向量库中进行相似度搜索,检索结果可进一步通过 知识片段选择(KNOWLEDGE_SELECT) 进行筛选,支持多个知识库场景,系统会根据语义相关性自动选择最匹配的知识片段(支持跨表路由)。 Prompt 构造与上下文拼接 系统根据用户配置的 Prompt 模板,将问题与召回内容结合,构造出最终用于模型推理的 Prompt 输入。 模型推理与回答生成 生成的 Prompt 被送入指定的 Chat 模型进行推理(如 deepseek r1、qwq-plus、GPT-4o 等),模型返回最终回答内容。 MCP 工具链集成(可选) 如需执行任务类问题(如"查 GitHub PR 状态"、"调用企业 API"),可启用 MCP 工具链调用。 支持标准化注册的 MCP 工具(HTTP / stdio),通过 Function Calling 调用链执行外部任务,补全答案或直接完成任务。 具体操作步骤可参考: 1.《使用大模型将数据嵌入到 PostgreSQL 向量》 2.《基于 PostgreSQL 向量构建 RAG API 服务》 任务创建成功后,将对外暴露一个具备内置知识库支持、查询语义优化能力、可选 MCP 工具链执行的 RAG 服务 ,且兼容 OpenAI 的 API 协议。 相当于将用户原有的大模型 API 接口进行了增强------无需更改客户端代码,即可接入增强后的智能问答与任务执行服务。 这里可以通过可视化工具 CherryStudio 进行交互测试。CherryStudio 兼容 OpenAI 接口标准,适合用于接口联调、上下文调试和模型效果验证。 Cherry Studio 配置步骤 打开 Cherry Studio,在"模型服务"中搜索 OpenAI。 配置参数如下: API 密钥:填写在 CloudCanal 中配置的 RagApi API Key API 地址:http://localhost:18089 模型名称:填写 CC_RAG 回到对话页面: 添加助手 → Default Assistant。 右键点击 Default Assistant → 编辑助手 → 模型设置,绑定上一步添加的模型。 在对话窗口中输入: CloudCanal 增量同步任务延迟是什么原因?应该怎么处理? RagApi 将根据向量数据自动检索相关知识内容(本例使用 CloudCanal 文档知识库),结合模型生成自然语言回答。 MCP 工具链集成示例 如果 RagApi 配置了 MCP 工具服务(如网页抓取、GitHub 查询等),模型可自动生成工具调用。 步骤如下: 进入 CloudCanal,点击任务详情页右上角「功能列表」>「参数修改」。 进入「目标数据源配置」,找到 mcpServers,将如下配置粘贴进去。 点击右上角「生效配置」,确认参数修改内容。 点击「确认」。如部分参数需重启任务生效,系统会自动提示是否重启。 { "mcpServers": { "github": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-github" ], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>" } }, "mcp-server-firecrawl": { "command": "npx", "args": [ "-y", "firecrawl-mcp" ], "env": { "FIRECRAWL_API_KEY": "<YOUR_API_KEY_HERE>" } } } } CloudCanal 将自动触发 MCP 工具执行 ,并进行多轮调用与总结 ,最终返回结果: 总结 RAG、Function Calling、MCP 和 AI Agent 不是孤立存在的技术,而是在现实应用中彼此协同、互为补充。CloudCanal 近期支持的 RagApi 服务,融合了这些 AI 底层能力,可以零代码傻瓜式完成 RAG 服务的构建,大大降低了使用智能 AI 的门槛。

优秀的个人博客,低调大师

MiniMax GenAI 可观测性分析 :基于阿里云 SelectDB 构建 PB 级别日志系统

"阿里云SelectDB作为MiniMax日志存储服务的核心支撑,为在线和离线业务提供了高效、稳定的查询与聚合分析能力。其支持实时物化视图、租户资源隔离、冷热分离等企业级特性,不仅有效解决了日志场景下PB级别数据查询的性能瓶颈,还通过智能化的资源调度与存储优化,实现了成本与效率的最佳平衡,为业务的高效运转提供了坚实保障。" ------MiniMax可观测架构师 香克斯 可观测日志系统的探索与挑战 近年来,MiniMax在多模态与文本模型领域持续发力,凭借其技术突破和应用创新能力,迅速成为全球人工智能领域的焦点。25年1月,MiniMax发布了多项重磅成果:支持主体参考功能的视频新模型S2V-01、基于大规模线性注意力机制的开源模型MiniMax-01系列,以及支持17种语言音频合成的T2A-01系列语音模型。作为一家成立仅三年但估值已突破数十亿美元的初创企业,MiniMax已然跻身人工智能领域最具潜力的独角兽企业之列。 为了深入洞察模型训练迭代和 AI应用的运行状态,精准定位潜在问题以持续优化模型和业务系统的性能,可观测系统的建设成为MiniMax底层基础设施建设中不可或缺的关键环节。然而,随着业务规模的快速扩张,海量日志数据的处理对系统的性能和成本提出了严峻挑战。 Loki架构的尝试与局限性 **在可观测系统的建设初期,为降低业务系统复杂度和存储成本,MiniMax采用轻量化的Grafana Loki。**其中,Promtail负责采集日志并发送给Loki,Loki负责日志存储和查询,Grafana用于UI展示。Loki通过日志标签和元数据索引显著降低了存储成本和索引复杂度。然而,因缺乏日志内容的索引,查询依赖正则表达式匹配和逐行扫描,造成大规模日志查询时资源消耗过高,查询响应时间延长。此外,每个Kubernetes集群需独立部署完整的日志采集与存储服务,增加了运维复杂度和成本。 随着业务规模的指数级增长,MiniMax日志数据量迅速攀升至PB级别,Apache Loki在资源消耗、写入性能和查询易用性等方面暴露出瓶颈。为此,MiniMax对日志可观测系统提出了更高要求: 更高的查询性能:支持上亿条数据的秒级查询响应。 更低的存储成本:在PB级日志数据规模下,实现更具性价比的日志采集与存储方案。 Doris架构的升级与痛点 为满足上述需求,MiniMax对日志可观测系统进行了全面重构。新系统采用阿里云开源的iLogtail作为日志采集工具,将日志数据推送至Kafka消息队列。随后,数据通过两种方式写入Doris集群:一部分由Mlogs Ingester从Kafka拉取并通过Stream Load写入Doris;另一部分由Doris通过Routine Load直接订阅Kafka消息流。Doris作为核心存储与查询引擎,实现了全量日志数据的统一管理,避免了多集群独立部署的复杂性。 然而,随着MiniMax旗下星野和Talkie等AI应用的日活跃用户数迅速攀升至行业榜首,其日志数据量和查询请求呈爆发式增长,日均新增日志数据量超过数百TiB,MiniMax日志可观测系统逐渐面临了诸多挑战: 业务快速扩张导致数据和查询量激增,频繁的集群扩容需要进行数据迁移,因数据规模较大,迁移过程繁琐且耗时,影响了业务连续性。 日志可观测系统负责多个业务的数据分析,单实例多业务并发时,内部资源竞争和干扰导致实例稳定性和查询性能下降,降低用户体验和决策及时性。 自建Doris的运维成本较高 ,参数调优和集群管理耗费了大量的人力物力。 在遇到Apache Doris内核相关问题时,社区支持的效率和专业性不均衡,增加了企业解决问题的时间成本和风险。 这些问题制约了MiniMax日志可观测系统的优化升级,亟待寻求更高效、稳定的解决方案。 DevOps日志系统最佳实践:阿里云SelectDB 为了应对上述挑战,MiniMax引入了阿里云企业级数据仓库SelectDB。SelectDB沿用了Apache Doris的技术架构,100%兼容Doris语法,并针对写入吞吐和查询性能等方面进行了深度优化。它不仅降低了使用成本,还简化了运维流程,提高了服务等级协议(SLA)保障。通过采用存算分离的云原生架构,SelectDB为处理海量日志提供了近乎无限的扩展能力,从而为MiniMax的日志可观测体系提供了更加稳定和健壮的日志数据处理能力。 阿里云SelectDB技术方案优势 阿里云SelectDB以其实时弹性、简单易用、开源开放等差异化优势,能够实时处理PB级别的日志数据,并且提供了万级QPS实时报表查询和亚秒级即席多维分析的体验。与开源自建方案相比,SelectDB在性价比上有显著提升,并通过深度优化OSS写入方式,实现了超过10GB/s的读写吞吐能力。 优势一:弹性伸缩,提高集群扩容效率 Apache Doris采用MPP架构,基于分桶逻辑进行数据的物理水平拆分,这种架构在用户数据量稳定阶段能有效利用多分桶的并行处理能力解决大规模数据实时查询问题。然而,随着数据写入量和单个分桶数据量的快速增长,单个数据分桶节点可能会达到资源瓶颈,此时集群必须进行水平扩展。Doris的水平扩展需要进行全量数据的Reblance,以避免各个节点间负载不均衡。对于MiniMax来说,单次扩容因涉及PB级数据的重分布,可能需要数小时甚至达到天级别,给运维带来巨大负担。此外,突发业务流量时,扩容效率低可能导致集群资源不足,进而引发实例宕机风险。 阿里云SelectDB采用存算分离的云原生架构,将计算与存储分层解耦,支持独立扩缩容。在扩容过程中无需迁移数据,PB级数据可以实现分钟级扩缩容 。业务低谷期可以根据实际情况动态缩减资源,避免了资源浪费,最大化提高资源利用效率。MiniMax在将日志可观测系统迁移到SelectDB 后,整体集群扩容时间可达到分钟级别,大大降低了运维成本,并且能够通过弹性伸缩能力迅速应对突发业务流量。 优势二:存算分离, 提升吞吐效率并降低存储成本 MiniMax在使用Apache Doris集群时,为了实现数据高可用,生产环境默认采用Doris的两副本模式,导致存储资源消耗和集群写入压力均增至单副本的两倍 。此外,考虑到过高的存储成本,MiniMax在Doris数仓中仅保留15天的业务数据,其他数据通过冷归档的方式存储;而需要对这部分归档数据进行查询分析时,则临时从归档库中解压加载后才能进行分析,极大降低了数据查询的效率。 阿里云SelectDB采用存算分离的设计,存储层基于阿里云对象存储OSS提供存储服务。MiniMax在使用SelectDB后,利用OSS的数据高可用能力,计算引擎仅需单份数据写入,存储资源需求减少至Doris的二分之一,实际业务写入吞吐能力提升超20% 。此外,由于整体存储成本的降低,SelectDB支持对历史全量数据的实时查询分析,大大提高了数据查询效率 。 优势三:资源隔离,提高并发读写效率 MiniMax在使用Apache Doris时,存在多个业务团队共享同一实例进行全量数据查询分析的情况,可能导致因不规范或大规模查询耗尽实例资源,进而引发查询或数据导入任务超时。 **阿里云SelectDB支持云原生多集群硬隔离能力,用户可以将单个实例的计算资源划分为多个逻辑集群,不同集群之间的分配独立的****计算资源,实现了不同集群的严格物理资源隔离和数据共享,很好的解决负载隔离问题。此外,SelectDB还支持读写分离能力,进一步提高了并发查询效率。MiniMax在使用了SelectDB后,采用了SelectDB多集群隔离能力,并将读写集群分开,避免了读写资源抢占带来的实例稳定性问题,大大提高了并发读写效率。 优势四:缓存加速,提供高吞吐与低延迟 **阿里云SelectDB通过单副本本地读写缓存、智能数据淘汰策略、高效列式存储格式和先进压缩算法,显著提升了海量数据的读写效率。**业务进行数据查询时,依据LRU的读缓存策略,保证业务对于实时写入数据和高频查询热数据的查询性能。当发现缓存命中率低和查询性能不及预期时,可以进行实时的缓存空间扩容,以提升缓存命中率,PB级数据P95查询可以在3秒内响应,提高了数据查询效率。 阿里云SelectDB还具备高SLA保障,持久化数据存储提供同城冗余和12个9的数据可靠性保障。此外,SelectDB还供了直观的用户界面和产品化的运维工具,支持扩缩容、版本升级、参数配置和监控告警等操作,显著降低了运维复杂度。用户仅需关注计算资源、缓存大小和数据存储使用率等核心指标,减少了开发和运维团队的负担。 业务价值 基于阿里云SelectDB,MiniMax构建了覆盖国内及海外业务的日志可观测中台,总体数据规模超过数PB,日均新增日志写入量达数百TB。系统在P95分位查询场景下的响应时间小于3秒,峰值时刻实现了超过10GB/s的读写吞吐。通过存算分离、高压缩比算法和单副本热缓存等技术手段,MiniMax在优化性能的同时显著降低了建设成本,计算资源用量降低40%,热数据存储用量降低50%,为未来业务的高速发展和技术演进奠定了坚实基础。 总结与展望 回顾MiniMax可观测系统的演进历程,从初期的Loki架构到Apache Doris的引入,再到SelectDB的全面升级,每一次技术迭代都体现了MiniMax对业务需求的深刻理解和对技术创新的不懈追求。阿里云SelectDB凭借其卓越的性能、灵活的架构和强大的生态能力,为MiniMax提供了高效、稳定的日志存储与分析服务,助力其在大模型实践中实现成本与效率的最佳平衡。 未来,随着MiniMax业务的持续高速发展,日志可观测系统将继续作为洞察系统运行状态和优化性能的核心工具。阿里云将与MiniMax携手,进一步挖掘日志数据的潜在价值,为业务创新提供更强有力的支持。

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册