GAAI框架:为AI编码工具引入治理层,实现可控的软件交付

news2026/5/3 18:06:31
1. 项目概述一个为AI编码工具注入“纪律”的治理框架如果你和我一样在过去一年里深度使用过Claude Code、Cursor、Windsurf这类AI编码工具那你一定体验过那种“冰火两重天”的感觉。一方面它们能瞬间生成代码、修复bug生产力爆棚另一方面你肯定也经历过“AI自由发挥”带来的噩梦它自作主张改了你没让改的文件把上个会话讨论好的架构忘得一干二净或者交付了一个根本无法验证是否满足需求的“黑盒”功能。这种“速度”与“失控”的并存正是当前AI辅助开发的核心痛点。GAAI框架全称Governed Agentic AI Infrastructure就是为了解决这个痛点而生的。它不是另一个AI代理编排框架如LangGraph也不是一个需要你学习新SDK的开发平台。它的核心思想极其简单在你现有的任何项目根目录下放入一个名为.gaai/的文件夹。这个文件夹里只有Markdown、YAML和Bash脚本。没有依赖没有安装包没有外部服务。它的唯一使命就是为你正在使用的AI编码工具无论是Claude Code还是Cursor套上一套可靠的“治理层”将散漫的AI对话转变为可预测、可审计、可重复的软件交付流水线。你可以把它理解为一个“AI编码纪律委员会”。它通过两个核心的、上下文隔离的代理Discovery和Delivery以及一个作为“神圣契约”的待办事项清单Backlog确保AI只建造你明确要求的东西并且每一步都经过验证。无论你是独立开发者、小团队的技术负责人还是任何受够了AI“胡作非为”的工程师GAAI提供的这套轻量级、文件驱动的治理方案都值得你花30分钟了解一下。2. 核心设计理念双轨制与上下文隔离GAAI的整个架构建立在两个基石之上双轨制工作流和严格的上下文隔离。理解这两点就理解了GAAI为什么能解决传统AI编码的“漂移”问题。2.1 双轨制想清楚与做清楚传统上我们与AI编码工具的交互是线性的、混合的。我们在同一个聊天会话里既讨论需求“我想加个用户认证”又执行实现“好现在去修改auth.py文件”。这种混合导致了责任的模糊和记忆的污染。GAAI强制将这个过程拆分为两条独立的轨道发现轨道由Discovery Agent负责。你在这个阶段与AI进行纯对话目标是澄清和定义要构建什么。输出物是一个结构化的“用户故事”包含清晰的验收标准并被放入Backlog。关键限制是Discovery Agent只思考不执行任何代码修改。交付轨道由Delivery Agent负责。它从Backlog中领取已细化的故事并在一个全新的、隔离的进程中执行。它内部进一步拆分为规划、实现、QA等子代理严格按计划执行并验证所有验收标准。关键限制是Delivery Agent只执行不决定或更改范围。这种分离确保了“决策”和“执行”的权责分明。Discovery可以天马行空地和你讨论而不用担心它的想法会污染执行环境Delivery则像一个可靠的工匠严格按图纸施工不会自作主张。2.2 上下文隔离根治“记忆污染”的良药“上下文污染”是AI代理的顽疾。上一个会话的临时指令、未完成的实验代码、无关的讨论都可能被带入下一个任务导致不可预测的行为。GAAI的解决方案既朴素又彻底物理进程隔离。当你运行/gaai-daemon启动交付守护进程时它会为每一个待办故事启动一个全新的Claude Code进程通过tmux或终端。这个新进程没有任何之前的聊天历史加载的是专为交付任务优化的系统提示词。Discovery会话的上下文被完全屏蔽在外。这就好比Discovery是在会议室和白板上与架构师画图讨论。Delivery是拿着最终图纸的施工队进入工地他们看不到会议室白板上那些被擦掉的草图、争论的笔记只看到最终确定的施工图。这种隔离通过操作系统的进程边界实现是目前最可靠、最彻底的隔离方式从根本上杜绝了“记忆漂移”。2.3 待办清单不可篡改的契约连接这两条轨道的就是Backlog。它不是一个简单的任务列表而是一个不可篡改的、结构化的契约。所有东西在建造前必须先进入Backlog成为一个带有唯一ID如E03S01、清晰标题和可测试验收标准的“故事”。Backlog文件位于.gaai/project/contexts/backlog/是纯YAML格式人类和AI都可读可写并通过Git进行版本控制。它的存在使得项目的完整构建历史变得可追溯、可审计。任何没有Backlog条目对应的代码变更在GAAI的视角下都是“未经授权的”。实操心得Backlog即文档我最初把Backlog仅仅当作任务列表后来发现它更大的价值是作为项目文档。每个完成的故事及其验收标准构成了项目功能演进的精确编年史。新成员加入或我自己隔了很久回头看通过翻阅Backlog的YAML文件能立刻理解每个功能为什么做、怎么做、验收条件是什么这比靠模糊的Git提交信息或记忆要可靠得多。3. 框架结构深度解析.gaai/文件夹里有什么把.gaai/文件夹拖进项目后它的内部结构是你理解其能力的关键。整个框架分为两大块核心框架和项目数据这种分离保证了框架本身可以独立更新而你的项目定制不会丢失。your-project/ └── .gaai/ ├── core/ # 框架引擎从中央仓库同步可更新 │ ├── README.md # 起点人类和AI的入门指南 │ ├── GAAI.md # 完整参考手册 │ ├── agents/ # 代理定义Discovery, Delivery, Bootstrap │ ├── skills/ # 47个可复用的“技能”单元 │ ├── contexts/rules/ # 框架级规则如代码风格、安全规范 │ ├── workflows/ # 核心工作流定义交付循环、引导 │ ├── scripts/ # Bash工具脚本安装、守护进程管理 │ └── compat/ # 针对不同AI工具的薄适配层 └── project/ # 你的项目数据永不随框架更新被覆盖 ├── agents/ # 自定义项目代理 ├── skills/ # 自定义项目技能 ├── contexts/ │ ├── memory/ # 持久化记忆决策、模式、上下文 │ ├── backlog/ # 你的待办事项清单 │ └── artefacts/ # 生成物故事、史诗、计划、报告 └── hooks/ # 项目特定的Git钩子3.1 Core目录框架的“发动机”core/目录是GAAI的大脑和肌肉它包含了让一切运转起来的逻辑。这里有几个关键部分需要深入了解Agents这里定义了Discovery和Delivery代理的“人格”与行为准则。它们本质上是高度优化的系统提示词Markdown文件规定了代理的角色、目标、约束和操作流程。例如delivery-agent.md会严格规定“你必须从Backlog中读取故事”、“你必须按规划-实现-QA的顺序执行”、“你绝不能修改验收标准之外的范围”。Skills这是GAAI的“技能库”目前有47个预置技能。每个技能都是一个自包含的、可执行的指令单元例如skill.write-unit-test.md描述了如何为一个函数编写单元测试skill.refactor-module.md描述了安全重构一个模块的步骤。Delivery代理在执行任务时会组合调用这些技能。你可以把Skills看作给AI的标准化操作程序它保证了不同任务、不同时间执行相同操作时输出质量的一致性。Workflows定义了核心的工作流程尤其是“交付循环”。它详细描述了Delivery Agent如何从一个Backlog故事开始逐步进行任务分析、技术规划、代码实现、质量验证并最终完成故事的全过程。这是框架的“主循环”逻辑。Scripts所有Bash工具脚本。最重要的是install.sh和daemon-setup.sh。这些脚本处理了框架的部署、适配器安装和守护进程配置等脏活累活。3.2 Project目录你的“工作区”project/目录完全属于你框架更新时不会触碰这里。这是你进行定制和存储项目特定数据的地方。Contexts/Backlog你的核心工作队列。每个故事一个YAML文件状态可以是proposed提议、refined已细化、in-progress进行中、done完成、blocked阻塞。Contexts/Memory这是GAAI的“持久化记忆”系统。它不是聊天历史而是结构化记忆。例如当Discovery Agent决定项目使用SQLAlchemy作为ORM时这个决策会被记录在memory/technical-decisions.yml中。之后无论是Discovery还是Delivery在涉及数据库操作时都会优先查阅这个记忆文件确保技术栈决策的一致性避免重复讨论或出现矛盾。Contexts/Artefacts存放所有工作产出物如详细的技术设计文档plan-*.md、测试报告等。这些是交付过程的审计轨迹。Skills Agents你可以在这里创建项目专属的技能和代理。比如如果你的项目有特殊的部署流程可以创建一个skill.deploy-to-staging.md。如果你的项目要求所有API响应必须遵循特定的包装格式可以创建一个定制化的delivery-agent-for-api.md在其中强化这条规则。注意事项定制与覆盖的优先级GAAI采用“项目优先”的加载策略。当框架运行时它会先检查project/目录下是否有对应的自定义文件如project/agents/my-agent.md如果有则使用自定义版本如果没有才回退到使用core/中的默认版本。这让你可以在不修改核心框架的情况下深度定制GAAI的行为以适应项目需求。但切记自定义文件需要遵循与核心文件相同的结构和约定否则可能导致代理行为异常。4. 完整工作流实操从零构建一个功能理论说得再多不如亲手跑一遍。让我们以一个真实的场景为例演示如何使用GAAI完整地交付一个功能为Web API添加一个全局的请求频率限制中间件限制为每分钟100次请求超出返回429状态码。4.1 第一步安装与引导首先在你的项目根目录执行安装。最快捷的方式是直接让AI助手比如Claude Code帮你运行安装脚本# 将以下指令粘贴给你的AI助手如Claude Code rm -rf /tmp/gaai git clone https://github.com/Fr-e-d/GAAI-framework.git /tmp/gaai bash /tmp/gaai/.gaai/core/scripts/install.sh --target . --tool claude-code --yes rm -rf /tmp/gaai安装脚本会自动完成几件事将.gaai/文件夹复制到你的项目根目录。根据你指定的工具如claude-code在相应位置创建适配文件。对于Claude Code会在项目根目录创建CLAUDE.md并在.claude/commands/目录下注册/gaai-discover和/gaai-deliver等命令。输出引导指令通常是让你或AI助手去阅读.gaai/core/README.md。接下来你需要进行“项目引导”。在AI助手中输入/gaai-bootstrap这个命令会启动Bootstrap Agent它会扫描你的项目结构理解技术栈比如是Python Flask项目还是Node.js Express项目并将这些信息初始化到project/contexts/memory/中。这一步为后续的Discovery和Delivery提供了关键的上下文。4.2 第二步发现与定义Discovery现在开始定义我们的功能。在AI助手中输入/gaai-discover这会激活Discovery Agent。你会看到提示符变为Discovery表示你已进入发现轨道。接着你描述需求“为我们的API添加全局请求频率限制。要求每个用户每分钟最多100次请求超出限制返回HTTP 429状态码。需要作为中间件集成到现有的Express应用中。”Discovery Agent会与你进行几轮对话来澄清细节例如“用户”如何标识是基于IP地址、API密钥还是用户ID限制是否需要区分不同的API端点限流数据是存储在内存中还是需要Redis这样的外部存储以保证分布式一致性在这个过程中Discovery Agent会做几件关键事情查阅记忆它会去project/contexts/memory/中查找已有的技术决策。比如如果记忆里显示项目已经使用了Redis作为缓存它可能会建议使用redis来存储计数器以实现分布式限流。搜索模式它会查看project/contexts/memory/patterns/寻找项目中已有的中间件模式以确保新中间件与现有代码风格一致。生成故事对话结束后它会生成一个结构化的故事文件例如backlog/E03S01-rate-limiting-middleware.yml。这个YAML文件内容大致如下id: E03S01 title: “添加全局用户请求频率限制中间件” status: refined acceptance_criteria: - 当用户请求频率低于100次/分钟时中间件放行请求。 - 当用户频率超过限制时中间件拦截请求并返回429状态码和清晰错误信息。 - 中间件应能基于用户ID从JWT令牌中提取进行区分。 - 限流计数器应使用项目现有的Redis实例进行存储。 - 中间件需集成到app.js的主请求管道中。 - 添加相应的单元测试覆盖正常、超限、无令牌等场景。 context_links: - memory/technical-decisions.yml # 引用已决定使用Redis的决策 - memory/patterns/middleware-structure.yml # 引用现有中间件模式至此Discovery阶段结束。你没有写一行代码但得到了一个清晰、无歧义、可测试的工作定义。4.3 第三步交付与执行Delivery故事已进入Backlog且状态为refined现在可以交付了。你有两种方式方式A单次交付交互式在AI助手中输入/gaai-deliver E03S01这会在当前会话中启动Delivery Agent让它专门处理故事E03S01。你会看到它开始工作读取故事、分析验收标准、制定技术计划、然后开始编码。整个过程你可以实时观察和交互虽然不建议中途干扰。方式B守护进程交付自动化、并行对于已细化好的多个故事或者你想让交付在后台自动进行可以使用守护进程。# 首先确保你的项目是一个Git仓库并且有staging分支 git checkout -b staging git push -u origin staging # 运行守护进程设置脚本通常只需一次 bash .gaai/core/scripts/daemon-setup.sh # 启动守护进程默认并行3个任务 /gaai-daemon守护进程启动后它会自动打开一个tmux监控面板。它会持续扫描backlog/目录下状态为refined的故事然后为每个故事启动一个独立的Claude Code进程在独立的tmux窗口或pane中来执行交付。让我们深入一个Delivery Agent的内部工作流程规划子代理首先它仔细阅读E03S01的故事文件特别是验收标准。然后它会生成一个详细的执行计划artefacts/plan-E03S01.md可能包括选择express-rate-limit库、设计中间件函数签名、确定Redis连接配置、规划测试用例等。实现子代理接着切换到实现模式。它会严格按计划行事检查package.json添加express-rate-limit依赖。在middleware/目录下创建rateLimit.js文件实现中间件逻辑。修改app.js引入并使用这个新中间件。关键动作在修改任何文件前它会运行相关的测试确保不破坏现有功能。QA子代理最后进行质量验证。它会运行所有验收标准对应的测试编写并运行针对新中间件的单元测试。可能启动一个测试服务器用脚本模拟高并发请求验证429响应是否正确触发。检查代码风格是否符合项目规则来自contexts/rules/。 只有所有验收标准都通过它才会将故事状态标记为done并提交代码到staging分支。在整个过程中你可以在tmux监控面板里看到所有并行任务的状态进行中、成功、失败。交付是完全隔离的即使某个任务失败也不会影响其他任务或你的主开发会话。4.4 第四步验收与合并当守护进程报告E03S01完成或者/gaai-deliver执行完毕你需要进行最终验收。代码审查查看Delivery Agent生成的提交。由于有清晰的计划和验收标准审查变得非常高效你只需要关注实现是否完全符合之前共同定义的故事。运行测试在本地运行完整的测试套件确保一切正常。合并到主分支如果一切满意将staging分支的更改合并到你的主开发分支如main。至此一个由AI编码工具构建、但全程受GAAI治理的功能就可靠地交付了。实操心得守护进程是“游戏规则改变者”最初我手动使用/gaai-deliver后来切换到守护进程模式效率提升了一个数量级。它的价值在于并行化我可以一次性在Backlog中细化3-5个小功能或bug修复然后启动守护进程去开会或处理其他事情。回来时它们可能都完成了。上下文专注我的主Claude Code会话可以完全专注于复杂的Discovery讨论或探索性编程而不用被具体的实现任务打断。可靠性守护进程内置了重试和错误处理逻辑。如果一个交付因网络或临时问题失败它会记录并可能重试而手动操作时我可能就忘了。5. 技能系统与记忆系统GAAI的“可复用智慧”GAAI的强大不仅在于流程更在于其沉淀和复用知识的能力这主要通过技能系统和记忆系统实现。5.1 技能系统标准化AI的操作手册core/skills/目录下的47个技能文件是GAAI的宝贵资产。每个技能都是一个微型的、针对特定任务的“最佳实践指南”。例如skill.write-unit-test.md不仅告诉AI“要写测试”还详细说明了步骤先理解函数输入输出再构思边界用例然后使用项目的测试框架如Jest、pytest的特定语法最后确保测试描述清晰。skill.refactor-extract-function.md指导AI如何安全地提取函数识别重复代码块确定新函数的参数和返回值确保不影响现有调用并更新相关注释。skill.handle-error-gracefully.md教导AI在代码中实现优雅的错误处理包括日志记录、用户友好的错误消息和适当的回滚操作。为什么技能如此重要在没有技能系统时AI对于“写一个测试”这样的任务输出质量波动很大。有了技能文件相当于给了AI一份详细的“岗位操作手册”无论哪个AI代理执行无论何时执行都能产出符合统一标准和质量的结果。你可以根据自己项目的技术栈和规范轻松地复制并修改这些技能文件到project/skills/下实现团队规范的固化。5.2 记忆系统项目的“集体大脑”记忆系统project/contexts/memory/是GAAI解决“会话失忆”问题的核心。它不是一个聊天记录转储而是一个结构化的知识库主要包含技术决策记录为什么选择某个库、为什么采用某种架构。例如“为什么用Prisma而不是TypeORM”。代码模式记录项目中反复出现的、被认可的良好代码模式。例如“我们如何定义RESTful控制器”、“事件监听器的标准格式是什么”。业务逻辑上下文记录复杂的业务规则和领域知识。例如“‘用户状态’字段的枚举值及其转换规则”。记忆是如何被创建和使用的创建通常在Discovery阶段当你和AI做出一个重要决定时Discovery Agent会提示“这是一个重要的技术决策是否要记录到记忆库中”。你同意后它会以结构化的格式YAML或Markdown将其保存到memory/目录。使用在后续的Discovery或Delivery中代理在开始工作前会主动去查询相关的记忆文件。比如当要处理用户认证相关的任务时它会自动加载memory/authentication-patterns.yml确保与之前的决策保持一致。避坑技巧有效利用记忆的层次不要把所有东西都扔进一个记忆文件。我建议按层次组织memory/decisions/存放重大技术决策。memory/patterns/code/存放代码模式。memory/patterns/api/存放API设计模式。memory/domain/存放业务领域知识。 同时为记忆文件起一个清晰的名字并在文件开头用YAML front-matter或注释说明该记忆的适用范围和有效期。例如一个关于“临时使用的日志库”的决策可以标记为deprecated_after: 2024-06-01防止过期记忆误导后续工作。6. 高级配置与定制化指南GAAI开箱即用但要发挥其最大威力需要根据你的项目和团队进行定制。6.1 适配不同的AI编码工具GAAI的核心逻辑是工具无关的它通过compat/目录下的薄适配层与不同工具交互。对于Claude Code深度集成安装时会创建CLAUDE.md和.claude/commands/。CLAUDE.md是主入口文件Claude Code启动时会自动加载它。其中的命令如/gaai-discover会调用.gaai/core/workflows/中的对应逻辑。对于Cursor、Windsurf等AGENTS.md兼容安装时会创建或更新AGENTS.md文件。你需要手动或通过提示在这些工具的“Agent”设置中将AGENTS.md指定为代理规则文件。之后你可以通过输入特定的激活提示词如“Activate GAAI Discovery mode”来进入相应模式。对于其他工具即使没有官方适配器你也可以直接让AI助手阅读.gaai/core/README.md来理解框架并手动遵循其工作流。Backlog和Memory文件是纯文本任何工具都能读写。6.2 定制项目规则与约束project/contexts/rules/目录是你放置项目专属约束的地方。这里的规则会覆盖core/contexts/rules/中的默认规则。你可以创建诸如rules.coding-style.yml定义缩进、命名规范、注释要求等。rules.security.md禁止使用某些不安全的函数要求对用户输入进行验证等。rules.dependencies.md规定添加新依赖的审批流程或禁止使用某些许可证的库。Delivery Agent在执行任务时会强制遵守这些规则。例如如果规则要求“所有数据库查询必须使用参数化查询以防止SQL注入”那么AI在编写SQL代码时就会自动遵循。6.3 集成到现有CI/CD流水线GAAI本身不替代CI/CD但可以与它们完美结合。在CI中验证Backlog你可以在CI脚本中添加一个步骤检查是否有代码变更但没有对应的、状态为done的Backlog故事ID。这可以作为一个门禁强制要求所有功能开发都经过GAAI流程。自动化验收测试Delivery Agent生成的验收测试可以集成到你的CI测试套件中确保每次构建都符合当初定义的标准。使用Backlog状态触发流程你可以配置CI工具当Backlog中某个故事状态变为done时自动部署到测试环境并通知相关人员验收。6.4 性能调优与故障排除守护进程并发数默认并发3个任务。如果你的机器性能强大可以通过/gaai-daemon --max-concurrent 5增加。如果资源紧张减少到1可以避免过载。处理交付失败如果一个故事交付失败守护进程会将其状态置为blocked并在artefacts/中生成失败报告。你需要手动审查报告解决问题可能是模糊的验收标准、环境问题或框架bug然后将故事状态改回refined守护进程会重新拾取它。记忆库膨胀定期回顾和清理记忆库。将过时的决策标记为archived将通用的模式沉淀到core/skills/中作为共享技能。一个臃肿的记忆库会降低代理检索相关信息的效率。7. 常见问题与实战排坑记录在实际使用GAAI的几个月里我踩过不少坑也总结了一些解决方案。7.1 问题AI代理不遵守GAAI规则直接开始写代码。排查与解决检查适配器是否正确加载对于Claude Code确认项目根目录存在CLAUDE.md文件并且其内容正确引用了.gaai框架。尝试重启Claude Code应用。检查代理的“注意力”有时AI会“忽略”系统提示。在对话中明确提醒它“请严格按照GAAI框架的规则操作。你当前应该处于Discovery模式只讨论需求不执行代码。请先确认你已阅读.gaai/core/agents/discovery-agent.md。”强化规则在project/contexts/rules/中添加更严格的规则文件例如rules.strict-mode.md其中用严厉的口吻强调违反流程的后果并在每次任务开始时让AI重新确认该规则。7.2 问题交付的代码质量不稳定有时很好有时很糟。排查与解决检查技能的使用确认Delivery Agent在关键步骤如写测试、重构时是否明确调用了对应的技能文件。你可以在artefacts/下的计划报告中查看其执行步骤。细化验收标准代码质量差往往源于模糊的验收标准。“实现用户登录”是模糊的。“实现用户登录使用JWT密码加盐哈希存储提供/api/loginPOST接口返回{token, user_id}”是清晰的。在Discovery阶段多花时间打磨验收标准。定制项目技能将你们团队公认的“好代码”模式写成自定义技能。例如project/skills/skill.api-response-format.md明确规定所有API控制器的响应必须包裹在{data: ..., code: 0, message: success}的结构中。让AI在实现时遵循这个技能。7.3 问题记忆系统似乎没起作用AI重复询问已决定过的事情。排查与解决检查记忆文件的格式和位置确保记忆文件是YAML或Markdown格式并放在正确的project/contexts/memory/子目录下。文件名最好具有描述性。检查记忆的关联性在创建Backlog故事时确保在context_links字段正确引用了相关的记忆文件。Discovery和Delivery代理会根据这些链接去主动加载记忆。主动提示如果重要的记忆没有被自动加载在对话中可以直接告诉AI“关于数据库连接池的配置我们之前已经决定使用HikariCP相关决策记录在memory/decisions/database-pool.yml中请先阅读该文件。”7.4 问题守护进程/gaai-daemon启动失败或没有反应。排查与解决检查前置条件确保项目是Git仓库并且存在staging分支。运行git branch确认。检查Claude Code CLI守护进程依赖claude命令行工具。在终端运行claude --version确认已安装且可在PATH中找到。即使你平时用Cursor做DiscoveryDelivery Daemon目前也需要Claude Code CLI来运行。检查tmux守护进程默认使用tmux来管理并行会话。运行tmux -V确认已安装。在macOS上如果未安装tmux守护进程会尝试回退到使用原生Terminal.app但功能可能受限。查看日志守护进程会在project/contexts/artefacts/daemon.log中记录运行日志。检查该文件是排查问题的第一步。7.5 问题团队协作时如何共用GAAI配置解决方案 将.gaai/project/目录下的所有自定义内容agents/,skills/,contexts/rules/,contexts/memory/中的核心部分纳入版本控制Git。而.gaai/core/目录可以通过.gitignore忽略或者通过子模块git submodule引入以便独立更新。团队新成员克隆项目后只需运行一次安装脚本或手动复制.gaai/就能获得完全相同的GAAI配置和项目记忆保证协作的一致性。GAAI框架带来的最大改变是让我从“AI编码的监督者”变成了“AI编码的架构师和产品经理”。我不再需要紧盯着AI写的每一行代码而是专注于前期更重要的需求澄清和设计决策。一旦清晰的契约Backlog故事达成我就可以信任这套系统去可靠地执行。它可能增加了最初的一点点流程开销但这点开销被后续在质量、可预测性和团队协作上带来的巨大收益完全覆盖。对于任何严肃的、希望规模化使用AI辅助开发的项目来说引入这样的治理层不再是可选项而是一个必选项。

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