从零构建MCP天气查询工具:让AI Agent学会调用外部API
1. 从“智能体”到“工具人”为什么我们需要MCP最近和几个做AI应用的朋友聊天大家都有一个共同的感受大语言模型LLM本身很强大但让它真正“干活”的时候总感觉差点意思。比如你让它帮你查一下明天北京的天气它可能会给你一段非常逼真的、包含温度、湿度、风向的“虚构”回答因为它本质上是在根据训练数据中的模式“生成”文本而不是真的去调用一个实时的天气API。这种“一本正经地胡说八道”在需要精确、实时数据的场景下就成了致命伤。这就是AI Agent智能体要解决的核心问题之一让AI不仅会“想”还要会“做”。一个完整的Agent通常需要具备感知理解用户意图、规划拆解任务步骤、行动调用工具执行、反思评估结果并调整的能力。而“行动”这一步往往就是通过调用各种外部工具Tools来实现的比如搜索引擎、数据库、计算器或者我们今天要做的——天气API。那么如何让LLM知道有哪些工具可用以及如何规范地调用它们呢这就是Model Context ProtocolMCP登场的背景。你可以把MCP想象成AI世界的“USB标准”或者“驱动协议”。它为工具比如我们的天气查询服务和AI客户端比如Claude Desktop、Cursor等之间定义了一套标准的通信方式。工具开发者按照MCP的规范“写驱动”实现ServerAI客户端“插上就能用”实现Client无需为每个工具单独适配。所以写一个MCP天气查询工具绝不仅仅是调个API那么简单。它是一次绝佳的实践让你能亲手摸到AI Agent“行动层”的脉搏理解工具如何被标准化地集成到AI工作流中。接下来我们就从零开始拆解这个过程。2. 动手之前厘清MCP的核心概念与我们的目标在敲代码之前我们必须先搞清楚几个关键概念否则很容易在实现过程中迷失方向。MCP的架构其实非常清晰主要包含三个角色MCP Server工具提供方就是我们即将要写的这个天气查询服务。它的职责是向Client宣告“我这里有这些工具比如get_weather可用。”定义每个工具的“使用说明书”输入参数、输出格式。当Client发来调用请求时执行具体的业务逻辑调用天气API并返回结构化的结果。MCP ClientAI客户端比如Claude Desktop。它的职责是发现并连接Server。获取Server提供的工具列表及其定义。在LLM需要时代表LLM去调用合适的工具并将结果返回给LLM用于生成最终回答。Transport传输层Server和Client之间如何通信。MCP支持几种方式对于我们这个本地工具最常用的是stdio标准输入输出和sse服务器发送事件。stdio模式最简单我们的Server作为一个命令行进程启动Client启动这个进程并通过管道stdin/stdout与之交换JSON格式的消息。我们的项目目标很明确实现一个MCP Server它提供一个名为get_weather的工具接收城市名作为参数调用第三方天气API获取实时数据并以MCP规定的格式返回给Client。为了完成这个目标我们需要选择合适的编程语言和MCP SDK。由于MCP协议基于JSON-RPC理论上任何语言都能实现。但考虑到生态和便捷性Node.jsTypeScript和Python是目前最主流的选择官方和社区提供了成熟的SDK。这里我选择用TypeScript来演示因为它强大的类型系统能很好地匹配MCP的协议定义减少出错。提示如果你更熟悉Python完全可以使用mcp这个Python库整体思路和架构是完全相通的。3. 环境搭建与项目初始化从空白目录到类型安全的起点好了理论准备就绪我们开始动手。首先确保你的开发环境已经安装了Node.js建议版本18和npm/yarn/pnpm等包管理器。# 创建一个新的项目目录并进入 mkdir mcp-weather-server cd mcp-weather-server # 初始化npm项目一路回车或按需填写 npm init -y # 初始化TypeScript配置 npx tsc --init接下来安装我们核心的依赖包。我们将使用modelcontextprotocol/sdk这个官方SDK来快速构建Server。npm install modelcontextprotocol/sdk因为我们还需要调用外部HTTP API所以也安装一个流行的HTTP客户端库比如axios。npm install axios同时安装TypeScript相关的开发依赖用于编译和类型检查。npm install --save-dev typescript types/node ts-node现在打开tsconfig.json文件进行一些基本配置以确保编译顺利。以下是一个适用于本项目的简化配置{ compilerOptions: { target: ES2022, module: commonjs, lib: [ES2022], outDir: ./dist, rootDir: ./src, strict: true, esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, resolveJsonModule: true }, include: [src/**/*], exclude: [node_modules] }创建我们的源代码目录和入口文件mkdir src touch src/index.ts至此一个类型安全、结构清晰的MCP Server项目骨架就搭建好了。package.json里记录了依赖tsconfig.json指导TypeScript如何编译src/index.ts将是我们编写所有逻辑的地方。4. 构建MCP Server骨架连接、工具声明与生命周期让我们开始编写src/index.ts。首先导入必要的模块。import { Server } from modelcontextprotocol/sdk/server/index.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { CallToolRequestSchema, ListToolsRequestSchema, } from modelcontextprotocol/sdk/types.js; import axios from axios;接下来我们初始化MCP Server实例。需要给它起个名字并定义版本这些信息会告知Client。// 创建Server实例 const server new Server( { name: mcp-weather-server, version: 0.1.0, }, { capabilities: { tools: {}, // 声明本Server提供工具能力 }, } );Server创建好了但它现在还是个“哑巴”不知道如何与外界通信。我们需要为它创建一个“传输层”Transport。如前所述我们使用最简单的stdio方式。// 创建Stdio传输层 const transport new StdioServerTransport();现在我们需要告诉Server两件最重要的事当Client询问“你有什么工具”时如何回答。这通过处理listTools请求实现。当Client说“请使用某个工具并给我结果”时如何执行。这通过处理callTool请求实现。我们先处理listTools。这里我们定义了一个工具叫get_weather。// 处理工具列表请求 server.setRequestHandler(ListToolsRequestSchema, async () { return { tools: [ { name: get_weather, description: 获取指定城市的当前天气信息。, inputSchema: { type: object, properties: { city: { type: string, description: 城市名称例如Beijing, Shanghai, New York, }, }, required: [city], }, }, ], }; });这段代码是核心之一我们来拆解一下name: 工具的唯一标识符Client将通过这个名字来调用它。description: 工具的详细描述。这个描述极其重要因为LLM如Claude会阅读这个描述来决定在什么场景下使用这个工具。描述要清晰、准确。inputSchema: 定义了工具的输入参数格式遵循JSON Schema标准。type: object表示输入是一个对象。properties下定义了对象有哪些属性。这里我们只有一个属性city类型是字符串。required: [city]表示city参数是调用时必须提供的。接下来处理callTool请求。这是真正执行业务逻辑的地方。// 处理工具调用请求 server.setRequestHandler(CallToolRequestSchema, async (request) { // 1. 检查调用的工具名是否是我们提供的 if (request.params.name ! get_weather) { throw new Error(Unknown tool: ${request.params.name}); } // 2. 从请求参数中提取城市名 // 注意SDK已经根据inputSchema做了初步校验但这里我们仍要安全地提取 const args request.params.arguments as { city?: string }; const city args.city; if (!city || typeof city ! string) { throw new Error(The \city\ argument (string) is required.); } // 3. 这里是调用真实天气API的地方我们先返回一个模拟结果 // 稍后我们会替换成真实的API调用 const mockWeatherInfo 当前城市 ${city} 的天气模拟数据晴25°C湿度50%。; // 4. 按照MCP格式返回结果 return { content: [ { type: text, text: mockWeatherInfo, }, ], }; });最后我们需要启动Server让它开始监听来自Client的连接。// 启动Server连接传输层 async function runServer() { await server.connect(transport); console.error(MCP Weather Server running on stdio...); } runServer().catch((error) { console.error(Server error:, error); process.exit(1); });注意我们将日志输出到console.error标准错误因为stdio传输层将stdout用于协议通信普通的日志输出会干扰协议消息导致连接失败。这是一个非常关键的细节。现在一个最基础的、能响应协议请求的MCP Server骨架就完成了。它虽然返回的是模拟数据但已经具备了完整的MCP通信能力。我们可以先编译运行一下看看它是否能正常启动。# 编译TypeScript到dist目录 npx tsc # 运行编译后的JS文件 node dist/index.js运行后程序会挂起等待Client通过stdin连接。你可以按CtrlC终止。到目前为止我们成功搭建了MCP的“基础设施”。下一章我们将注入灵魂——接入真实的天气API。5. 接入真实数据源天气API的选择、调用与错误处理骨架有了现在需要让它真正“活”起来去获取真实的天气数据。这里有几个公开的天气API可供选择各有优劣API提供商免费额度/限制主要特点适用场景OpenWeatherMap60次/分钟1000次/天历史悠久数据全面文档详尽个人项目、学习演示WeatherAPI100万次/月免费额度极大无需信用卡需要大量调用的测试、原型和风天气开发者免费版有限额中文支持好国内访问快主要面向国内用户的项目心知天气有免费套餐国内服务稳定可靠商业项目初期的国内数据源为了演示的通用性我们选择OpenWeatherMap。首先你需要去其官网openweathermap.org注册一个免费账户然后在控制台获取你的API Key。这个Key是调用API的凭证务必妥善保管不要直接硬编码在代码里提交到公开仓库。我们将使用环境变量来管理这个敏感信息。在项目根目录创建一个.env文件OPENWEATHER_API_KEY你的_Api_Key_在这里然后安装dotenv包来在开发时加载环境变量。npm install dotenv现在我们来改造src/index.ts中的工具调用处理器用真实的API调用替换模拟数据。首先在文件顶部导入dotenv并配置。import * as dotenv from dotenv; dotenv.config(); // 加载 .env 文件中的环境变量 const OPENWEATHER_API_KEY process.env.OPENWEATHER_API_KEY; if (!OPENWEATHER_API_KEY) { console.error(错误未设置 OPENWEATHER_API_KEY 环境变量。请在 .env 文件中配置。); process.exit(1); }接下来我们编写一个专门的函数fetchWeatherFromOpenWeather来处理API调用。这里会涉及几个重要的实践点参数处理、错误处理和结果解析。async function fetchWeatherFromOpenWeather(city: string): Promisestring { // 1. 构造API请求URL // 使用“按城市名查询”的端点unitsmetric表示使用摄氏度 const url https://api.openweathermap.org/data/2.5/weather; try { const response await axios.get(url, { params: { q: city, appid: OPENWEATHER_API_KEY, units: metric, // 公制单位得到摄氏度 lang: zh_cn, // 返回中文描述 }, timeout: 10000, // 设置10秒超时避免长时间等待 }); const data response.data; // 2. 解析API返回的复杂JSON提取我们需要的信息 // OpenWeatherMap返回的数据结构很丰富我们取核心部分 const cityName data.name; const country data.sys.country; const temp data.main.temp; const feelsLike data.main.feels_like; const humidity data.main.humidity; const description data.weather[0].description; const windSpeed data.wind.speed; // 3. 格式化成对人类和AI都友好的文本 const weatherText 城市${cityName}, ${country} 天气状况${description} 温度${temp}°C (体感 ${feelsLike}°C) 湿度${humidity}% 风速${windSpeed} m/s 数据来源OpenWeatherMap; return weatherText; } catch (error: any) { // 4. 细致的错误处理给Client明确的反馈 console.error(调用天气API失败 (城市: ${city}):, error.message); if (axios.isAxiosError(error)) { // 如果是Axios错误网络或HTTP错误 if (error.response) { // 服务器返回了错误状态码 const status error.response.status; if (status 401) { throw new Error(天气服务认证失败请检查API Key。); } else if (status 404) { throw new Error(未找到城市“${city}”请检查城市名拼写。); } else if (status 429) { throw new Error(天气服务请求过于频繁请稍后再试。); } else { throw new Error(天气服务返回错误 (状态码: ${status})。); } } else if (error.request) { // 请求已发出但没有收到响应 throw new Error(无法连接到天气服务请检查网络。); } else { // 请求配置出错 throw new Error(请求配置错误: ${error.message}); } } else { // 非Axios错误 throw new Error(获取天气数据时发生未知错误: ${error.message}); } } }这个函数体现了生产级代码的几个关键考虑参数国际化我们传递了units‘metric’和lang‘zh_cn’让返回的数据更符合中文用户习惯。超时控制设置了timeout防止网络不佳时无限期等待。结构化解析从API返回的嵌套JSON中精准提取所需字段。友好的结果格式化将数据组织成清晰的多行文本便于LLM理解和用户阅读。全面的错误处理区分了认证失败、城市未找到、限流、网络问题等不同情况并抛出带有明确提示信息的错误。这些错误信息最终会通过MCP协议返回给Client和LLM让用户知道问题出在哪里而不是得到一个笼统的“调用失败”。现在我们修改callTool的处理器调用这个真实的函数。server.setRequestHandler(CallToolRequestSchema, async (request) { if (request.params.name ! get_weather) { throw new Error(Unknown tool: ${request.params.name}); } const args request.params.arguments as { city?: string }; const city args.city; if (!city || typeof city ! string) { throw new Error(The \city\ argument (string) is required.); } // 调用真实的天气API函数 try { const weatherText await fetchWeatherFromOpenWeather(city); return { content: [ { type: text, text: weatherText, }, ], }; } catch (error: any) { // 捕获fetchWeatherFromOpenWeather抛出的错误并返回给Client return { content: [ { type: text, text: 获取天气信息失败${error.message}, }, ], isError: true, // MCP协议中标记这是一个错误响应 }; } });至此一个功能完整、具备错误恢复能力的MCP天气查询工具Server就实现了。重新编译运行它已经可以处理真实的查询了。不过我们还需要一个Client来测试它。在下一章我们将介绍如何配置流行的AI客户端如Claude Desktop来连接和使用我们这个自定义Server。6. 集成与测试让Claude Desktop“认识”你的工具我们的Server已经就绪但它现在还是一个独立的进程。如何让像Claude Desktop这样的AI客户端发现并使用它呢这就需要通过客户端的配置来实现。以Claude Desktop为例它支持通过配置文件来声明本地的MCP Server。配置文件通常位于以下位置macOS:~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:%APPDATA%\Claude\claude_desktop_config.jsonLinux:~/.config/Claude/claude_desktop_config.json如果文件不存在你可以创建它。我们需要在这个JSON配置文件中添加一个mcpServers字段。下面是一个配置示例{ mcpServers: { weather: { command: node, args: [ /ABSOLUTE/PATH/TO/YOUR/mcp-weather-server/dist/index.js ], env: { OPENWEATHER_API_KEY: 你的_Api_Key_在这里 } } } }配置详解与避坑指南command: 启动Server的命令。我们的是node。args: 传递给命令的参数。这里必须是编译后的JS文件的绝对路径。使用相对路径如./dist/index.js大概率会失败因为Claude Desktop的工作目录不确定。如何获取绝对路径在终端中进入你的项目目录运行pwdLinux/macOS或cdWindows获取当前绝对路径然后拼接上/dist/index.js。env: 设置环境变量。我们将API Key直接写在这里。注意这不如.env文件安全但对于本地测试是方便的。更安全的方式是让Server从系统的环境变量中读取但这需要你预先在系统层面设置好。注意修改配置文件后必须完全重启Claude Desktop应用退出再重新打开配置才会生效。重启Claude Desktop后当你新建一个对话时Claude应该就能识别到我们注册的weather服务器了。你可以通过以下方式验证在输入框里Claude可能会自动提示它可用的工具。或者你可以直接问“你能查天气吗” Claude应该会回复它有一个get_weather工具并询问你要查哪个城市。进行测试输入“请帮我查一下北京的天气。”Claude会理解你的意图在后台调用我们的get_weather工具参数city设为Beijing。我们的Server收到请求调用OpenWeatherMap API。Server将格式化后的天气文本返回给Claude。Claude结合这个工具返回的结果组织成一段自然的对话回复给你。如果一切顺利你将看到Claude返回了真实的北京天气信息。如果失败请按以下步骤排查检查Claude Desktop日志Claude Desktop通常有输出日志的地方如macOS的控制台应用查看是否有关于启动MCP Server的错误信息。检查Server启动在配置中可以暂时在args里加上-e console.error(Server starting...)之类的看日志是否有输出确认命令是否被执行。检查API Key和环境变量确保在配置的env里或系统的环境变量中OPENWEATHER_API_KEY设置正确且有效。手动测试Server你可以写一个简单的测试脚本模拟Client通过stdio调用你的Server来隔离问题。7. 进阶优化与扩展思路从“能用”到“好用”一个基础的MCP工具已经跑通了但要想让它更健壮、更实用我们还可以做很多优化。7.1 输入验证与清洗目前的工具只要求一个city字符串。但用户输入可能是“中国北京”、“Beijing, China”或“beijing”。虽然OpenWeatherMap的API有一定容错能力但我们可以在Server端做一层预处理。// 在调用API前可以添加一个清洗函数 function normalizeCityInput(rawInput: string): string { // 移除多余空格提取可能的核心城市名简单示例 let cleaned rawInput.trim(); // 可以添加更多规则比如处理“北京市”-“Beijing” // 这里只是一个简单示例实际可能需要更复杂的映射或地理编码服务 return cleaned; } // 在callTool处理器中使用 const city normalizeCityInput(args.city);7.2 结果缓存天气数据变化相对较慢频繁查询同一城市会造成不必要的API调用消耗免费额度。可以引入一个简单的内存缓存。const weatherCache new Mapstring, { data: string; timestamp: number }(); const CACHE_TTL_MS 10 * 60 * 1000; // 缓存10分钟 async function fetchWeatherWithCache(city: string): Promisestring { const normalizedCity normalizeCityInput(city); const cached weatherCache.get(normalizedCity); if (cached (Date.now() - cached.timestamp) CACHE_TTL_MS) { console.error([Cache Hit] 返回 ${normalizedCity} 的缓存天气数据); return cached.data; } console.error([Cache Miss] 查询 ${normalizedCity} 的实时天气); const freshData await fetchWeatherFromOpenWeather(normalizedCity); weatherCache.set(normalizedCity, { data: freshData, timestamp: Date.now() }); return freshData; }7.3 支持更多功能一个工具可以定义多个“子功能”。我们可以扩展我们的工具比如增加get_weather_forecast天气预报或get_air_quality空气质量。只需要在listTools中返回多个工具定义并在callTool中根据request.params.name进行分支处理即可。7.4 结构化输出目前我们返回的是纯文本type: ‘text’。MCP协议还支持更丰富的类型比如image或resource。虽然天气数据不适合图片但我们可以考虑返回部分结构化数据方便Client进行二次处理。不过对于LLM来说清晰的文本通常就是最好的输入。7.5 日志与监控在生产环境中需要记录工具的使用情况、API调用成功率、耗时等。可以在Server中集成简单的日志库如winston或pino将日志输出到文件或标准错误。import winston from winston; const logger winston.createLogger({ level: info, format: winston.format.json(), transports: [ new winston.transports.File({ filename: mcp-weather-server.log }), new winston.transports.Console({ format: winston.format.simple() }) ], }); // 在工具调用和API调用处添加日志 logger.info(Tool called, { tool: get_weather, city: city });通过以上这些优化你的MCP工具就从一个小实验进化成了一个更可靠、更高效的“生产就绪”组件。这个过程也是大多数AI Agent工具开发的缩影先跑通核心流程再围绕稳定性、性能和用户体验不断打磨。

