基于.NET 8与MCP协议构建智能体:实战Agent框架与工具集成
在实际 AI 应用开发中构建一个能够理解复杂指令、调用外部工具并完成特定任务的智能体Agent正从前沿探索走向工程实践。传统的单一模型调用模式在面对需要多步骤推理、动态工具选择和状态管理的场景时显得力不从心。Agent 框架的出现旨在为这类复杂智能应用提供一套标准化的开发范式而模型上下文协议Model Context Protocol, MCP则为智能体安全、高效地接入外部工具和数据源提供了统一接口。结合 .NET 生态的稳健性和高性能开发者可以构建出既智能又可靠的企业级应用。本文将以一个具体的实战项目为例带你从零开始基于主流的 Agent 框架、MCP 协议和 .NET 8 平台构建一个具备联网搜索和代码执行能力的智能体。我们将深入理解 Agent 的工作流、MCP 服务器的实现原理并完成一个可运行、可验证的完整案例。无论你是希望将 AI 能力集成到现有 .NET 系统中的开发者还是对智能体架构感兴趣的工程师都能通过本文获得一套可直接复现的工程方案。1. 理解智能体Agent的核心架构与 MCP 协议在深入代码之前必须厘清几个核心概念什么是 Agent 框架MCP 协议解决了什么问题以及 .NET 在其中扮演何种角色。1.1 Agent 框架超越简单模型调用一个智能体Agent通常不是指单个大语言模型LLM而是一个由 LLM 作为“大脑”驱动的系统。这个系统包含几个关键组件规划器Planner解析用户意图将复杂任务分解为可执行的子步骤序列。工具Tools智能体可以调用的外部函数例如搜索网络、查询数据库、执行代码、调用 API 等。这是智能体与外界交互、获取实时信息或执行操作的关键。记忆Memory存储对话历史、工具执行结果和中间状态为后续决策提供上下文。执行引擎Execution Engine协调整个流程根据规划调用工具处理工具返回结果并决定下一步行动继续、重试或结束。Agent 框架如 Semantic Kernel, LangChain, AutoGen 等封装了这些组件的通用模式让开发者无需从零构建任务调度、状态管理和工具调用的复杂逻辑。1.2 MCP 协议标准化工具与数据接入模型上下文协议Model Context Protocol, MCP是一个开放协议它定义了一套标准使得任何兼容 MCP 的客户端如 AI 应用、Agent 框架能够以统一的方式发现、描述和调用来自不同服务器提供的工具和资源。它的核心价值在于解耦与安全解耦工具提供者如一个内部数据库服务、一个计算服务只需实现一个 MCP 服务器任何支持 MCP 的客户端就能立即使用这些工具无需为每个客户端编写特定的集成代码。安全MCP 服务器运行在独立的进程中甚至独立的机器上。客户端通过进程间通信如 stdio或网络与服务器交互。这意味着敏感的数据源如生产数据库或危险的操作如 shell 命令可以被隔离在受控的服务器环境中客户端只能通过定义良好的协议接口进行有限度的访问大大提升了系统安全性。1.3 .NET 生态的定位.NET特别是最新的 .NET 8为构建此类 AI 应用提供了强大的基础设施高性能运行时对于需要处理大量数据或高并发请求的 Agent 后端服务.NET 的性能优势明显。丰富的库支持通过Microsoft.SemanticKernel等官方库可以便捷地集成 Azure OpenAI 或 OpenAI 的模型并构建 Agent。成熟的工程化能力依赖注入、配置管理、日志记录、健康检查等 .NET 原生特性使得构建稳定、可维护的生产级 AI 应用更加容易。跨平台开发的智能体服务可以运行在 Windows、Linux 或 macOS 上。在本项目中我们将使用Semantic Kernel作为 Agent 框架因为它与 .NET 生态集成最紧密并且官方支持 MCP。我们将分别构建一个 MCP 服务器提供工具和一个 .NET 控制台应用作为 Agent 客户端。2. 环境准备与项目初始化开始编码前需要确保本地开发环境就绪并创建项目结构。2.1 开发环境要求请确保你的机器上已安装以下软件组件版本要求说明.NET SDK8.0 或更高用于构建和运行 .NET 应用程序。IDE / 编辑器Visual Studio 2022 / VS Code推荐使用 Visual Studio 或安装 C# 插件的 VS Code。OpenAI API 密钥-用于调用 GPT 模型。你也可以使用 Azure OpenAI 端点。打开终端使用以下命令验证 .NET 环境dotnet --version预期应输出8.0.x或更高版本。2.2 创建解决方案与项目我们将创建一个解决方案包含两个项目一个 MCP 服务器项目和一个智能体客户端项目。# 创建解决方案目录并进入 mkdir McpAgentDemo cd McpAgentDemo # 创建解决方案文件 dotnet new sln -n McpAgentDemo # 创建 MCP 服务器项目类库 dotnet new classlib -n McpDemo.Server dotnet sln add McpDemo.Server/McpDemo.Server.csproj # 创建智能体客户端项目控制台应用 dotnet new console -n McpDemo.Agent dotnet sln add McpDemo.Agent/McpDemo.Agent.csproj # 为客户端项目添加对服务器项目的引用可选仅为代码共享 dotnet add McpDemo.Agent reference McpDemo.Server2.3 安装必要的 NuGet 包我们需要为两个项目分别安装核心依赖。对于 MCP 服务器项目 (McpDemo.Server)进入McpDemo.Server目录安装 MCP 协议的基础包。cd McpDemo.Server dotnet add package ModelContextProtocol.Server --version 1.0.0-preview.3注意MCP 相关包可能处于预览版版本号请以 NuGet 上的最新稳定版或预览版为准。对于智能体客户端项目 (McpDemo.Agent)进入McpDemo.Agent目录安装 Semantic Kernel 和 MCP 客户端包。cd ../McpDemo.Agent dotnet add package Microsoft.SemanticKernel --version 1.13.0 dotnet add package Microsoft.SemanticKernel.Agents.Core --version 1.13.0-alpha dotnet add package ModelContextProtocol.Transport.Stdio --version 1.0.0-preview.3 dotnet add package ModelContextProtocol.SemanticKernel --version 1.0.0-preview.3注意Agents.Core包在撰写本文时可能仍为 Alpha 版本用于提供最新的 Agent 抽象。请根据 Semantic Kernel 的官方发布情况调整。安装完成后建议运行dotnet restore确保所有依赖正确解析。3. 实现 MCP 服务器提供工具能力MCP 服务器的核心是声明一系列Tool工具并实现其执行逻辑。我们将创建一个提供“计算器”和“获取当前时间”两个简单工具的服务器。3.1 定义工具接口在McpDemo.Server项目中创建一个新的 C# 类文件CalculatorTool.cs。// McpDemo.Server/CalculatorTool.cs using System.Text.Json.Serialization; using ModelContextProtocol.Server; namespace McpDemo.Server; // 工具输入参数的强类型定义 public class CalculatorInput { [JsonPropertyName(a)] public double A { get; set; } [JsonPropertyName(b)] public double B { get; set; } [JsonPropertyName(operation)] public string Operation { get; set; } ; // 默认加法 } // 工具本身的实现类继承自 McpTool public class CalculatorTool : McpToolCalculatorInput, string { // 工具名称客户端将通过此名称调用 public override string Name calculator; // 工具描述用于帮助 LLM 理解工具的用途 public override string Description Performs basic arithmetic operations (add, subtract, multiply, divide) on two numbers.; // 工具的执行逻辑 protected override Taskstring ExecuteAsync(CalculatorInput input, CancellationToken cancellationToken) { double result; switch (input.Operation) { case : result input.A input.B; break; case -: result input.A - input.B; break; case *: result input.A * input.B; break; case /: if (input.B 0) { throw new ArgumentException(Division by zero is not allowed.); } result input.A / input.B; break; default: throw new ArgumentException($Unsupported operation: {input.Operation}); } return Task.FromResult($The result of {input.A} {input.Operation} {input.B} is {result}.); } }再创建一个GetCurrentTimeTool.cs文件。// McpDemo.Server/GetCurrentTimeTool.cs using ModelContextProtocol.Server; namespace McpDemo.Server; // 此工具无需输入参数使用 McpToolWithoutInput 基类 public class GetCurrentTimeTool : McpToolWithoutInputstring { public override string Name get_current_time; public override string Description Gets the current date and time in UTC.; protected override Taskstring ExecuteAsync(CancellationToken cancellationToken) { return Task.FromResult($The current UTC time is: {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss}); } }3.2 创建服务器入口点修改McpDemo.Server项目中的Program.cs文件如果不存在则创建。这是服务器的启动入口。// McpDemo.Server/Program.cs using ModelContextProtocol.Server; using McpDemo.Server; // 1. 创建 MCP 服务器构建器 var builder McpServerBuilder.Create(); // 2. 注册我们定义的工具 builder.AddToolCalculatorTool(); builder.AddToolGetCurrentTimeTool(); // 3. 构建服务器 var server builder.Build(); // 4. 运行服务器使用标准输入输出作为传输层。 // 这是 MCP 的典型用法客户端将启动此进程并通过管道通信。 await server.RunAsync();这个服务器现在可以通过标准输入输出stdio与客户端通信。当客户端请求调用calculator或get_current_time工具时服务器会执行相应的ExecuteAsync方法并返回结果。3.3 生成服务器可执行文件在McpDemo.Server目录下发布项目为一个独立可执行文件方便客户端调用。dotnet publish -c Release -r win-x64 --self-contained true /p:PublishSingleFiletrue-r win-x64: 指定目标运行时为 Windows x64。如果是 Linux可改为linux-x64macOS 可改为osx-x64。--self-contained true: 包含 .NET 运行时使得生成的可执行文件无需在目标机器安装 .NET 即可运行。/p:PublishSingleFiletrue: 打包成单个可执行文件。发布完成后在bin/Release/net8.0/win-x64/publish目录下会找到McpDemo.Server.exeWindows或McpDemo.ServerLinux/macOS。记下这个路径稍后客户端需要启动它。4. 构建智能体客户端集成 MCP 与 Semantic Kernel客户端负责启动 MCP 服务器进程加载其提供的工具并利用 Semantic Kernel 构建一个能够使用这些工具的智能体。4.1 配置 MCP 服务器连接在McpDemo.Agent项目中首先需要配置如何连接到我们刚刚构建的 MCP 服务器。修改Program.cs。// McpDemo.Agent/Program.cs using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.Chat; using ModelContextProtocol.SemanticKernel; using ModelContextProtocol.Transport.Stdio; // 请替换为你的 OpenAI API 密钥和端点 string apiKey your-openai-api-key; string modelId gpt-4o-mini; // 或 gpt-4-turbo, gpt-3.5-turbo string endpoint https://api.openai.com/v1/chat/completions; // Azure OpenAI 用户需更换 // 1. 创建 Semantic Kernel 内核 var kernel Kernel.CreateBuilder() .AddOpenAIChatCompletion(modelId, apiKey, endpoint: endpoint) .Build(); // 2. 创建 MCP 客户端配置指定服务器可执行文件路径 // 注意你需要将路径替换为实际发布的可执行文件路径 var serverPath C:\path\to\your\McpDemo.Server.exe; // Windows 示例 // var serverPath /home/user/path/to/McpDemo.Server; // Linux 示例 var mcpClientConfig new StdioMcpClientConfig(serverPath); var mcpClient new StdioMcpClient(mcpClientConfig); // 3. 从 MCP 服务器加载工具到 Kernel var mcpToolKernelPlugin await kernel.ImportMcpToolsAsync(mcpClient); Console.WriteLine($Loaded tools from MCP server: {string.Join(, , mcpToolKernelPlugin.Select(t t.Name))});关键点解释StdioMcpClientConfig: 配置了 MCP 服务器的启动方式这里是通过标准输入输出启动一个本地进程。StdioMcpClient: 是 MCP 协议的客户端实现负责与服务器进程通信。ImportMcpToolsAsync: 这是 Semantic Kernel 的扩展方法它会向 MCP 服务器请求工具列表并将这些工具转换为 Kernel 可以识别的KernelFunction封装成一个KernelPlugin。之后Agent 就可以像调用普通 Kernel 函数一样调用这些工具。4.2 创建并运行智能体接下来我们使用 Semantic Kernel 的 Agents 抽象来创建一个简单的聊天智能体。// 接上一段代码 // 4. 创建一个使用这些工具的智能体 var agent new ChatCompletionAgent( name: MathAndTimeAssistant, instructions: 你是一个乐于助人的助手擅长数学计算和提供时间信息。 当用户需要计算时请使用 calculator 工具。 当用户询问时间时请使用 get_current_time 工具。 如果用户的问题不涉及这些请直接基于你的知识回答。 请清晰、有条理地回复。 , kernel: kernel // 内核中已包含从 MCP 加载的工具 ); // 5. 创建代理聊天线程并开始交互 var thread new AgentGroupChat([agent]); var chatHistory thread.AddUserMessage(请计算一下 125 乘以 48 等于多少); try { // 执行聊天Agent 会自动决定是否以及何时调用工具 await foreach (var message in thread.InvokeAsync()) { Console.WriteLine($[{message.Sender?.Name ?? System}]: {message.Content}); } } catch (Exception ex) { Console.WriteLine($Error during agent execution: {ex.Message}); }运行这段代码智能体会分析用户消息“请计算一下 125 乘以 48 等于多少”识别出这是一个计算任务然后自动调用calculator工具传入a125, b48, operation*获取工具返回的结果最后组织成自然语言回复给用户。4.3 完整客户端程序示例将以上步骤整合并添加一些交互逻辑形成一个完整的演示程序。// McpDemo.Agent/Program.cs (完整版) using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Agents; using Microsoft.SemanticKernel.Agents.Chat; using ModelContextProtocol.SemanticKernel; using ModelContextProtocol.Transport.Stdio; // 配置 var config new { OpenAIApiKey your-api-key-here, ModelId gpt-4o-mini, Endpoint https://api.openai.com/v1/chat/completions, McpServerPath C:\Dev\McpAgentDemo\McpDemo.Server\bin\Release\net8.0\win-x64\publish\McpDemo.Server.exe }; // 初始化 Kernel 和 MCP 客户端 var kernel Kernel.CreateBuilder() .AddOpenAIChatCompletion(config.ModelId, config.OpenAIApiKey, endpoint: config.Endpoint) .Build(); var mcpClientConfig new StdioMcpClientConfig(config.McpServerPath); var mcpClient new StdioMcpClient(mcpClientConfig); Console.WriteLine(正在连接 MCP 服务器并加载工具...); var mcpPlugin await kernel.ImportMcpToolsAsync(mcpClient); Console.WriteLine($工具加载成功: {string.Join(, , mcpPlugin.Select(t t.Name))}); // 创建智能体 var agent new ChatCompletionAgent( name: Assistant, instructions: 你是一个助手可以帮用户进行数学计算和查询当前时间。请根据需要使用相应的工具。, kernel: kernel ); var thread new AgentGroupChat([agent]); Console.WriteLine(\n智能体已就绪。输入您的问题输入 exit 退出:\n); // 交互循环 while (true) { Console.Write(用户: ); var userInput Console.ReadLine(); if (string.IsNullOrWhiteSpace(userInput) || userInput.Equals(exit, StringComparison.OrdinalIgnoreCase)) { break; } thread.AddUserMessage(userInput); Console.Write(助手: ); try { string fullResponse ; await foreach (var message in thread.InvokeAsync()) { if (message.Sender is ChatCompletionAgent) { // 流式输出 Agent 的回复 Console.Write(message.Content); fullResponse message.Content; } } Console.WriteLine(); // 换行 } catch (Exception ex) { Console.WriteLine($\n[系统错误] {ex.Message}); } }5. 运行验证与结果分析现在让我们运行整个系统观察智能体如何工作。5.1 启动与验证步骤构建并发布 MCP 服务器确保已按照 3.3 节的命令成功发布McpDemo.Server。配置客户端在McpDemo.Agent的Program.cs中正确设置OpenAIApiKey、ModelId和McpServerPath。运行客户端在终端中导航到McpDemo.Agent项目目录执行dotnet run观察输出程序启动后你应该看到类似以下的日志表明 MCP 服务器连接成功工具已加载正在连接 MCP 服务器并加载工具... 工具加载成功: calculator, get_current_time 智能体已就绪。输入您的问题输入 exit 退出5.2 测试用例与预期结果输入不同的指令验证智能体的行为用户输入预期行为与输出关键特征计算 98 加上 17 等于多少Agent 应识别计算意图调用calculator工具并返回 “The result of 98 17 is 115.” 或类似表述。现在几点了Agent 应识别时间查询意图调用get_current_time工具并返回包含当前 UTC 时间的句子。请介绍一下你自己。Agent 应识别此问题无需工具直接利用 LLM 的知识生成自我介绍。先计算 12*5再告诉我现在的时间。Agent 应进行规划先调用计算工具再调用时间工具最后将两个结果整合成连贯回复。5.3 深入分析执行流程通过在上述客户端代码的关键位置添加日志或在支持 SK 日志记录的情况下运行可以清晰地看到 Agent 的思考与执行链接收用户消息“计算 98 加上 17 等于多少”LLM 规划Agent 内部的 LLM 分析消息判断需要调用calculator工具并生成符合工具输入格式的参数 JSON{a: 98, b: 17, operation: }。工具调用Semantic Kernel 通过 MCP 客户端将调用请求发送给 MCP 服务器进程。服务器执行MCP 服务器收到请求找到CalculatorTool执行ExecuteAsync方法计算9817得到115。返回结果服务器将结果字符串“The result of 98 17 is 115.”通过 MCP 协议返回给客户端。结果处理客户端将工具执行结果作为上下文再次交给 LLM。生成最终回复LLM 结合原始问题和工具结果生成面向用户的自然语言回复如“98 加上 17 等于 115。”。这个流程完美诠释了 Agent 的“思考-行动-观察”循环。6. 常见问题排查在实际运行中你可能会遇到以下问题。这里提供排查路径。6.1 MCP 服务器连接失败现象客户端启动时卡在“正在连接 MCP 服务器...”或抛出异常提示无法启动进程或通信失败。排查步骤检查路径确认McpServerPath变量指向的确实是发布后的可执行文件而不是 DLL 或项目目录。检查文件权限确保当前运行客户端程序的用户有权限执行该服务器文件。手动测试服务器尝试在终端中直接运行服务器可执行文件。它应该启动并等待标准输入可能没有输出。如果能正常启动说明服务器本身无问题。检查依赖如果发布时未使用--self-contained请确保运行客户端的环境已安装对应版本的 .NET 运行时。查看异常信息捕获并打印ImportMcpToolsAsync或StdioMcpClient初始化时的异常详细信息通常包含操作系统级别的错误码。6.2 工具加载成功但调用失败现象客户端启动时显示工具已加载但用户提问后Agent 报错或无法正确调用工具。排查步骤检查工具描述确保 MCP 服务器中工具类的Name和Description属性清晰明确。模糊的描述可能导致 LLM 无法正确匹配用户意图。查看内核日志启用 Semantic Kernel 的日志记录查看 LLM 生成的规划步骤和工具调用参数是否正确。// 在 KernelBuilder 后添加 builder.Services.AddLogging(c c.AddConsole().SetMinimumLevel(LogLevel.Debug));验证参数格式检查 LLM 生成的工具调用参数 JSON 是否完全符合CalculatorInput类的定义。类型不匹配如字符串传给数字会导致服务器端反序列化失败。服务器端日志在 MCP 服务器的ExecuteAsync方法中添加Console.WriteLine输出观察调用是否到达以及参数值。6.3 Agent 不调用工具直接回答现象对于明显应该使用工具的问题如“123*456”Agent 却尝试直接计算并给出一个可能错误的答案。排查步骤强化指令Instructions检查创建ChatCompletionAgent时的instructions参数。指令必须清晰、强制性地要求 Agent 在特定场景下使用工具。可以像示例中那样明确写出“当用户需要计算时请使用 calculator 工具。”检查工具描述工具描述 (Description) 需要让 LLM 能准确理解其能力边界。例如“Performs basic arithmetic operations” 就比 “A tool” 好得多。使用更强大的模型如果使用gpt-3.5-turbo对于复杂或隐含的工具调用场景其规划能力可能不如gpt-4或gpt-4o系列。尝试升级模型。提供少量示例Few-shot在instructions中可以加入一两个用户提问和正确调用工具的示例引导模型学习调用模式。6.4 性能与超时问题现象响应缓慢或出现超时错误。排查步骤网络延迟如果使用远程 OpenAI/Azure OpenAI 端点网络延迟是主要因素。考虑使用地理位置更近的端点。工具执行耗时检查 MCP 服务器中工具的执行逻辑。如果工具需要访问网络或进行复杂计算可能导致超时。需要在工具实现中加入超时控制和优化。MCP 通信开销进程间通信stdio有一定开销。对于超低延迟场景可以考虑使用基于 Socket 的 MCP 传输层或将工具直接以内置函数形式集成到客户端牺牲隔离性。客户端超时设置检查 Semantic Kernel 和 MCP 客户端是否有可配置的超时设置并根据需要调整。7. 生产环境最佳实践与扩展方向将上述演示项目升级为生产可用系统还需要考虑以下方面。7.1 安全性强化MCP 服务器隔离生产环境中MCP 服务器应运行在独立的、权限受限的容器或进程中。特别是提供数据库访问、系统命令执行等敏感工具时。输入验证与消毒在 MCP 服务器的ExecuteAsync方法中必须对输入参数进行严格的验证和消毒防止注入攻击。访问控制实现 MCP 服务器的认证机制确保只有授权的客户端可以连接和调用工具。MCP 协议本身支持 TLS 和认证扩展。API 密钥管理切勿将 OpenAI API 密钥硬编码在代码中。使用 .NET 的配置系统如appsettings.json、环境变量或 Azure Key Vault 等安全存储服务。7.2 可观测性与可靠性结构化日志在 MCP 服务器和客户端中集成如 Serilog 这样的日志库记录工具调用请求、参数、结果、耗时和错误便于监控和调试。指标收集使用 Application Insights、OpenTelemetry 等收集工具调用次数、延迟、错误率等指标。错误处理与重试在客户端代码中对工具调用和 LLM 调用实现完善的错误处理如网络抖动、速率限制和重试策略使用 Polly 库。进程健康检查监控 MCP 服务器进程的健康状态如果崩溃客户端应能感知并尝试重启或告警。7.3 架构扩展工具动态发现本示例是静态注册工具。更复杂的系统可以从配置文件或数据库加载工具定义实现热更新。多工具服务器一个 MCP 服务器可以提供多个相关工具组如所有数据库操作工具。也可以为不同领域计算、搜索、绘图部署独立的 MCP 服务器客户端按需连接。复杂 Agent 编排Semantic Kernel Agents 支持更复杂的编排模式如多个专家 Agent 协作AgentGroupChat、具有持久化记忆的 Agent 等。可以根据业务需求设计工作流。流式响应对于生成内容较长的场景实现 Agent 回复的流式输出提升用户体验。7.4 下一步学习路径在掌握本实战项目的基础上你可以沿着以下方向深入探索更多工具尝试实现一个调用真实网络搜索 API如 Bing Search的 MCP 工具或一个执行安全沙箱内 Python 代码的工具。集成向量数据库为 Agent 添加长期记忆能力使用 Semantic Kernel 的插件将对话历史或知识库存入如 Qdrant、Weaviate 等向量数据库。研究提示工程优化 Agent 的instructions和工具的description这是提升 Agent 意图理解和工具调用准确率的关键。部署为服务将智能体客户端封装为 ASP.NET Core Web API提供 HTTP 接口前端通过聊天界面与之交互。深入 MCP 协议阅读 MCP 官方规范了解其资源Resources、提示模板Prompts等高级特性构建更强大的工具生态。通过本次实战你已经掌握了基于 Agent 框架和 MCP 协议构建可扩展、安全智能体的核心模式。这套架构将 LLM 的推理能力、外部工具的功能性以及 .NET 的工程可靠性结合在一起为开发下一代 AI 原生应用奠定了坚实的基础。在实际项目中从这个小而全的原型出发逐步迭代和强化各个组件是通向成功的最佳路径。

相关新闻

小瓶白酒哪个好喝?百年糊涂经典小百年:顺口不寡淡,够味不辣喉

小瓶白酒哪个好喝?百年糊涂经典小百年:顺口不寡淡,够味不辣喉

当“微醺”成为当代人解压的关键词,当“悦己”成为饮酒的核心诉求,小瓶白酒市场正迎来一场品质与体验的双重升级。作为深耕白酒领域20余年的实力品牌,百年糊涂旗下经典小百年(33/43/52)凭借“顺口又够味”的核心特质&a…

2026/10/2 7:44:14 阅读更多 →
Vue3 + Vite 实战:接入钉钉 OAuth 扫码登录(内嵌二维码 + 跳转授权)

Vue3 + Vite 实战:接入钉钉 OAuth 扫码登录(内嵌二维码 + 跳转授权)

Vue3 Vite 实战:接入钉钉 OAuth 扫码登录(内嵌二维码 跳转授权) 本文基于 Vue 3 Vite TypeScript Pinia 的登录页工程,完整演示钉钉开放平台 OAuth2 授权码模式:内嵌扫码(DTFrameLogin)与整…

2026/10/14 9:40:51 阅读更多 →
自动化文档命名系统:解决无标题文件管理难题

自动化文档命名系统:解决无标题文件管理难题

1. 项目概述作为一名从业多年的技术博主,我经常遇到一个令人头疼的问题——那些随手保存的代码片段、临时记录的想法、未完成的草稿,总是以"无标题"的形式散落在电脑各处。这个看似简单的命名问题,实际上反映了数字时代知识管理的普…

2026/10/7 10:21:13 阅读更多 →

最新新闻

图是一篇论文的门面,科迅捷AI帮你画到审稿人挑不出毛病

图是一篇论文的门面,科迅捷AI帮你画到审稿人挑不出毛病

博士论文里,图不只是插图,它是论证的一部分,是论文的门面。审稿人翻开论文,第一眼扫过的往往是图表。图做得好,读者对整篇论文的第一印象就好。这篇聊聊怎么把图画到挑不出毛病。 第一,图必须自洽。一张合…

2026/10/15 19:25:19 阅读更多 →
中牟全屋定制怎么选才不踩坑

中牟全屋定制怎么选才不踩坑

在中牟装修新房,很多业主都会纠结一个问题:全屋定制到底值不值得做?要回答中牟全屋定制怎么选不被坑,首先得把全屋定制优缺点看清楚。全屋定制的核心优势在于整体性强。以中牟欣琪雅全屋定制工厂的门墙柜一体化全屋定制为例&#…

2026/10/15 19:25:19 阅读更多 →
React Native iOS图片不显示?ATS、Base64与本地资源排查手册

React Native iOS图片不显示?ATS、Base64与本地资源排查手册

React Native 在 iOS 上跑起来,功能逻辑都没问题,结果一进详情页图片全空白;Android 上好好的,iOS 就是显示不出来。这种问题我处理过很多次,大部分情况不是 React Native 的 bug,而是 iOS 平台固有的机制在…

2026/10/15 19:25:19 阅读更多 →
9款AI写论文哪个好?云智变AI 云智变AI官网www.yunzhibian.cn 微信公众号搜一搜 云智变ai学术——一篇帮你从“比功能”升级到“比骨架”的选购指南

9款AI写论文哪个好?云智变AI 云智变AI官网www.yunzhibian.cn 微信公众号搜一搜 云智变ai学术——一篇帮你从“比功能”升级到“比骨架”的选购指南

先说一个反直觉的发现:大多数人在搜“9款AI写论文哪个好”的时候,真正应该问的问题不是“哪个软件功能多”,而是“哪个软件能帮我把论证搭结实”。 为什么?因为2026年高校对AI工具的使用规范已经收紧了。中国学位与研究生教育学会…

2026/10/15 19:25:19 阅读更多 →
第14章:恶意代码防范技术原理与应用

第14章:恶意代码防范技术原理与应用

震网病毒攻击的是西门子公司 SIMATIC 的 WinCC病毒命名前缀Worm网络蠕虫(WannaCry 永恒之蓝)Trojan特洛伊木马(植入威胁)Script脚本病毒(Script.Redlof)Harm破坏程序病毒Binder捆绑机病毒Macro宏病毒文件型…

2026/10/15 19:25:19 阅读更多 →
30天从零开始学AI应用开发(Day 26):项目三完工:调试 Agent 的血泪经验

30天从零开始学AI应用开发(Day 26):项目三完工:调试 Agent 的血泪经验

这是系列的第 26 篇。整个系列写给零基础、想入行 AI 的朋友,每天一篇,30 天后你会做出 3 个能写进简历的项目。这篇解决什么问题 昨天项目三跑通了,有几个朋友说规划步骤挺像样,也有人报告了各种奇怪的状况:跑着跑着不…

2026/10/15 19:24:19 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/15 9:49:14 阅读更多 →