尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

MCP协议详解:构建AI智能体可扩展能力的开放标准

MCP协议详解:构建AI智能体可扩展能力的开放标准 1. 项目概述为什么MCP值得每一位开发者关注最近在AI应用开发圈子里MCPModel Context Protocol这个词的热度越来越高。如果你关注Claude Code、Cursor这类AI编程工具或者在使用Obsidian、Figma等生产力软件时希望获得更智能的辅助那你很可能已经接触过MCP或者至少听说过它。我第一次深入了解MCP是在尝试让Claude Code帮我分析一个本地项目代码库时发现它无法直接读取我的文件系统当时就在想如果AI能像插件一样“接入”我的工作环境该多好。后来发现MCP正是为了解决这个问题而生的。简单来说MCP是一个开放协议它定义了AI模型比如Claude、GPT如何安全、标准化地与外部工具、数据源和系统进行交互。你可以把它想象成AI世界的“USB协议”或“插件标准”。在没有MCP之前如果你想给一个AI助手增加“读取本地数据库”或“操作Figma设计稿”的能力可能需要针对每个AI平台写一套复杂的集成代码过程繁琐且不通用。而MCP提供了一套统一的“插座”和“插头”规范任何符合MCP标准的工具称为MCP Server都可以被任何支持MCP的AI客户端称为MCP Client即插即用。这带来的直接好处是巨大的。对于开发者而言你不再需要为Claude、Cursor、Dify等不同平台重复开发集成功能。你只需要编写一个符合MCP协议的服务器它就能被所有支持MCP的客户端调用。对于用户来说这意味着你的AI助手能力可以无限扩展今天给它装上“文件系统阅读器”明天装上“数据库查询器”后天再装个“音乐播放控制器”它就能从一个单纯的聊天机器人进化成你数字工作流的全能中枢。从网络上的热议也能看出它的潜力大家关心如何为Code添加搜索类MCP服务器如tavily-mcp如何打通Claude Code到Obsidian的笔记流甚至如何开发自己的MCP Server。这背后反映的是业界对构建更开放、更可组合的AI智能体的强烈需求。MCP很可能成为下一代AI应用基础设施的关键拼图。2. MCP核心原理与架构拆解协议层到底规定了什么要真正用好MCP不能只停留在“它是一个协议”的模糊认知上。我们需要拆开它的技术外壳看看里面到底是怎么运转的。MCP的核心思想其实非常清晰它采用客户端-服务器Client-Server架构并通过标准化的JSON-RPC over STDIO/SSE进行通信。这句话听起来有点技术化我们把它翻译成更易懂的比喻。想象一下AI客户端比如Claude Code是一个“大脑”它很聪明但眼不能看、耳不能听、手不能动。MCP Server就是为这个大脑配备的“感官器官”和“机械臂”。它们之间需要一个高效、无歧义的沟通方式。MCP协议就是这个沟通方式的“世界语”词典和语法手册。2.1 通信基石JSON-RPC与传输层MCP选择JSON-RPC作为其远程过程调用的协议这是一个非常务实且成熟的选择。JSON格式轻量、通用几乎被所有编程语言支持。RPC远程过程调用模式则让调用远程服务器的函数就像调用本地函数一样简单。在传输层MCP主要支持两种方式标准输入输出STDIO这是最常见的方式尤其适合本地工具集成。MCP Server作为一个独立的进程启动AI客户端通过管道pipe与其标准输入stdin和标准输出stdout连接。双方通过这个管道交换JSON-RPC消息。这种方式部署简单隔离性好一个Server崩溃不会直接影响客户端主进程。服务器发送事件SSE这种方式更适合网络环境或需要服务器主动推送信息的场景。MCP Server作为一个HTTP服务器运行客户端通过建立SSE连接来接收服务器推送的更新例如文件系统的变化、数据库的实时更新。客户端则通过HTTP POST请求来发送JSON-RPC调用。在实际开发中STDIO模式占绝大多数。你编写的MCP Server就是一个可以从命令行启动的程序它持续从stdin读取JSON请求处理后将JSON响应写入stdout。2.2 核心资源模型工具Tools、资源Resources与提示词PromptsMCP协议定义了三种核心概念这是Server向Client宣告自己能力的载体工具Tools这是最常用、最直接的能力暴露方式。一个Tool就是一个可以被AI调用的函数。例如一个“搜索网络”的Tool一个“执行SQL查询”的Tool或者一个“播放指定音乐”的Tool。每个Tool都有明确的输入参数inputSchema定义。当AI模型认为需要调用某个Tool时它会生成符合该Schema的参数客户端则负责调用对应的Server方法。实操细节在定义inputSchema时务必详尽且类型准确。使用JSON Schema来描述参数包括类型string, number, boolean, array、是否必需、描述、枚举值等。一个清晰的Schema能极大地帮助AI模型理解何时以及如何调用你的工具。资源ResourcesResource代表的是可供AI读取的“数据”或“内容”。它可以是文本、图像、代码片段或者任何URI可以指向的东西。例如你的本地文件系统中的某个文件、数据库中的一张表视图、一个在线的API文档页面都可以被定义为一个Resource。AI客户端可以“读取”read这些资源的内容将其作为上下文信息注入到与用户的对话中。核心价值Resource机制使得AI能够突破其固有知识库的限制动态加载最新的、私有的或特定场景下的信息。这是实现“Codebase Memory”代码库记忆或“个人知识库助手”等功能的基础。提示词PromptsPrompt是一段预定义的文本模板可以包含参数。AI客户端可以获取get这些Prompt并将其用作与用户对话的起点或框架。这允许Server开发者封装一些最佳实践或特定领域的对话流程。使用场景比如一个代码审查MCP Server可以提供“审查Python函数安全性”的Prompt模板用户输入函数代码作为参数AI就能基于这个模板进行专业的审查。一个典型的交互流程初始化Client启动连接到Server。Server向Client发送一个initialize请求交换双方的能力和配置。能力宣告Server通过notify消息向Client列出自己提供的所有Tools、Resources和Prompts的元数据名称、描述、参数Schema等。调用用户向AI提出需求如“帮我查一下今天的天气”。AI模型分析后决定调用Server提供的“查询天气”Tool。Client向Server发送tools/call请求附带参数{“location”: “北京”}。执行与返回Server执行真正的查询逻辑可能是调用一个天气API然后将结果封装成标准格式通过tools/result返回给Client。内容呈现Client将Tool执行的结果“北京今天晴25度”提供给AI模型AI模型再整合这个信息生成最终回复给用户。注意MCP协议本身不关心Tool内部如何实现。它只关心“调用接口”和“返回格式”。这意味着你可以用Python、JavaScript、Go、Java等任何语言来实现Server的内部逻辑只要最终通过STDIO或SSE说出MCP规定的“语言”即可。3. 从零构建一个MCP Server以“本地文件搜索”为例理论讲得再多不如动手做一个。我们以构建一个“本地文件搜索”MCP Server为例这是很多开发者第一个想做的工具因为它实用且能直观体现MCP的价值。我们将使用Python来实现因为它生态丰富且易于理解。3.1 环境准备与项目初始化首先你需要一个Python环境3.8。然后我们选择官方推荐的SDK来简化开发。Anthropic提供了mcp这个Python库它封装了底层的协议通信细节让我们可以专注于业务逻辑。# 创建项目目录并初始化虚拟环境 mkdir local-file-search-mcp cd local-file-search-mcp python -m venv venv # 激活虚拟环境 (Linux/macOS) source venv/bin/activate # Windows # venv\Scripts\activate # 安装MCP SDK pip install mcp接下来我们创建一个主要的服务器文件server.py。3.2 核心工具Tool的实现search_files我们的核心目标是提供一个Tool让AI能根据关键词搜索我们指定目录下的文件内容。# server.py import os from pathlib import Path from typing import Any, List import mcp.server as mcp from mcp.server.models import InitializationOptions import mcp.server.stdio # 创建一个Server实例 app mcp.Server(local-file-search) # 定义我们允许搜索的根目录基于安全考虑必须限制范围 ALLOWED_ROOT Path.home() / projects # 例如只允许搜索用户Home目录下的projects文件夹 app.list_tools() async def handle_list_tools() - list[mcp.Tool]: 向客户端宣告我们提供的工具列表 return [ mcp.Tool( namesearch_files, description在允许的项目目录内根据关键词搜索文件内容。, inputSchema{ type: object, properties: { keyword: { type: string, description: 用于搜索文件内容的关键词 }, file_extension: { type: string, description: 可选的文件扩展名过滤器例如 .py, .md, default: } }, required: [keyword] } ) ] app.call_tool() async def handle_call_tool(name: str, arguments: dict[str, Any]) - list[mcp.TextContent]: 处理客户端对工具的调用 if name search_files: return await handle_search_files(**arguments) else: raise ValueError(f未知工具: {name}) async def handle_search_files(keyword: str, file_extension: str ) - list[mcp.TextContent]: 执行文件搜索的核心逻辑 if not keyword.strip(): return [mcp.TextContent(typetext, text搜索关键词不能为空。)] results: List[str] [] # 使用pathlib递归遍历目录更安全高效 for file_path in ALLOWED_ROOT.rglob(*): # 安全检查确保文件在允许的根目录下防御路径遍历 try: file_path.relative_to(ALLOWED_ROOT) except ValueError: continue # 文件不在允许的目录内跳过 if not file_path.is_file(): continue if file_extension and not str(file_path).endswith(file_extension): continue try: # 针对文本文件进行搜索忽略二进制文件 with open(file_path, r, encodingutf-8, errorsignore) as f: content f.read() if keyword.lower() in content.lower(): # 记录匹配的文件路径和简要上下文 # 这里可以优化为显示匹配行为了简单先展示路径 results.append(f- {file_path.relative_to(ALLOWED_ROOT)}) except (UnicodeDecodeError, IOError): # 跳过无法读取或非文本的文件 continue if results: result_text f在目录 {ALLOWED_ROOT} 中搜索关键词 {keyword} 找到 {len(results)} 个文件\n \n.join(results[:20]) # 限制返回数量 if len(results) 20: result_text f\n... 以及另外 {len(results) - 20} 个文件。 else: result_text f在目录 {ALLOWED_ROOT} 中未找到包含关键词 {keyword} 的文件。 return [mcp.TextContent(typetext, textresult_text)] async def main(): 启动服务器使用标准输入输出进行通信 async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await app.run( read_stream, write_stream, InitializationOptions( server_namelocal-file-search, server_version0.1.0 ) ) if __name__ __main__: import asyncio asyncio.run(main())代码关键点解析安全第一我们严格限定了搜索根目录ALLOWED_ROOT。绝对不能让AI拥有无限制的文件系统访问权限这是MCP Server开发的铁律。在实际产品中这个路径应该由用户配置。工具定义app.list_tools()装饰器下的函数返回工具列表。每个工具都需要清晰的name,description和inputSchema。好的描述能帮助AI准确理解工具用途。输入验证在handle_search_files中我们首先检查关键词是否为空。虽然Schema定义了required但Server端仍需做验证。错误处理文件读取时可能会遇到编码错误或权限问题我们用try...except捕获这些异常并跳过避免整个Server崩溃。结果格式化返回给AI的结果应该是结构清晰、信息量适中的文本。我们限制了返回的文件数量防止结果过长淹没AI的上下文。3.3 运行与测试你的第一个MCP Server现在我们可以先不依赖AI客户端用最简单的方法测试一下Server是否能正常工作。MCP协议基于STDIO我们可以手动模拟一个客户端。创建一个测试脚本test_client.py# test_client.py (简易测试) import subprocess import json # 启动Server进程 proc subprocess.Popen( [python, server.py], stdinsubprocess.PIPE, stdoutsubprocess.PIPE, stderrsubprocess.PIPE, textTrue ) # 模拟发送一个简单的初始化请求简化版 init_request { jsonrpc: 2.0, id: 1, method: initialize, params: { protocolVersion: 1.0, capabilities: {}, clientInfo: {name: test-client} } } proc.stdin.write(json.dumps(init_request) \n) proc.stdin.flush() # 读取一行响应 response_line proc.stdout.readline() print(Server响应:, response_line) # 发送关闭请求 shutdown_request { jsonrpc: 2.0, id: 2, method: shutdown, params: {} } proc.stdin.write(json.dumps(shutdown_request) \n) proc.stdin.flush() proc.terminate()更专业的测试方法是使用像MCP Inspector这样的工具。它是一个图形化调试工具可以连接到你的MCP Server可视化地查看Server提供的Tools/Resources并手动触发调用是开发调试的利器。你可以从MCP的官方GitHub仓库找到它的安装和使用方法。4. 在Claude Code中配置与使用自定义MCP Server构建好Server后下一步就是让它被AI客户端使用。这里以Claude Code或Cursor的Claude模式为例因为它对MCP的支持比较直接。4.1 配置Claude Desktop以使用MCPClaude Desktop应用允许通过配置文件添加自定义的MCP Server。找到配置文件macOS:~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:%APPDATA%\Claude\claude_desktop_config.jsonLinux:~/.config/Claude/claude_desktop_config.json如果文件或目录不存在手动创建即可。编辑配置文件在配置文件中添加mcpServers字段。以下是一个配置我们刚编写的local-file-searchServer的示例{ mcpServers: { local-file-search: { command: python, args: [ /ABSOLUTE/PATH/TO/YOUR/local-file-search-mcp/venv/bin/python, // 注意必须使用虚拟环境中的Python解释器绝对路径 /ABSOLUTE/PATH/TO/YOUR/local-file-search-mcp/server.py ], env: { // 可以在这里设置环境变量 } } // 你可以在这里继续添加其他MCP Server例如tavily搜索、数据库连接等 // tavily-search: { ... }, // obsidian-vault: { ... } } }关键配置项说明command: 启动Server的命令。对于Python脚本通常就是python。args: 传递给命令的参数列表。最重要的一点你必须使用虚拟环境中Python解释器的绝对路径作为第一个参数然后是脚本的绝对路径。直接写python可能会使用系统默认的Python导致依赖包缺失。在Windows上虚拟环境的Python路径类似C:\...\local-file-search-mcp\venv\Scripts\python.exe。env: 可选的环境变量。如果你的Server需要访问特定的API密钥如搜索服务的Key可以在这里设置例如TAVILY_API_KEY: your_key_here。重启Claude Desktop保存配置文件后完全退出并重新启动Claude Desktop应用。4.2 在对话中验证与使用重启后在Claude Code的聊天界面你可以尝试直接询问“你现在可以使用哪些工具”或者“你有什么能力”。如果配置成功Claude应该会回复它已连接到一个名为“local-file-search”的服务器并列出可用的工具即我们的search_files。现在你可以进行自然语言搜索了用户“请在我的项目里搜索所有提到‘用户认证’的Python文件。”Claude识别到需要调用工具它会自动调用search_files工具参数为{“keyword”: “用户认证” “file_extension”: “.py”}然后将工具返回的结果整合到它的回复中。实操心得路径问题是最常见的坑80%的MCP Server连接失败都源于配置文件中的路径错误。务必使用绝对路径并确保Claude Desktop应用有权限执行该路径下的命令和脚本。权限问题在macOS或Linux上可能需要为脚本文件添加执行权限(chmod x server.py)或者确保Python解释器可执行。查看日志如果连接失败查看Claude Desktop的应用日志通常可以在其设置菜单中找到能获得详细的错误信息是排查问题的关键。5. 进阶构建更复杂的MCP Server与生态集成掌握了基础Server的构建后我们可以探索更复杂的场景这也是MCP生态的魅力所在。5.1 实现资源Resources提供以“项目文件树”为例除了工具让AI能动态读取资源也很有用。比如我们可以提供一个Resource让AI能获取当前项目目录的文件树结构帮助它了解项目布局。在server.py中增加以下代码from mcp.server.models import ResourceTemplate app.list_resources() async def handle_list_resources() - list[ResourceTemplate]: 向客户端宣告我们提供的资源模板 return [ ResourceTemplate( uriTemplatefile-tree://{project_path}, name项目文件结构, description获取指定项目路径的目录树结构。, mimeTypetext/plain ) ] app.read_resource() async def handle_read_resource(uri: str) - mcp.ResourceContents: 处理客户端读取资源的请求 if uri.startswith(file-tree://): # 解析出路径参数 import urllib.parse parsed urllib.parse.urlparse(uri) # 简单处理实际应从uri中安全地提取路径 # 这里假设路径是uri中file-tree://之后的部分 request_path uri.replace(file-tree://, , 1) if not request_path: request_path str(ALLOWED_ROOT) target_path Path(request_path) # 再次进行安全检查 try: target_path.relative_to(ALLOWED_ROOT) except ValueError: return mcp.ResourceContents( contents[mcp.TextContent(typetext, text错误请求的路径不在允许的范围内。)] ) if not target_path.exists(): return mcp.ResourceContents( contents[mcp.TextContent(typetext, textf错误路径不存在 {target_path})] ) # 生成目录树 tree_text generate_directory_tree(target_path) return mcp.ResourceContents( contents[mcp.TextContent(typetext, texttree_text)] ) else: raise ValueError(f不支持的资源URI模式: {uri}) def generate_directory_tree(path: Path, prefix: str ) - str: 递归生成目录树字符串 contents list(path.iterdir()) pointers [├── ] * (len(contents) - 1) [└── ] tree_str for pointer, content in zip(pointers, contents): tree_str prefix pointer content.name \n if content.is_dir(): extension │ if pointer ├── else tree_str generate_directory_tree(content, prefix extension) return tree_str这样配置后AI客户端就可以通过类似file-tree:///Users/me/projects/myapp的URI来请求获取该路径的文件树并将其作为上下文加载。AI在回答关于项目结构的问题时就能基于实时、准确的信息。5.2 集成第三方服务以搜索类Server为例网络热词中提到了tavily-mcp、brave-search-mcp这些都是将第三方搜索API封装成MCP Server的绝佳例子。其实现模式与我们本地搜索类似核心是调用外部API。核心步骤获取API密钥在Tavily或Brave Search官网注册并获取API Key。创建Tool定义一个如web_search的工具输入参数为query搜索词。实现调用逻辑在Tool的处理函数中使用requests或aiohttp库向搜索服务的API端点发送HTTP请求附带API Key。处理与返回解析API返回的JSON结果提取标题、链接、摘要等关键信息格式化成清晰的文本返回给AI。安全配置API Key不应硬编码在代码中。可以通过环境变量传入在Claude Desktop配置文件的env字段设置或让用户在首次使用时配置。一个简化的Tavily搜索工具实现框架import os import aiohttp import json TAVILY_API_KEY os.getenv(TAVILY_API_KEY) TAVILY_API_URL https://api.tavily.com/search async def handle_tavily_search(query: str) - list[mcp.TextContent]: if not TAVILY_API_KEY: return [mcp.TextContent(typetext, text错误未配置Tavily API密钥。)] params { api_key: TAVILY_API_KEY, query: query, max_results: 5 } async with aiohttp.ClientSession() as session: async with session.post(TAVILY_API_URL, jsonparams) as resp: if resp.status 200: data await resp.json() # 格式化结果 formatted_results [] for result in data.get(results, []): formatted_results.append(f- [{result[title]}]({result[url]}): {result[content]}) result_text f关于 {query} 的搜索结果\n \n.join(formatted_results) return [mcp.TextContent(typetext, textresult_text)] else: return [mcp.TextContent(typetext, textf搜索请求失败状态码{resp.status})]5.3 生态工具与调试技巧MCP Inspector前文提到的调试神器。它允许你单独运行MCP Server并与之交互可视化地测试所有Tools和Resources是开发阶段必不可少的工具。官方示例与SDKAnthropic的官方GitHub仓库modelcontextprotocol/servers提供了大量用不同语言编写的示例Server是学习的最佳资料。除了Pythonmcp库社区也有Node.js、Go、Rust等语言的SDK。社区Server市场随着MCP生态发展会出现一个汇集了各种功能Server的“市场”。用户可以根据需要像安装手机App一样轻松为AI助手添加天气预报、股票查询、智能家居控制等无数能力。6. 常见问题与排查技巧实录在实际开发和集成MCP的过程中我踩过不少坑。这里把一些典型问题和解决方法记录下来希望能帮你节省时间。6.1 Server连接失败或无法识别症状在Claude中询问可用工具AI回复说没有连接任何MCP Server或者配置后Claude直接启动失败。排查步骤检查配置文件语法JSON文件格式必须严格正确一个多余的逗号都会导致解析失败。使用在线的JSON校验工具检查你的claude_desktop_config.json。检查路径这是最常见的问题。确保command和args中的每一个路径都是绝对路径并且真实存在。特别是Python虚拟环境路径在Windows和macOS/Linux下差异很大。检查权限确保Claude Desktop应用有权限读取配置文件和执行你指定的命令/脚本。在macOS上如果脚本放在/usr/local等系统目录可能需要权限调整。查看客户端日志Claude Desktop通常有应用日志输出。在macOS上可以通过Console.app查看在Windows上查看事件查看器或Claude设置中的日志选项。日志会明确显示加载MCP配置时的错误信息例如“Cannot find module”或“Permission denied”。手动测试Server使用前面提到的test_client.py脚本或MCP Inspector先确认你的Server本身能独立正常运行能响应标准的MCP请求。6.2 工具调用无响应或返回错误症状AI列出了工具但在调用时长时间无反应或返回内部错误。排查步骤Server进程崩溃在Server代码中增加更详细的日志记录打印到stderr。在Claude Desktop配置中可以暂时将stderr重定向到一个文件以便查看Server运行时抛出的异常。args: [/path/to/python, /path/to/server.py, 2, /tmp/mcp_server.log]超时问题某些工具操作如网络请求、复杂计算可能耗时较长。MCP客户端可能有默认的超时设置。确保你的工具逻辑高效或实现异步非阻塞操作如使用asyncio。响应格式错误MCP对Tool和Resource的响应格式有严格规定。确保你返回的对象结构完全符合SDK的要求。使用MCP Inspector调试可以清晰地看到发送和接收的原始JSON消息便于比对。输入参数不匹配AI模型根据你定义的inputSchema来生成参数。如果Schema定义模糊或有歧义AI可能生成意料之外的参数导致你的处理函数出错。务必把Schema定义得尽可能精确并为所有参数提供清晰的description。6.3 性能与安全性考量问题当Resource内容非常大如整个代码库的文件树或者Tool执行非常耗时会影响AI响应的速度。应对策略分页与流式响应对于大型资源考虑实现分页机制。MCP协议支持通过range请求头进行部分内容读取。对于耗时Tool可以探索流式返回部分结果但这需要更高级的协议使用。结果摘要不要一次性返回成千上万行文本。在Server端对结果进行过滤、排序和摘要。例如文件搜索只返回前20个最相关的结果。缓存策略对于不常变动的资源如项目结构可以在Server端实现缓存避免每次请求都进行昂贵的磁盘遍历。安全边界这是重中之重。永远假设AI生成的输入可能是恶意的。必须对任何用户输入来自AI进行严格的验证、清理和权限检查。路径遍历防护像我们例子中一样使用pathlib.Path的relative_to方法确保所有文件操作都被限制在预设的沙箱目录内。命令注入防护如果你的Tool涉及执行系统命令如调用git绝对不要直接将用户输入拼接成命令。使用参数列表形式传递。资源消耗限制限制单个请求能读取的文件大小、遍历的目录深度或消耗的计算时间防止拒绝服务攻击。6.4 与其他概念的区别澄清网络热词中提到了Function Calling、Skill等概念容易与MCP混淆。MCP vs. Function CallingFunction Calling是OpenAI等模型提供的一种机制让模型可以“声明”它希望在对话中调用某个函数。MCP是Function Calling的“传输层”和“服务发现层”标准化。Function Calling定义了“调什么”MCP定义了“怎么找到这些可调用的函数”以及“如何与提供这些函数的服务安全通信”。MCP使得Function Calling的能力来源从封闭的插件市场变成了开放的、可自建的服务网络。MCP vs. Skill (如ReAct, LangChain Tools)Skill或Agent的Tool使用框架如LangChain Tools、AutoGPT的插件通常是一个应用层面的抽象它们定义了工具如何被AI智能体规划和调用。MCP可以看作是这些框架的后端协议标准。一个LangChain Agent可以使用MCP Client来连接和调用成千上万个标准化的MCP Server从而极大地扩展了其能力范围而无需为每个工具编写特定的集成代码。我个人在实际将多个工作流接入MCP的过程中最大的体会是“标准化带来的自由”。最初需要为每个AI平台适配不同接口的麻烦消失了现在只需要维护一个统一的MCP Server就能在Claude、Cursor、甚至是未来任何支持MCP的平台上使用。这种“一次编写到处运行”的体验对于提升开发效率和构建复杂的AI辅助工作流来说是一个巨大的飞跃。
返回列表