基于AWS Serverless构建企业级OpenAI代理网关:安全、可控、低成本集成AI服务

news2026/5/9 17:41:27
1. 项目概述与核心价值最近在折腾一个很有意思的项目叫aws-openai来自 GitHub 上的FullStackWithLawrence仓库。乍一看名字你可能会觉得这又是一个简单的“把 OpenAI API 套个 AWS 壳”的玩具。但实际深入进去你会发现它的设计思路非常巧妙解决了一个在真实企业级应用开发中非常普遍且头疼的问题如何安全、可控、低成本地将强大的第三方 AI 服务如 OpenAI集成到自己的云原生架构中。这个项目本质上是一个部署在 AWS 上的代理服务。它在你自己的 AWS 账户里运行作为一个“中间人”接收来自你内部应用或服务的请求然后将这些请求转发给远端的 OpenAI API最后再把结果返回给你的应用。听起来好像多此一举直接在你的代码里调用 OpenAI 的官方 SDK 不香吗这里面的门道可就多了。直接调用意味着你的应用代码里硬编码了 OpenAI 的 API Key这个 Key 拥有极高的权限一旦泄露轻则产生天价账单重则数据泄露。其次OpenAI 的 API 有速率限制如果你的应用突然流量暴增可能会被限流影响用户体验。再者你无法对请求和响应进行审计、内容过滤或格式转换。aws-openai项目就是来解决这些痛点的。它通过 AWS 的 Serverless 服务如 API Gateway, Lambda, DynamoDB构建了一个弹性的、安全的代理层。你的应用不再直接面对 OpenAI而是面对你自己完全控制的 AWS 端点。你可以在这里面做很多事情记录每一次对话用于分析和审计实施精细化的用量控制和配额管理防止某个用户或部门滥用对输入输出进行内容安全审查过滤掉不适当的内容甚至实现请求的缓存对重复性问题直接返回缓存结果以节省成本和提升速度。对于正在或计划将 GPT 等大模型能力集成到产品中的开发者、架构师和运维工程师来说这个项目提供了一个近乎“开箱即用”的参考架构。它不是一个最终产品而是一个最佳实践的蓝图。你可以基于它进行二次开发快速搭建起符合自己业务需求和安全规范的 AI 网关。2. 架构设计与核心组件拆解要理解这个项目我们必须先拆解它的技术栈。它完全构建在 AWS Serverless 服务之上这意味着你无需管理服务器只需为实际使用的计算资源和 API 调用次数付费非常适合流量波动大或处于初期的项目。2.1 整体数据流与核心服务角色整个系统的数据流非常清晰我们可以把它想象成一个精心设计的安检通道和调度中心入口API Gateway这是整个服务的门面。你的应用程序比如一个前端网页、一个移动 App 或者另一个后端服务将所有发给 OpenAI 的请求发送到你部署的这个 API Gateway 的特定端点例如https://your-api-id.execute-api.region.amazonaws.com/prod/v1/chat/completions。API Gateway 负责接收 HTTPS 请求进行基础的认证、限流并将请求路由到后端的 Lambda 函数。它的优势在于可以轻松处理海量并发并且与 AWS 的认证授权服务如 Cognito、IAM无缝集成。业务逻辑核心AWS Lambda这是整个代理的“大脑”。一个或多个 Lambda 函数承载了核心逻辑。当 API Gateway 把请求转发过来后Lambda 函数会执行一系列操作请求验证与解析检查请求头、API Key这里是你自己发放给内部应用的 Key而非 OpenAI 的 Key、请求体格式。业务逻辑处理这是可扩展性最强的一环。在这里你可以查询 DynamoDB 来检查用户配额、记录日志可以调用其他 AWS 服务如 Amazon Comprehend进行内容审查可以对请求的 Prompt 进行预处理比如添加系统指令、格式化历史对话。转发请求使用内置的HTTP模块将处理后的请求转发给真正的 OpenAI API 端点。这里的关键是OpenAI 的 API Key 是存储在 Lambda 的环境变量或 AWS Secrets Manager 中的完全与你的应用代码隔离。响应处理与返回收到 OpenAI 的响应后Lambda 函数还可以进行后处理比如提取关键信息、格式化响应、记录响应内容到数据库最后将处理后的结果返回给 API Gateway再传回给你的应用程序。数据存储与状态管理Amazon DynamoDB这是一个全托管的 NoSQL 数据库用于存储所有需要持久化的状态。典型的表设计可能包括Users表存储内部用户/应用的 ID、名称、分配的 API Key哈希处理后的、调用配额每月/每日次数、已使用量等。RequestLogs表记录每一次代理调用的详细信息包括请求 ID、时间戳、用户 ID、原始 Prompt可选脱敏、Token 使用量、模型名称、响应时间、状态码等。这张表对于监控、审计和成本分摊至关重要。Cache表可选用于缓存高频或固定的问答对Key 可以是 Prompt 的哈希值Value 是对应的 Completion并设置 TTL生存时间。密钥与配置管理AWS Systems Manager Parameter Store / Secrets Manager安全是重中之重。OpenAI 的 API Key 属于最高机密。最佳实践是将其存储在 AWS Secrets Manager 中该服务提供自动轮转、加密存储和细粒度的访问控制。Lambda 函数在运行时通过 IAM 角色临时获取访问权限去读取这个密钥确保密钥不会出现在代码或日志中。一些非机密的配置如默认模型、超时时间、速率限制值则可以放在 Parameter Store 中。2.2 为什么选择 Serverless 架构这个选型背后有深刻的考量绝非盲目追新。成本效益对于 AI 代理这类流量可能忽高忽低的服务Serverless 是绝配。没有流量时成本几乎为零除了少量的存储费用。流量激增时Lambda 和 API Gateway 会自动扩展你只需为那几秒或几分钟的计算付费。相比之下维护一台始终在线的 EC2 实例无论用不用都要花钱。运维简化无需操心服务器补丁、系统监控、容量规划。AWS 负责底层基础设施的可用性和扩展性开发者可以聚焦在业务逻辑上。安全内置IAM 角色机制使得服务间的权限管理变得清晰和安全。Lambda 函数通过角色获取最小必要权限遵循了安全最佳实践。快速迭代每个功能点如认证、转发、日志都可以由一个独立的 Lambda 函数实现通过 API Gateway 路由。这使得代码结构清晰也便于独立部署和更新。注意Serverless 并非银弹。它的冷启动问题Lambda 函数从休眠到响应的延迟在需要极低延迟100ms的场景下需要仔细优化例如通过预置并发。但对于大多数 AI 对话场景几百毫秒的冷启动延迟是可以接受的。3. 核心功能模块深度解析了解了整体架构我们深入到几个核心功能模块看看它们是如何被具体实现的以及其中有哪些值得注意的细节和“坑”。3.1 认证、授权与配额管理这是企业级服务的基石。你的代理不能对所有人开放必须知道“谁”在调用以及“他”还能调用多少次。1. 认证Authentication - 你是谁通常采用 API Key 机制。你的内部应用在调用代理时需要在 HTTP 请求头如X-API-Key中携带一个你预先发放的 Key。Lambda 函数收到请求后从请求头中提取这个 Key。在 DynamoDB 的Users表中查询该 Key 对应的用户记录。这里存储的应该是 Key 的哈希值例如 SHA-256而非明文即使数据库泄露攻击者也无法直接获得可用的 Key。如果查询不到或哈希值不匹配立即返回401 Unauthorized。2. 授权Authorization - 你能做什么在Users表中除了基础信息还可以定义用户的权限等级。例如role: “admin”可以访问所有模型无配额限制。role: “user”只能访问gpt-3.5-turbo等成本较低的模型。model_whitelist: [“gpt-3.5-turbo”, “text-embedding-ada-002”]一个更细粒度的模型白名单。Lambda 函数在转发请求前会检查当前用户是否有权使用其请求中指定的 AI 模型。3. 配额管理Quota - 你还能用多少这是控制成本的核心。配额通常基于时间窗口如“每月 1000 次请求”或“每天消耗不超过 50 万 Token”。实现逻辑如下在Users表中有quota_total,quota_used,quota_reset_date配额重置日期等字段。Lambda 处理请求时先根据user_id查询出当前用量。判断是否超出配额if quota_used quota_total: return 429 Too Many Requests。如果未超限则转发请求给 OpenAI。关键步骤收到 OpenAI 的响应后从响应头或响应体中解析出本次消耗的total_tokens。使用 DynamoDB 的UpdateItem操作以原子方式增加quota_used字段的值。这里必须使用原子操作防止高并发下的配额超卖。# 伪代码示例使用 boto3 (AWS SDK for Python) import boto3 from decimal import Decimal dynamodb boto3.resource(‘dynamodb’) table dynamodb.Table(‘Users’) # 原子增加 quota_used table.update_item( Key{‘user_id’: user_id}, UpdateExpression‘ADD quota_used :val’, ExpressionAttributeValues{‘:val’: Decimal(total_tokens_used)}, ConditionExpression‘quota_used quota_total’ # 条件更新再次检查防止竞态条件 )同时将这次调用的 Token 用量记录到RequestLogs表。实操心得配额设计的艺术直接限制请求次数比较简单但不够精确。因为不同模型、不同长度的 Prompt成本差异巨大。更精细的做法是基于 Token 消耗来计费。你需要根据 OpenAI 的定价表为每个模型设置一个“积分系数”例如gpt-4 每 Token 消耗 10 积分gpt-3.5-turbo 每 Token 消耗 1 积分。用户的配额单位是“积分”而不是简单的“次数”。这样能更公平、更准确地反映实际成本。3.2 请求/响应处理与日志审计代理层的一个巨大优势是拥有完整的请求/响应可见性。请求预处理在将用户的 Prompt 转发给 OpenAI 之前你可以注入业务逻辑。例如系统指令注入自动为每个对话开头加上一段固定的系统角色指令比如“你是一个专业的客服助手请用中文简洁回答。”确保所有通过代理的对话都遵循统一的风格。Prompt 工程优化对用户输入的 Prompt 进行清洗、格式化或增强提升最终模型输出的质量。敏感信息过滤扫描 Prompt 中是否包含手机号、身份证号等个人敏感信息PII并进行脱敏处理后再转发保护用户隐私。响应后处理收到 OpenAI 的回复后也可以进行加工格式标准化将模型返回的 JSON 或文本转换成你内部应用期望的统一格式。内容安全审查对模型生成的内容进行二次检查确保其符合内容安全政策。这可以调用另一个专门的审查模型或规则引擎。结果提取与结构化如果调用的是函数调用Function Calling功能可以解析返回的 JSON并触发后续的业务流程。全链路日志审计每一次调用无论成功失败都应该被详尽地记录在RequestLogs表中。日志条目应包含字段名类型说明request_idString唯一请求 ID便于追踪timestampNumber请求时间戳Unix epochuser_idString发起调用的用户 IDmodel_requestedString用户请求的模型model_usedString实际使用的模型可能被代理层覆盖prompt_lengthNumber输入 Prompt 的 Token 数completion_lengthNumber输出 Completion 的 Token 数total_tokensNumber本次调用总 Token 消耗status_codeNumber最终返回给用户的状态码如 200, 429, 500openai_statusNumberOpenAI API 返回的原始状态码response_time_msNumber从接收到用户请求到返回响应的总耗时cost_estimateNumber根据 Token 数和模型单价估算的成本有了这张表你可以轻松地监控异常快速发现某个用户或模型的失败率飙升。成本分析按部门、按项目、按模型进行成本分摊。性能分析分析不同模型或不同 Prompt 长度的响应时间分布。数据回放在模型升级后用历史 Prompt 进行回归测试对比输出质量。3.3 错误处理与重试机制网络服务不可能 100% 可靠OpenAI 的 API 也可能偶尔返回 5xx 错误或速率限制429。一个健壮的代理必须能妥善处理这些情况。1. 错误分类与响应客户端错误4xx如配额不足、请求格式错误、认证失败。这些错误应立即返回给调用方并附带清晰的错误信息。服务器端错误5xx包括代理自身错误Lambda 超时、DynamoDB 异常和 OpenAI 返回的错误。对于自身错误应返回500 Internal Server Error或503 Service Unavailable。对于 OpenAI 的错误代理可以选择性地将错误信息透传也可以进行转换和润色避免将后端服务的内部细节暴露给前端。2. 智能重试策略对于 OpenAI 返回的429 Too Many Requests速率限制或500 Internal Server Error简单的失败返回体验很差。应该实现一个带有退避策略的重试机制。import time import openai def send_request_with_retry(prompt, max_retries3): for attempt in range(max_retries): try: response openai.ChatCompletion.create(...) # 你的调用逻辑 return response except openai.error.RateLimitError: if attempt max_retries - 1: raise wait_time (2 ** attempt) random.random() # 指数退避加随机抖动 time.sleep(wait_time) continue except openai.error.APIError as e: # 处理其他API错误如500错误 if e.status_code 500: time.sleep(1) continue else: raise指数退避每次重试的等待时间加倍1秒2秒4秒...避免在服务恢复瞬间造成新的洪峰。随机抖动在退避时间上加一个小的随机值防止多个客户端同时重试导致同步震荡。重试上限必须设置最大重试次数如3次避免因持续错误导致请求长时间挂起。在代理层实现重试对前端应用是完全透明的提升了整体的可用性和用户体验。4. 部署、配置与运维实操指南理论讲完了我们来看看如何亲手把这个架构搭建起来。aws-openai项目通常会提供基础设施即代码IaC的模板例如 AWS SAMServerless Application Model或 CDK 定义让部署一键完成。4.1 环境准备与初始部署前提条件一个 AWS 账户并配置好具有足够权限的 IAM 用户/角色包含创建 Lambda、API Gateway、DynamoDB 等资源的权限。本地安装 AWS CLI 并配置好凭证aws configure。安装 SAM CLI如果项目使用 SAM或 AWS CDK CLI。部署步骤以 SAM 为例获取代码从 GitHub 克隆FullStackWithLawrence/aws-openai仓库。配置参数查看template.yaml文件找到Parameters部分。你需要准备以下关键参数OpenAIApiKey你的 OpenAI API Key。绝对不要直接写在代码或模板里最佳实践是在部署时通过命令行传入或更安全地在部署后手动存入 AWS Secrets Manager。DefaultModel默认使用的模型如gpt-3.5-turbo。CorsOrigin如果你有前端网页需要调用此代理需要设置允许跨域的源地址如https://your-frontend.com。构建与部署# 在项目根目录下 sam build sam deploy --guided在--guided交互模式下SAM CLI 会提示你输入上述参数。对于OpenAIApiKey你可以先输入一个占位符部署完成后再去 AWS 控制台手动配置。配置密钥部署完成后在 AWS 控制台找到生成的 Lambda 函数。在它的“配置”-“环境变量”中添加一个名为OPENAI_API_KEY的变量。但更好的方式是使用 Secrets Manager在 Secrets Manager 中创建一个新的密钥将你的 OpenAI API Key 存入。修改 Lambda 函数的 IAM 执行角色附加一个允许读取该特定密钥的策略。修改 Lambda 函数代码从boto3.client(‘secretsmanager’)获取密钥而不是环境变量。获取端点部署输出中会给出 API Gateway 的调用 URL如https://xxxxx.execute-api.us-east-1.amazonaws.com/Prod。这就是你的 AI 代理服务的入口。4.2 核心配置详解与调优部署只是第一步要让服务稳定高效运行还需要调整一系列配置。Lambda 函数配置内存与超时对话模型的响应时间较长。建议将 Lambda 内存设置为至少 512 MB内存大小也间接影响 CPU 能力超时时间设置为 30 秒以应对复杂的对话或网络延迟。并发执行与预置如果你预计会有突发流量例如产品上线推广可以考虑为 Lambda 函数配置预置并发。这相当于提前“预热”一定数量的函数实例可以完全消除冷启动对首批用户的影响。但这会产生额外的费用。环境变量除了 API Key还可以将日志级别、默认模型、各种开关如是否启用缓存、是否开启详细日志放在环境变量中便于在不同环境开发、测试、生产间切换。API Gateway 配置授权器为了更强大的认证可以创建自定义的 Lambda 授权器。在 API Gateway 的方法请求中配置该授权器它会在调用你的业务 Lambda 之前先执行一个独立的认证函数来验证 JWT Token 或 API Key并生成 IAM 策略。这比在业务 Lambda 内做认证更清晰、更高效。使用计划与 API KeyAPI Gateway 原生支持“使用计划”你可以创建不同的计划如“免费版”、“专业版”每个计划有不同的速率每秒请求数和配额每日请求数。然后生成 API Key 并与计划绑定。这样API Gateway 会在入口处就进行限流和配额检查减轻业务 Lambda 的压力。这与我们在业务层实现的配额管理是互补的API Gateway 管“粗”粒度的请求频率和次数业务层管“细”粒度的 Token 成本和业务规则。缓存对于某些重复性很高的请求例如询问“今天的日期”可以在 API Gateway 层面开启缓存直接返回缓存结果极大减少后端调用和延迟。DynamoDB 表设计优化主键设计RequestLogs表查询模式通常是“按用户查某段时间的日志”或“查某次具体请求”。因此分区键Partition Key可以设为user_id排序键Sort Key设为timestamp请求时间戳。这样你可以高效地执行Query操作获取某个用户在特定时间范围内的所有请求。GSI全局二级索引如果你需要按request_id快速查找或者需要按model_used进行聚合分析就需要创建相应的 GSI。读写容量与按需模式初期或流量不确定时强烈建议使用“按需容量模式”DynamoDB 会根据实际流量自动伸缩。如果流量模式非常规律且可预测才考虑使用预置容量模式以节省成本。4.3 监控、告警与成本控制服务上线后必须建立监控体系。1. 核心监控指标使用 Amazon CloudWatchLambdaInvocations调用次数Errors错误次数Duration持续时间Throttles被限制次数。为Errors和持续高Duration设置告警。API Gateway4XXError,5XXError,Latency延迟Count请求数。关注错误率和 P99 延迟。DynamoDBReadThrottleEvents,WriteThrottleEvents读写被限制事件ConsumedReadCapacityUnits,ConsumedWriteCapacityUnits消耗的容量单位。如果使用预置模式这些指标对避免限流至关重要。2. 业务指标监控除了基础设施指标更需要关注业务指标。你可以在 Lambda 函数中使用CloudWatch Embedded Metric Format (EMF)来发布自定义指标。每次请求记录TokenUsed,ModelName,UserId。在 CloudWatch 中你可以基于这些自定义指标创建仪表盘直观看到不同模型的使用占比、Top N 用户的 Token 消耗、总体成本趋势。3. 成本控制告警这是使用 OpenAI 代理最关键的环节之一。你可以在 AWS Cost Explorer 中设置预算。创建月度总预算告警。更精细的做法由于 DynamoDB 记录了每次调用的 Token 和模型你可以近乎实时地计算累计成本。可以写一个定时触发的 Lambda 函数通过 CloudWatch Events每天汇总前一天的 Token 消耗乘以官方单价计算出日成本并发送到 SNS通知服务或 Slack。一旦发现某天或某个用户的成本异常飙升立即触发告警。5. 常见问题、故障排查与进阶优化在实际运行中你一定会遇到各种问题。这里总结了一些典型场景和排查思路。5.1 常见问题速查表问题现象可能原因排查步骤与解决方案调用代理返回401 Unauthorized1. 请求头中未携带X-API-Key。2. API Key 错误或已失效。3. DynamoDB 中用户状态为禁用。1. 检查前端/客户端代码确认请求头设置正确。2. 在 DynamoDBUsers表中核对 Key 的哈希值。3. 检查用户记录的is_active字段。调用代理返回429 Too Many Requests1. 用户在业务层配额已用尽。2. API Gateway 使用计划中的速率或配额超限。1. 检查 DynamoDB 中用户的quota_used是否大于等于quota_total。2. 在 API Gateway 控制台检查该 API Key 关联的使用计划。调用代理返回504 Gateway Timeout1. Lambda 函数执行超时默认3秒可能不够。2. 网络问题导致与 OpenAI 通信缓慢。1. 检查 Lambda 函数的超时配置建议设为 30 秒。2. 查看 Lambda 的 CloudWatch 日志看函数是否在超时前打印了日志。增加 Lambda 内存可能提升网络性能。响应速度很慢尤其是第一次调用Lambda 冷启动。函数代码包大或依赖的层Layer多。1. 优化代码包大小移除不必要的依赖。2. 使用 Lambda 层管理公共依赖。3. 对生产环境关键函数配置预置并发。DynamoDB 出现ThrottlingException表或索引的读写容量不足请求速率超过了预置容量。1. 切换到“按需容量模式”以自动扩展。2. 如果使用预置模式分析访问模式可能需要增加容量或优化分区键设计使请求更均匀分布。3. 在代码中对 DynamoDB 操作实现指数退避重试。OpenAI 返回429错误但代理未重试代理层的错误处理或重试逻辑未生效。检查 Lambda 函数中针对openai.error.RateLimitError的异常捕获和重试逻辑是否正确实现。查看 CloudWatch 日志确认错误类型。5.2 性能与成本进阶优化当服务稳定后可以追求更优的性能和更低的成本。1. 实现响应流式传输StreamingOpenAI 的 Chat Completions API 支持以 Server-Sent Events (SSE) 形式流式返回 tokens。这对于需要实时显示生成结果的场景如聊天界面体验极佳。在代理层实现流式转发有一定挑战Lambda 限制Lambda 的响应负载有 6MB 大小限制且响应需要是完整的。对于流式响应你需要使用Lambda Function URL 配合响应流Lambda Response Streaming或者考虑使用HTTP API Gateway 的HTTP_PROXY集成直接将请求透传给后端但这会绕过你的业务逻辑。常见折中方案业务 Lambda 仍以非流式方式调用 OpenAI获取完整响应后再以“伪流式”的方式通过 WebSocket 连接使用 API Gateway WebSocket API将内容分片推送给客户端。这增加了复杂度但保留了业务逻辑处理能力。2. 引入缓存层对于高度重复或结果确定的查询例如“将‘Hello World’翻译成中文”缓存可以极大提升响应速度和降低成本。缓存策略在 DynamoDB 中设计一个Cache表。Key 可以是模型名 Prompt 的 MD5 哈希Value 是完整的响应 JSON并设置合理的 TTL例如24小时。缓存流程Lambda 在处理请求时先根据 Key 查询缓存。如果命中且未过期直接返回缓存结果并记录一次“缓存命中”。如果未命中则调用 OpenAI将结果存入缓存后再返回。注意事项缓存只适用于确定性的请求。对于创造性写作、代码生成等每次输出都可能不同的场景不宜开启缓存或需要非常谨慎地设计缓存键例如将“温度”参数temperature也包含在缓存键中。3. 多模型路由与降级策略你的代理不应该只绑定一个 OpenAI 模型。可以设计一个路由策略在用户请求或用户配置中指定模型优先级列表如[“gpt-4”, “gpt-3.5-turbo”]。Lambda 函数首先尝试调用gpt-4。如果gpt-4返回速率限制错误或超时则自动降级使用gpt-3.5-turbo重试。这既能保证关键请求优先使用最强模型又能在高负载时通过降级保障服务的整体可用性。4. 请求批处理Batching如果你的应用场景是处理大量独立的、不紧急的文本生成任务例如为一批商品生成描述可以考虑实现一个异步批处理队列。前端将任务放入一个 Amazon SQS简单队列服务队列。一个专用的“批处理 Lambda 函数”被定时触发或由队列深度触发一次从队列中取出 N 个任务例如10个。将这 N 个任务的 Prompt 组合成一个批处理请求发送给 OpenAI 的 Batch API如果支持或通过精心构造的 Prompt 让单个对话完成多个任务。处理完成后将结果写回另一个结果队列或数据库并通知前端。这样做可以显著减少 API 调用次数利用 OpenAI 可能提供的批量折扣并更好地控制速率。构建一个aws-openai这样的代理服务远不止是技术上的拼接。它要求你在云架构、安全、成本优化和用户体验之间找到最佳平衡点。这个项目提供了一个极佳的起点和设计范式。当你根据自己业务的独特需求一步步完善它的认证、监控、缓存和容错机制时你构建的不仅仅是一个 API 代理而是一个坚固、可控、面向未来的 AI 能力中台。这其中的设计思路和踩坑经验对于任何想要在云上构建复杂、可靠服务的开发者来说都是一笔宝贵的财富。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2598242.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…