相关新闻

PCB打样怎么最省钱?这5招亲测有效

PCB打样怎么最省钱?这5招亲测有效

硬件研发过程中,PCB 打样属于高频支出,不少工程师会遇到功能简单的板子报价却居高不下的情况。很多人第一反应是更换供应商压价,却忽略 80% 的成本问题根源来自设计端,不合理的层数堆叠、盲目选用高端板材,直接推高打样…

2026/9/25 17:21:58 阅读更多 →
找不到MSVCP140.dll怎么办?软领驱动大师辅助排查并给出4种修复方法

找不到MSVCP140.dll怎么办?软领驱动大师辅助排查并给出4种修复方法

在使用第三方软件、游戏或一些专业工具时,弹窗提示“找不到 MSVCP140.dll”是挺常见的情况。这个文件属于 Microsoft Visual C Redistributable 运行库,很多程序启动时会调用它。如果 DLL 文件损坏、缺失或被安全软件拦截,程序就会拒绝启动。…

2026/9/24 13:17:10 阅读更多 →
YOLOv8目标检测实战:从数据标注到模型部署全流程详解

YOLOv8目标检测实战:从数据标注到模型部署全流程详解

1. 项目概述:为什么现在还要学YOLOv8?目标检测,这个听起来有点学术的词,其实离我们很近。想象一下,你手机相册里自动识别人脸和宠物的功能,或者停车场入口自动识别车牌的系统,背后都是目标检测技…

