从Whetstone.ChatGPT迁移到官方OpenAI .NET SDK的完整指南

news2026/5/3 10:01:52
1. 项目概述一个已归档的 .NET OpenAI API 封装库如果你在2023年或2024年初想在 .NET 应用里快速集成 ChatGPT 的功能那么你很可能在 GitHub 或 NuGet 上遇到过Whetstone.ChatGPT这个库。它曾是一个相当受欢迎的轻量级封装为开发者提供了调用 OpenAI GPT-3.5、GPT-4、Whisper 等 API 的便捷方式并且原生支持 .NET 的依赖注入DI用起来很顺手。我自己在几个内部工具和原型项目中就曾深度使用过它确实能省去不少直接处理 HTTP 请求和 JSON 序列化的麻烦。然而这个库现在已经被作者标记为“已弃用DEPRECATED”并归档了。作者 John Iwasz 明确建议开发者转向使用官方的OpenAI .NET 客户端库。这其实是一个非常重要的信号在技术选型时拥抱官方维护的 SDK 通常是更稳妥、更具前瞻性的选择。官方库会紧跟 OpenAI API 的迭代提供最及时的功能支持和错误修复。虽然 Whetstone.ChatGPT 在其活跃期做得不错甚至被 Visual Studio Magazine 报道过但技术的车轮总是向前滚动的。那么为什么我们今天还要花时间聊一个“过时”的库呢原因有三第一理解封装逻辑。通过剖析一个设计良好的第三方封装我们能更深刻地理解如何与 OpenAI API 交互这对于即使使用官方库也大有裨益。第二迁移经验。很多现有项目可能还在使用它了解其核心模式有助于平滑迁移到官方库。第三设计启示。它的代码结构和设计思路比如对依赖注入的友好支持、清晰的请求/响应模型定义仍然是优秀的 .NET 库设计范例。本文适合所有层次的 .NET 开发者无论你是想回顾一个经典的社区项目还是正在为现有项目寻找从 Whetstone.ChatGPT 迁移到官方 OpenAI .NET SDK 的路径都能在这里找到详细的拆解和实操建议。我们会深入其核心设计、典型用法并重点分享迁移过程中的“踩坑”经验和注意事项。2. 库的核心设计与架构思路解析Whetstone.ChatGPT 的设计目标非常明确做一个“简单轻量”的包装器。它没有试图去创造一个全新的抽象层而是专注于将 OpenAI 的 REST API 映射成一套类型安全、易于使用的 .NET 接口和类。这种“忠实于原 API”的设计哲学使得熟悉 OpenAI 官方文档的开发者能几乎无成本地上手。2.1 核心组件与职责划分整个库围绕几个核心组件构建理解它们的关系是高效使用或迁移的关键。1.IChatGPTClient接口与ChatGPTClient实现类这是库的入口和心脏。所有与 OpenAI 服务的交互都通过这个客户端进行。它定义了一系列异步方法如CreateChatCompletionAsync、CreateImageAsync等一一对应着 OpenAI API 的端点。ChatGPTClient内部封装了HttpClient负责处理认证添加Authorization头、构造请求 URL、序列化请求对象、发送 HTTP 请求、反序列化响应以及处理错误状态码。这种集中式的客户端设计让使用者无需关心 HTTP 细节。2. 请求与响应模型Request/Response Models库为每一种 OpenAI API 功能定义了对应的 C# 类。例如ChatGPTChatCompletionRequest对应聊天补全 API 的请求参数包含Model、Messages、Temperature、MaxTokens等属性。ChatGPTChatCompletionResponse对应聊天补全 API 的响应包含Choices、Usage等属性并提供了GetCompletionText()这样的便捷方法来提取助理的回复文本。类似的还有ChatGPTCompletionRequest旧版补全、ChatGPTCreateImageRequest、ChatGPTAudioTranscriptionRequest等。这些模型类使用了System.Text.Json进行序列化属性通常用JsonPropertyName特性来匹配 API 的 JSON 字段名。这种强类型模型极大地提升了开发体验和代码安全性。3. 常量与枚举库定义了一些静态类或常量来管理模型名称和角色例如ChatGPT35Models.Turbo对应字符串gpt-3.5-turboChatGPTMessageRoles.System对应system。这避免了在代码中硬编码字符串减少拼写错误。2.2 依赖注入DI集成设计这是 Whetstone.ChatGPT 的一个亮点。它提供了与 .NET 内置依赖注入容器IServiceCollection无缝集成的扩展方法。其典型配置模式如下// 1. 配置凭据通常从IConfiguration读取 services.ConfigureChatGPTCredentials(options { options.ApiKey configuration[OpenAI:ApiKey]; options.Organization configuration[OpenAI:Organization]; // 可选 }); // 2. 确保 HttpClient 服务已注册.NET Core 之后通常已默认添加 services.AddHttpClient(); // 如果尚未全局添加 // 3. 注册 ChatGPT 客户端 services.AddScopedIChatGPTClient, ChatGPTClient();设计考量为什么是Scoped而不是Singleton虽然HttpClient本身建议以Singleton或静态方式使用以避免套接字耗尽但ChatGPTClient内部通常会从IHttpClientFactory获取一个具名或类型的客户端实例。将其注册为Scoped可以与当前请求的生命周期绑定在某些需要根据用户上下文动态设置 API Key 或基地址BaseAddress的高级场景中更为灵活。不过在绝大多数单密钥、单端口的场景下将其注册为Singleton也是完全可行且更高效的这需要开发者根据实际情况判断。实操心得在实际项目中我强烈建议将ApiKey等敏感信息放在appsettings.json或用户机密中通过IConfiguration注入。绝对不要将密钥硬编码在源码里尤其是准备提交到公共仓库时。3. 核心功能实操与代码示例深度解读虽然库已弃用但其代码示例清晰地展示了如何调用各类 OpenAI API。理解这些示例等于理解了 API 的基本用法迁移到官方库时概念是相通的。3.1 聊天补全对话的核心聊天补全是目前最常用的功能。Whetstone.ChatGPT 的示例展示了构建多轮对话的标准流程。var gptRequest new ChatGPTChatCompletionRequest { Model ChatGPT35Models.Turbo, Messages new ListChatGPTChatCompletionMessage() { // 系统消息设定助手的行为和角色 new ChatGPTChatCompletionMessage(ChatGPTMessageRoles.System, You are a helpful assistant.), // 用户的问题 new ChatGPTChatCompletionMessage(ChatGPTMessageRoles.User, Who won the world series in 2020?), // 助理的历史回复用于维持上下文 new ChatGPTChatCompletionMessage(ChatGPTMessageRoles.Assistant, The Los Angeles Dodgers won the World Series in 2020.), // 用户的后续问题 new ChatGPTChatCompletionMessage(ChatGPTMessageRoles.User, Where was it played?) }, Temperature 0.9f, // 控制随机性0-2越高越随机 MaxTokens 100 // 限制生成的最大令牌数控制响应长度 };关键点解析Messages数组这是对话的上下文历史。API 本身是无状态的每次请求都需要携带完整的对话历史。数组中的顺序至关重要它代表了对话的时序。System角色用于在对话开始时给 AI 一个高级指令设定其身份、风格或目标。这对于塑造对话走向非常有效。Temperature和MaxTokensTemperature创造性 vs. 确定性。写创意文案可以设高如 0.8-1.2做代码生成或事实问答建议调低如 0.2-0.5。MaxTokens必须设置。需要估算“用户输入 期望的助理输出”的令牌数并留有余地。GPT-3.5 Turbo 的上下文窗口通常是 4096 或 16385 个令牌GPT-4 更大。超出会截断。常见问题很多新手会忘记在后续请求中包含之前的对话历史导致 AI“失忆”。正确的做法是在客户端或服务层维护一个对话的Messages列表每次新请求都附上整个列表。3.2 文件与微调定制专属模型微调Fine-tuning是使用自有数据训练专属模型的重要手段。Whetstone.ChatGPT 展示了从准备数据到发起训练的完整流程。步骤一准备训练数据数据需要是JSONL格式即每行一个 JSON 对象。库提供了ChatGPTTurboFineTuneLine等辅助类来构建数据并最终通过.ToJsonLBinary()扩展方法转换为字节流。ListChatGPTTurboFineTuneLine tuningInput new() { new ChatGPTTurboFineTuneLine() { Messages new ListChatGPTTurboFineTuneLineMessage() { new(ChatGPTMessageRoles.System, Marv is a factual chatbot that is also sarcastic.), new(ChatGPTMessageRoles.User, Whats the capital of France?), new(ChatGPTMessageRoles.Assistant, Paris, as if everyone doesnt know that already.) }, }, // ... 更多对话样本 }; byte[] tuningText tuningInput.ToJsonLBinary();步骤二上传文件将内存中的字节数组包装成ChatGPTFileContent然后调用UploadFileAsync。ChatGPTUploadFileRequest uploadRequest new ChatGPTUploadFileRequest { File new ChatGPTFileContent { FileName marvin.jsonl, Content tuningText }, Purpose fine-tune // 明确指定用途 }; var newFileInfo await client.UploadFileAsync(uploadRequest); string fileId newFileInfo.Id; // 保存这个ID用于后续步骤步骤三创建微调任务使用上一步获得的fileId来发起微调任务。ChatGPTCreateFineTuneRequest tuningRequest new ChatGPTCreateFineTuneRequest { TrainingFileId fileId, Model gpt-3.5-turbo-1106 // 指定基础模型 }; var fineTuneJob await client.CreateFineTuneAsync(tuningRequest); string fineTuneJobId fineTuneJob.Id;步骤四轮询与使用微调是异步任务需要轮询RetrieveFineTuneAsync(fineTuneJobId)来检查状态。当Status变为succeeded后会得到一个专属的模型 ID格式如ft:gpt-3.5-turbo-1106:your-org::unique-id之后在聊天请求的Model字段中使用这个 ID 即可。注意微调成本较高且新版 API如gpt-3.5-turbo-instruct或gpt-4的微调的流程和参数可能有变。务必查阅最新的 OpenAI 官方文档。Whetstone 库中的示例可能基于旧的 API 版本。3.3 图像生成与音频转录这两项功能的调用模式非常直观体现了库的封装思路。图像生成 (DALL·E)var imageRequest new ChatGPTCreateImageRequest() { Prompt A serene lake at sunset, digital art, Size CreatedImageSize.Size1024, // 枚举值对应 1024x1024 ResponseFormat CreatedImageFormat.Url // 或 Base64 }; var imageResponse await client.CreateImageAsync(imageRequest); // 如果返回Url直接使用 imageResponse.Data[0].Url // 如果返回Base64使用 client.DownloadImageAsync 解码关键参数N控制生成图片的数量默认1Quality仅对dall-e-3模型有效standard或hd。音频转录 (Whisper)byte[] audioBytes File.ReadAllBytes(meeting.mp3); var transcriptionRequest new ChatGPTAudioTranscriptionRequest { File new ChatGPTFileContent { FileName meeting.mp3, Content audioBytes }, Model whisper-1, // 模型固定 ResponseFormat json, // 或 text, srt, vtt 等 Language en // 可选提示音频语言可提高准确性 }; var transcript await client.CreateTranscriptionAsync(transcriptionRequest); Console.WriteLine(transcript.Text);注意事项Whisper API 支持多种音频格式但最稳定的是mp3、wav、m4a。文件大小有限制通常 25MB。对于长音频可以考虑在客户端先进行分割。4. 向官方 OpenAI .NET SDK 迁移的完整指南既然原库已弃用将现有项目迁移到官方库是必然选择。官方库OpenAI由 OpenAI 维护功能更全面更新更及时。下面是一个详细的迁移手册。4.1 环境准备与安装首先移除对Whetstone.ChatGPT的 NuGet 包引用。然后安装官方库# 使用 .NET CLI dotnet add package OpenAI --version 1.10.0 # 请使用最新稳定版 # 或在 Visual Studio 的包管理器控制台 Install-Package OpenAI官方库的命名空间是OpenAI核心客户端是OpenAIClient。4.2 客户端配置与依赖注入迁移Whetstone 的ChatGPTCredentials配置方式需要改变。官方库推荐直接使用OpenAIClient的构造函数。旧方式 (Whetstone)services.ConfigureChatGPTCredentials(options options.ApiKey sk-...); services.AddScopedIChatGPTClient, ChatGPTClient();新方式 (OpenAI .NET SDK)// 方式1直接实例化适合简单控制台应用 var openAIClient new OpenAIClient(sk-...); // 方式2通过依赖注入推荐用于 ASP.NET Core services.AddSingletonOpenAIClient(sp { var configuration sp.GetRequiredServiceIConfiguration(); var apiKey configuration[OpenAI:ApiKey]; // 也可以从 Azure OpenAI 端点初始化这里以 OpenAI 为例 return new OpenAIClient(apiKey); });如果之前使用了Organization可以在构造函数中传入OpenAIClientSettings对象进行设置。4.3 核心功能调用迁移对照表下表列出了主要功能从 Whetstone 迁移到官方 SDK 的代码对比功能Whetstone.ChatGPT (旧)OpenAI .NET SDK (新)关键差异与注意事项聊天补全client.CreateChatCompletionAsync(request)client.ChatCompletions.CreateCompletionAsync(new ChatCompletionsOptions { ... })1. 请求类名变为ChatCompletionsOptions。2.Messages是IListChatRequestMessage其派生类如ChatRequestSystemMessage,ChatRequestUserMessage替代了旧的Role枚举。3. 响应类为ChatCompletions通过response.Choices[0].Message.Content获取文本。文本补全client.CreateCompletionAsync(request)(已过时)client.Completions.CreateCompletionAsync(new CompletionsOptions { ... })用于旧版text-davinci-003等模型非聊天模型。官方也推荐优先使用聊天补全端点。图像生成client.CreateImageAsync(request)client.Images.GenerateImageAsync(new ImageGenerationOptions { ... })1. 请求类名ImageGenerationOptions。2. 尺寸用字符串如1024x1024。3. 响应中图片 URL 在response.Data[0].Url。音频转录client.CreateTranscriptionAsync(request, verbose)client.Audio.TranscribeAsync(new AudioTranscriptionOptions { ... })1. 文件通过BinaryData传入。2. 请求类名AudioTranscriptionOptions。3. 响应文本在response.Text。文件上传client.UploadFileAsync(request)client.Files.UploadFileAsync(File.OpenRead(path), fine-tune)官方 SDK 方法更直接接受Stream和用途字符串。微调任务client.CreateFineTuneAsync(request)client.FineTuningJobs.CreateFineTuningJobAsync(new FineTuningJobCreateOptions { ... })API 有较大更新参数和对象模型不同需仔细对照官方文档。4.4 迁移实战以聊天补全为例让我们将一个具体的 Whetstone 调用示例迁移到官方库。旧代码using Whetstone.ChatGPT; using Whetstone.ChatGPT.Models; var gptRequest new ChatGPTChatCompletionRequest { Model gpt-3.5-turbo, Messages new ListChatGPTChatCompletionMessage() { new ChatGPTChatCompletionMessage(system, You are a helpful assistant.), new ChatGPTChatCompletionMessage(user, Hello!) } }; using var client new ChatGPTClient(sk-...); var response await client.CreateChatCompletionAsync(gptRequest); Console.WriteLine(response?.GetCompletionText());迁移后的新代码using OpenAI; using OpenAI.Chat; // 初始化客户端 var openAIClient new OpenAIClient(sk-...); // 构建请求选项 var chatCompletionsOptions new ChatCompletionsOptions { DeploymentName gpt-3.5-turbo, // 注意官方SDK中常用 DeploymentName Messages { new ChatRequestSystemMessage(You are a helpful assistant.), new ChatRequestUserMessage(Hello!) }, Temperature 0.7f, // 可选参数 MaxTokens 500 // 可选参数 }; // 调用API ChatCompletions response await openAIClient.GetChatCompletionsAsync(chatCompletionsOptions); // 获取回复 string assistantReply response.Choices[0].Message.Content; Console.WriteLine(assistantReply);迁移要点命名空间从Whetstone.ChatGPT改为OpenAI和OpenAI.Chat。客户端从ChatGPTClient改为OpenAIClient。请求对象从ChatGPTChatCompletionRequest改为ChatCompletionsOptions。消息构建从通用的ChatGPTChatCompletionMessage配合角色字符串改为使用特定的消息类型类ChatRequestSystemMessage,ChatRequestUserMessage,ChatRequestAssistantMessage。这提供了更好的类型安全。获取响应文本从response.GetCompletionText()改为response.Choices[0].Message.Content。模型指定官方 SDK 在与 Azure OpenAI 服务兼容的设计下常用DeploymentName属性来指定模型。对于直接使用 OpenAI 端点将其值设为模型名称如gpt-3.5-turbo即可。4.5 错误处理与重试策略官方 SDK 抛出的异常类型更为丰富。在迁移时需要更新错误处理逻辑。旧方式可能简单处理try { var response await client.CreateChatCompletionAsync(request); } catch (HttpRequestException ex) { // 处理网络或HTTP错误 }新方式应更细致try { var response await openAIClient.GetChatCompletionsAsync(chatCompletionsOptions); } catch (RequestFailedException ex) // 官方SDK抛出的特定异常 { Console.WriteLine($Error Code: {ex.ErrorCode}); Console.WriteLine($Status: {ex.Status}); Console.WriteLine($Message: {ex.Message}); // 可以根据 ex.Status 进行重试如429 503 if (ex.Status 429) // 速率限制 { // 实现指数退避重试逻辑 await Task.Delay(1000); // retry... } }实操建议对于生产环境务必实现一个带有指数退避和抖动Jitter的重试机制特别是针对429 Too Many Requests和5xx服务器错误。可以考虑使用Polly这样的弹性库来优雅地处理瞬态故障。5. 常见问题、排查技巧与迁移避坑实录在实际迁移和使用过程中会遇到一些典型问题。这里记录了我个人和社区中常见的一些“坑”及其解决方案。5.1 认证失败与密钥问题问题调用 API 时返回401 Unauthorized。排查检查密钥格式确保 API 密钥以sk-开头。从 OpenAI 平台复制的密钥可能包含多余空格。检查环境变量/配置确认运行时代码读取到的密钥是正确的。在代码中临时打印或记录密钥的前几位切勿完整记录进行验证。密钥是否过期或禁用在 OpenAI 平台检查密钥的额度、有效期和状态。组织ID如使用如果旧代码配置了Organization迁移到官方 SDK 时需要在OpenAIClientSettings中设置Organization属性或者通过OpenAIClient的另一个构造函数重载传入。5.2 模型名称或部署名错误问题返回404 Not Found或400 Bad Request提示模型不存在。排查确认模型可用性gpt-4等模型可能需要单独申请访问权限。确保你的账户有权使用所请求的模型。迁移后参数名在官方 SDK 中使用DeploymentName属性。对于 OpenAI 端点其值就是模型名称字符串如gpt-4-turbo-preview。确保字符串完全匹配官方文档中可用的模型名称。大小写和连字符模型名称对大小写和符号敏感确保完全一致。5.3 上下文超限与令牌计算问题请求失败错误信息提示context_length_exceeded。排查与解决计算令牌数每次请求的Messages总令牌数不能超过模型的上限如gpt-3.5-turbo通常是 16385。需要估算输入和输出的令牌数。可以使用 OpenAI 提供的 tiktoken 库进行精确计算或者在客户端实现一个近似的估算例如1个英文单词≈1.3个令牌1个中文字符≈2个令牌。实现上下文窗口管理对于长对话不能无限制地累积历史消息。需要实现一个策略当令牌数接近上限时从历史中移除最早的消息对或进行摘要。一种常见策略是保留最新的N轮对话或者使用System消息对之前的长上下文进行总结。检查MaxTokens确保MaxTokens参数设置合理为输入令牌留出空间。MaxTokens是输出令牌的最大值。5.4 流式响应处理差异Whetstone.ChatGPT 支持响应流式传输Streaming官方 SDK 也支持但 API 调用方式不同。旧方式 (Whetstone):var response await client.StreamChatCompletionAsync(request); await foreach (var chunk in response) { Console.Write(chunk.GetCompletionText()); }新方式 (OpenAI .NET SDK):var chatCompletionsOptions new ChatCompletionsOptions { ... }; var response await openAIClient.GetChatCompletionsStreamingAsync(chatCompletionsOptions); await foreach (ChatCompletionsUpdate update in response) { Console.Write(update.ContentUpdate); }迁移注意流式响应处理逻辑需要重写。官方 SDK 的流式响应返回一个AsyncCollection需要遍历并拼接ContentUpdate。5.5 依赖注入容器中的生命周期管理问题在 ASP.NET Core 应用中将OpenAIClient注册为Scoped可能导致HttpClient连接池效率不高注册为Singleton又无法支持每个请求不同配置如多租户场景。解决方案单租户/单配置场景注册为Singleton是最佳实践。services.AddSingletonOpenAIClient(_ new OpenAIClient(configuration[OpenAI:ApiKey]));多租户场景需要根据请求动态创建客户端。可以注册一个工厂服务。services.AddScopedIOpenAIClientFactory, OpenAIClientFactory(); // 在 Factory 中根据当前租户信息从数据库或配置中读取对应的 ApiKey然后 new OpenAIClient(key)使用IHttpClientFactory官方OpenAIClient内部管理自己的HttpClient。通常不需要也不建议用IHttpClientFactory去创建它除非你有非常特殊的代理或处理器配置需求。5.6 版本兼容性与弃用 API问题迁移后发现某些在 Whetstone 中可用的功能在官方 SDK 中找不到对应方法。排查查阅官方 SDK 文档和发行说明OpenAI API 本身在迭代一些端点可能已被弃用如旧的/v1/completions端点被/v1/chat/completions取代。官方 SDK 会反映这些变化。检查 NuGet 包版本确保你使用的是最新稳定版的OpenAI包。旧版本可能不支持最新的 API 功能如 GPT-4 Vision JSON Mode 等。回顾 Whetstone 的代码如果 Whetstone 中使用了某个特性但官方 SDK 示例中没有首先去 OpenAI API 官方文档 确认该特性是否仍然存在以及其调用方式。很可能只是参数名或对象结构发生了变化。迁移本身是一个细致的过程最好的方法是先在一个独立的测试项目或分支中针对每个功能点进行逐个验证和迁移确保所有业务逻辑在新库下工作正常再进行全面的替换。虽然 Whetstone.ChatGPT 曾是一个优秀的桥梁但过渡到官方 SDK 无疑是更可持续的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2577914.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…