2026/9/24 1:57:29 阅读更多 →

最新新闻

扒了下 Cursor 的提示词,被狠狠惊艳到了!——用 TaoToken 统一 Key 复现同款 Agent 配置

扒了下 Cursor 的提示词,被狠狠惊艳到了!——用 TaoToken 统一 Key 复现同款 Agent 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 17:21:38 阅读更多 →
GPT Image Playground 预置配置 JSON 完全参考:3 种方式为团队批量注入 AI 绘图配置

GPT Image Playground 预置配置 JSON 完全参考:3 种方式为团队批量注入 AI 绘图配置

GPT Image Playground 预置配置 JSON 完全参考:3 种方式为团队批量注入 AI 绘图配置 【免费下载链接】gpt_image_playground 基于 OpenAI gpt-image-2.5 API 的图片生成与编辑工具 项目地址: https://gitcode.com/gh_mirrors/gp/gpt_image_playground GPT Im…

2026/9/25 17:21:38 阅读更多 →
数据库系统概论课设完整资源:从ER图到SQL脚本的跑通全流程

数据库系统概论课设完整资源:从ER图到SQL脚本的跑通全流程

简介:《山东科技大学数据库系统概论课程设计》配套资源包,主要面向高校数据库初学者及需要完成课程设计的学生。资源围绕数据库最基本的建表与改表操作展开,涵盖字段名、字段类型、字段长度、空值约束等核心概念,以及需求变化时新…

2026/9/25 17:21:38 阅读更多 →
MySQL MGR高可用集群实战:从主从复制到自动故障转移

MySQL MGR高可用集群实战:从主从复制到自动故障转移

MySQL 主从复制是很多团队的高可用底线,但用过的人都清楚,“底线”和“天花板”是两回事。手动切换、从库延迟、丢数据,任何一个都够你在凌晨两点的电话里崩溃。我这次要聊的,是一套我在生产环境完整落地过的 MySQL MGR 高可用集群…

2026/9/25 17:21:38 阅读更多 →
从表格到在线CRM:小团队客户管理系统落地全攻略

从表格到在线CRM:小团队客户管理系统落地全攻略

第一次意识到“客户管理”必须换一种做法,是在一个周五晚上九点。团队七个人,六个正在跟进的客户分散在四张Excel表、两个聊天记录置顶会话和我的个人备忘录里,结果同一位客户被两个同事分别跟进,报价还报出了两个数——客户当场发…

2026/9/25 17:21:38 阅读更多 →
10-除了 ConcurrentHashMap,这些并发容器和阻塞队列也该会

10-除了 ConcurrentHashMap,这些并发容器和阻塞队列也该会

生产者消费者模型离不了阻塞队列,读多写少场景 CopyOnWrite 比加锁香,高频插入用无锁队列更猛。这一篇把 JUC 里常用的并发容器和阻塞队列全家桶补齐,让你在合适场景直接掏出对的那个,而不是无脑 synchronized 一把锁。 一、为什么…

2026/9/25 17:20:37 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →