跳转到内容

AI 编程

2 篇包含标签 "AI 编程" 的文章

AI 编程助手的幻觉问题:如何用 OpenSpec 实现规范驱动开发

AI 编程助手的幻觉问题:如何用 OpenSpec 实现规范驱动开发

Section titled “AI 编程助手的幻觉问题:如何用 OpenSpec 实现规范驱动开发”

AI 编程助手虽然强大,但常常生成不符合实际需求、违反项目规范的代码。本文分享 HagiCode 项目如何通过 OpenSpec 流程实现”规范驱动开发”,用结构化的提案机制显著减少 AI 幻觉风险。

用过 GitHub Copilot 或 ChatGPT 写代码的同学可能都有过这样的经历:AI 生成的代码看起来很漂亮,但真正用起来却问题百出。可能是用错了项目里的某个组件,可能是忽略了团队的编码规范,也可能是基于一些不存在的假设写了大段逻辑。

这就是所谓的”AI 幻觉”问题——在编程领域,它表现为生成看似合理但实际上不符合项目实际情况的代码。

其实这事儿也挺无奈的。AI 编程助手越来越普及,这个问题也就越发严重了。毕竟,AI 缺乏对项目历史、架构决策和编码规范的理解,而自由度过高又容易让它”创造性”地生成不符合实际的代码。这和写文章倒是挺像的,没有章法就容易写得天马行空,可实际上并不是那么回事儿。

为了解决这些痛点,我们做了一个大胆的决定:不是试图让 AI 更聪明,而是给它套上一个”规范”的笼子。这个决定带来的变化,可能比你想象的还要大——稍后我会具体说。

本文分享的方案来自我们在 HagiCode 项目中的实践经验。HagiCode 是一个开源的 AI 代码助手项目,致力于通过结构化的工程实践来解决 AI 编程中的实际问题。

在深入解决方案之前,咱们先看看问题到底出在哪。毕竟知己知彼,方能百战不殆,只是这话用在 AI 身上,好像也有点意思。

AI 模型训练时用的是公开的代码库,但你的项目有它自己的历史、约定和架构决策。这些”隐性知识” AI 没法直接获取,所以生成的代码往往和项目实际情况脱节。

这也不能全怪 AI,毕竟它又没在你们项目待过,哪知道你们那些江湖规矩呢?就像新来的实习生,不懂规矩也正常,只是代价可能有点大罢了。

当你问 AI”帮我实现一个用户认证功能”时,它可能生成任何形式的代码。没有明确的约束,AI 就会按照它”认为”合理的方式去实现,而不是按照你项目的要求。

这就像是让一个从未学过你项目规范的人自由发挥,能不出问题吗?其实也不是它不负责任,只是它压根不知道什么是责任。

AI 生成代码后,如果没有经过结构化的审查流程,那些基于错误假设的代码就会直接进入代码库。等到测试甚至生产环境才发现问题,代价就太大了。

这无异于亡羊补牢,只是羊都已经跑光了,补牢又有什么用呢?这道理谁都懂,可真正做起来,又总觉得麻烦。毕竟在事情变坏之前,谁愿意多花时间呢?

HagiCode 选择 OpenSpec 作为解决方案,核心思路是:所有代码变更必须通过结构化的提案流程,把抽象的想法转化为可执行的实施计划。

这话说得挺高大上的,其实就是让 AI 在写代码之前,先把需求文档写好罢了。毕竟凡事预则立,不预则废,古人诚不我欺。

OpenSpec 是一个基于 npm 的命令行工具(@fission-ai/openspec),它定义了一套标准的提案文件结构和验证机制。简单说,就是让 AI 在写代码之前,先”写好需求文档”。

OpenSpec 通过一个三步流程来确保提案质量:

Step 1:初始化提案 - 设置会话状态为 Openspecing Step 2:中间处理 - 保持 Openspecing 状态,逐步完善工件 Step 3:完成提案 - 转换到 Reviewing 状态

这个设计有个很巧妙的细节:第一步使用的是 ProposalGenerationStart 类型,完成后不会触发状态转换。这确保了整个多步流程完成前,不会过早进入审查阶段。

其实这个细节也挺有意思的,就像做菜一样,火候没到就揭锅盖,肯定是什么都做不好的。只有耐心一点,一步一步来,最后才能做出一道好菜。

// HagiCode 项目中的实现
public enum MessageAssociationType
{
ProposalGeneration = 2,
ProposalExecution = 3,
/// <summary>
/// 标记三步提案生成流程的开始
/// 完成后不会转换到 Reviewing 状态
/// </summary>
ProposalGenerationStart = 5
}

每个 OpenSpec 提案都遵循相同的目录结构:

openspec/
├── changes/ # 活跃和归档的变更
│ ├── {change-name}/
│ │ ├── proposal.md # 提案描述
│ │ ├── design.md # 设计文档
│ │ ├── specs/ # 技术规范
│ │ └── tasks.md # 可执行任务清单
│ └── archive/ # 归档的变更
└── specs/ # 独立的规范库

根据 HagiCode 项目的统计,目前已经有 4000+ 个归档变更和 15 万+ 行规范文件。这些历史积累不仅让 AI 有章可循,也为团队提供了宝贵的知识库。

这就像是古人留下的典籍,读多了自然就能悟出点门道来。只是现在这典籍不是写在竹简上,而是存放在文件里罢了。

系统实现了多层验证来确保提案质量:

// 验证必需文件存在
ValidateProposalFiles()
// 验证执行前提条件
ValidateExecuteAsync()
// 验证启动条件
ValidateStartAsync()
// 验证归档条件
ValidateArchiveAsync()
// 提案名称格式验证(kebab-case)
ValidateNameFormat()

这些验证就像是层层把关的守门人,只有真正合格的提案才能通过。虽然看起来繁琐,可总比让糟糕的代码进入代码库要强吧?

HagiCode 中的 AI 执行时使用预定义的 Handlebars 模板,这些模板包含明确的步骤指导和保护措施。比如:

  • 禁止在未理解用户意图时继续
  • 禁止生成未验证的代码
  • 要求在名称无效时重新提供
  • 如果变更已存在,建议使用继续命令而不是重新创建

这种”带着脚镣跳舞”的方式,反而让 AI 更聚焦于理解需求和生成符合规范的代码。其实约束这东西,也不一定是坏事,毕竟自由过头了就容易乱套。

实践:如何在项目中使用 OpenSpec

Section titled “实践:如何在项目中使用 OpenSpec”
Terminal window
npm install -g @fission-ai/openspec@1
openspec --version # 验证安装

在项目根目录会自动创建 openspec/ 文件夹结构。

这步其实也没什么好说的,安装工具嘛,大家都懂。只是记得用 @fission-ai/openspec@1 这个版本,新版本可能有坑,毕竟稳定压倒一切。

在 HagiCode 的对话界面中,使用快捷命令:

/opsx:new

或者指定变更名称和目标仓库:

/opsx:new "add-user-auth" --repos "repos/web"

创建提案这事儿,就像写文章列提纲一样,有了提纲后面就好写了。只是很多人喜欢直接开始写,写到一半才发现思路不通,那才叫头疼。

使用 /opsx:continue 逐步生成所需的工件:

proposal.md - 描述变更的目的和范围

# Proposal: Add User Authentication
## Why
当前系统缺少用户认证功能,无法保护敏感 API。
## What Changes
- 添加 JWT 认证中间件
- 实现登录/注册 API
- 更新前端集成

design.md - 详细的技术设计

# Design: Add User Authentication
## Context
当前使用公开 API,任何人均可访问...
## Decisions
1. 选择 JWT 而非 Session...
2. 使用 HS256 算法...
## Risks
- 令牌泄露风险...
- 缓解措施...

specs/ - 技术规范和测试场景

# user-auth Specification
## Requirements
### Requirement: JWT Token Generation
系统 SHALL 使用 HS256 算法生成 JWT 令牌。
#### Scenario: Valid login
- WHEN 用户提供有效凭据
- THEN 系统 SHALL 返回有效的 JWT 令牌

tasks.md - 可执行的任务清单

# Tasks: Add User Authentication
## 1. Backend Changes
- [ ] 1.1 创建 AuthController
- [ ] 1.2 实现 JWT 中间件
- [ ] 1.3 添加单元测试

这些工件其实就像是写文章的草稿,草稿写好了,正文自然就顺畅了。只是很多人不喜欢写草稿,觉得浪费时间,可实际上草稿才是最能理清思路的地方。

完成所有工件后:

/opsx:apply

AI 会读取所有上下文文件,按照 tasks.md 中的清单逐步执行任务。这时候因为有了清晰的规范,生成的代码质量会高很多。

其实到了这一步,事情就已经成了一半了。有了明确的任务清单,剩下的就是按部就班地执行罢了。只是很多人跳过了前面的步骤,直接到这里,那质量自然就难以保证了。

变更完成后:

/opsx:archive

将完成的变更移动到 archive/ 目录,方便以后查阅和复用。

归档这事儿挺重要的,就像把写完的文章好好收起来一样。以后遇到类似的问题,翻一翻以前的记录,可能就有答案了。只是很多人懒得做,觉得麻烦,可实际上这些积累才是最宝贵的财富。

使用 kebab-case 格式,以字母开头,仅包含小写字母、数字和连字符:

  • add-user-auth
  • AddUserAuth
  • add--user-auth

命名规范这东西,说起来也没啥大不了的,只是统一一点总归是好的。毕竟代码这事儿, consistency 很重要,只是很多人不在意罢了。

  1. 在三步流程的步骤 1 使用错误的类型 - 会过早转换状态
  2. 忘记在最后一步触发状态转换 - 会卡在 Openspecing 状态
  3. 跳过审查直接执行 - 应该先验证所有工件完整

这些错误其实都是新手容易犯的,老手自然知道怎么避免。只是新手总有变老手的一天,走了弯路也就罢了,只希望不要走太多弯路就好。

OpenSpec 支持同时管理多个提案,这在处理大型功能时特别有用:

Terminal window
# 查看所有活动变更
openspec list
# 切换到特定变更
openspec apply "add-user-auth"
# 查看变更状态
openspec status --change "add-user-auth"

多变更管理这事儿,就像同时写几篇文章一样,需要一点技巧和耐心。只是习惯了就好了,毕竟人嘛,总能适应的。

了解状态转换有助于排查问题:

Init → Drafting → Openspecing → Reviewing → Executing → ExecutionCompleted → Completed → Archived
  • Openspecing:生成规划中
  • Reviewing:审查中(可反复修改工件)
  • Executing:执行中(应用 tasks.md)

状态机这东西,说白了就是一套规则。规则这东西,有时候挺烦人的,但更多时候是有用的。毕竟没有规矩不成方圆,这话古人早就说过了。

通过 OpenSpec 流程,HagiCode 项目在解决 AI 幻觉问题上取得了显著效果:

  1. 减少幻觉 - AI 必须遵循结构化规范,不能随意生成代码
  2. 提高质量 - 多层验证确保变更符合项目标准
  3. 加速协作 - 归档的变更为后续开发提供参考
  4. 可追溯性 - 每个变更都有完整的提案、设计、规范和任务记录

这套方案不是让 AI 变聪明,而是给它套上”规范”的笼子。实践证明,带着脚镣跳舞,反而跳得更好。

其实这道理也简单,约束不一定是什么坏事。就像写文章,有了格式的约束,反而更容易写出好东西来。只是很多人不喜欢约束,觉得限制了自己的创造力,可实际上创造力也需要土壤才能开花结果。

如果你也在使用 AI 编程助手,并且遇到过类似的问题,不妨试试 OpenSpec。规范驱动开发可能看起来多了一些步骤,但这些前期投入会在代码质量和维护效率上得到数倍的回报。

毕竟,慢一点,有时候反而是快一点。只是很多人不明白这个道理罢了…


如果本文对你有帮助,欢迎来 GitHub 给个 Star。HagiCode 公测已开始,现在安装即可参与体验。


这文章写得也差不多了,其实也没什么特别高深的东西,只是把一些实践经验总结了一下罢了。希望对大家有用,毕竟分享这东西,自己学到了,也让别人学到了,两全其美,何乐而不为呢?

只是文章终究是文章,真正有用的还是实践。毕竟纸上得来终觉浅,绝知此事要躬行,古人诚不我欺…

感谢您的阅读,如果您觉得本文有用,欢迎点赞、收藏和分享支持。 本内容采用人工智能辅助协作,最终内容由作者审核并确认。

GLM-5.1 全面支持与 Gemini CLI 集成:HagiCode 的多模型进化之路

GLM-5.1 全面支持与 Gemini CLI 集成:HagiCode 的多模型进化之路

Section titled “GLM-5.1 全面支持与 Gemini CLI 集成:HagiCode 的多模型进化之路”

本文介绍了 HagiCode 平台近期的重要更新——智谱 AI GLM-5.1 模型的全面支持,以及 Gemini CLI 作为第十个 Agent CLI 的成功集成。这两项更新进一步强化了平台的多模型能力和多 CLI 生态。

时间过得真快,大语言模型的发展就像春天的竹子一样,蹭蹭地往上窜。曾经我们还在为”一个能写代码的 AI”而欢呼雀跃,如今已是多模型协同、多工具融合的时代了。这有意思吗?或许吧,毕竟开发者需要的从来都不只是工具本身,而是一种能够适应不同场景、灵活切换的从容。

HagiCode 作为一个 AI 辅助编码平台,最近也算是迎来了两件大事:一是智谱 AI 的 GLM-5.1 模型全面接入,二是 Gemini CLI 正式成为第十个支持的 Agent CLI。这两件事说大不大,说小也不小,只是对于平台的完善而言,总归是好事一桩。

GLM-5.1 是智谱 AI 的最新旗舰模型,相比 GLM-5.0,推理能力更强了,代码理解更深了,工具调用也更顺滑了。更重要的是,它是首个支持图片输入的 GLM 模型——这意味着什么?意味着用户可以直接截图让 AI 看问题,不用再费劲巴力地描述了。这便利性,用过就懂了。

与此同时,HagiCode 通过 HagiCode.Libs.Providers 架构,把 Gemini CLI 成功集成了进来。这是第十个 Agent CLI 了,说实话,能走到这一步,也算是有些许成就感罢了。

值得一提的是,HagiCode 的图片上传功能让用户可以直接截图与 AI 交流。即使运行的是 GLM 4.7 版本,平台依然能够良好运行,并且已经帮助项目完成了许多重要的构建工作。至于 GLM-5.1?那自然会更进一步。

本文分享的方案来自我们在 HagiCode 项目中的实践经验。HagiCode 是一个开源的 AI 辅助编码平台,旨在通过多模型、多 CLI 的架构设计,为开发者提供灵活、强大的 AI 编程助手。项目地址:github.com/HagiCode-org/site

HagiCode 的核心优势之一,就是通过统一的抽象层支持多种不同的 AI 编程 CLI 工具。这种设计的好处,说穿了也就那么回事:新东西能进来,旧东西能留下,代码还不乱。毕竟,谁都希望生活能这样吧?

平台通过 AIProviderType 枚举定义了支持的 CLI 提供商类型:

public enum AIProviderType
{
ClaudeCodeCli = 0, // Claude Code CLI
CodexCli = 1, // GitHub Copilot Codex
GitHubCopilot = 2, // GitHub Copilot
CodebuddyCli = 3, // Codebuddy CLI
OpenCodeCli = 4, // OpenCode CLI
IFlowCli = 5, // IFlow CLI
HermesCli = 6, // Hermes CLI
QoderCli = 7, // Qoder CLI
KiroCli = 8, // Kiro CLI
KimiCli = 9, // Kimi CLI
GeminiCli = 10, // Gemini CLI (新增)
}

可以看到,Gemini CLI 作为第十个成员加入了这个大家庭。每个 CLI 都有独特的特点和适用场景,用户可以根据自己的需求灵活选择。毕竟,条条大路通罗马,只是有的路好走一点,有的路稍微曲折一点罢了。

HagiCode.Libs.Providers 提供了统一的 Provider 接口,让每个 CLI 的集成变得规范而简洁。以 Gemini CLI 为例:

public class GeminiProvider : ICliProvider<GeminiOptions>
{
private static readonly string[] DefaultExecutableCandidates = ["gemini", "gemini-cli"];
private const string ManagedBootstrapArgument = "--acp";
public string Name => "gemini";
public bool IsAvailable => _executableResolver.ResolveFirstAvailablePath(DefaultExecutableCandidates) is not null;
}

这种设计的好处是:

  • 新 CLI 的集成只需要实现一个 Provider 类
  • 统一的生命周期管理和会话池化
  • 自动化的别名解析和可执行文件查找

说穿了,这种设计其实就是把复杂的事情简单化,让生活更轻松一点罢了。

Provider Registry 自动处理别名映射和注册:

if (provider is GeminiProvider)
{
registry.Register(provider.Name, provider, ["gemini-cli"]);
continue;
}

这意味着用户可以使用 geminigemini-cli 两种方式来调用 Gemini CLI,系统会自动识别。这就像你朋友多,有的叫大名,有的叫小名,反正都是他,怎么叫都行。

GLM-5.1 是智谱 AI 的最新旗舰模型,HagiCode 已完成对其的全面支持。

HagiCode 通过 Secondary Professions Catalog 管理所有支持的模型。以下是 GLM 系列的配置:

Model IDNameSupportsImageCompatible CLI Families
glm-4.7GLM 4.7-claude, codebuddy, hermes, qoder, kiro
glm-5GLM 5-claude, codebuddy, hermes, qoder, kiro
glm-5-turboGLM 5 Turbo-claude, codebuddy, hermes, qoder, kiro
glm-5.0GLM 5.0 (Legacy)-claude, codebuddy, hermes, qoder, kiro
glm-5.1GLM 5.1trueclaude, codebuddy, hermes, qoder, kiro

GLM-5.1 的关键特性可以总结为:

  • 独立的版本标识,没有 legacy 包袱
  • 首个支持图片输入的 GLM 模型
  • 更强的推理能力和代码理解
  • 广泛的多 CLI 兼容性

从代码层面来看,GLM-5.1 与 GLM-5.0 的关键区别:

// GLM-5.0 (Legacy) - 有特殊保留逻辑
private const string Glm50CodebuddySecondaryProfessionId = "secondary-glm-5-codebuddy";
private const string Glm50CodebuddyModelValue = "glm-5.0";
// GLM-5.1 - 独立的新模型标识
private const string Glm51SecondaryProfessionId = "secondary-glm-5-1";
private const string Glm51ModelValue = "glm-5.1";

GLM-5.0 带有 “Legacy” 标记,是为了向后兼容而保留的旧版本标识。而 GLM-5.1 是一个全新的独立版本,没有任何历史包袱。这就像有些人,总是活在过去;而有些人,轻装上阵,走得更快罢了。

在 HagiCode 中使用 GLM-5.1 的配置示例:

{
"primaryProfessionId": "profession-claude-code",
"secondaryProfessionId": "secondary-glm-5-1",
"model": "glm-5.1",
"reasoning": "high"
}

HagiCode 的图片支持是通过 SecondaryProfession 的 SupportsImage 属性实现的:

public class HeroSecondaryProfessionSettingDto
{
public bool SupportsImage { get; set; }
}

在 Secondary Professions Catalog 中,GLM-5.1 的配置如下:

{
"id": "secondary-glm-5-1",
"supportsImage": true
}

这意味着用户可以直接上传截图让 AI 分析,比如:

  • 错误信息的截图
  • UI 界面的问题
  • 数据可视化图表
  • 代码运行结果

不用再手动描述问题了,直接截图就行——这个功能的便利性用过就知道了。毕竟,有些事情,说再多不如看一眼。

Gemini CLI 作为第十个 Agent CLI,通过标准的 Provider 架构集成到 HagiCode 中。

Gemini CLI 支持丰富的配置选项:

public class GeminiOptions
{
public string? ExecutablePath { get; set; }
public string? WorkingDirectory { get; set; }
public string? SessionId { get; set; }
public string? Model { get; set; }
public string? AuthenticationMethod { get; set; }
public string? AuthenticationToken { get; set; }
public Dictionary<string, string?> AuthenticationInfo { get; set; }
public Dictionary<string, string?> EnvironmentVariables { get; set; }
public string[] ExtraArguments { get; set; }
public TimeSpan? StartupTimeout { get; set; }
public CliPoolSettings? PoolSettings { get; set; }
}

这些选项覆盖了从基本配置到高级特性的方方面面,用户可以根据自己的需求进行灵活配置。毕竟,每个人的需求都不一样,能灵活一点总是好的。

Gemini CLI 支持 ACP (Agent Communication Protocol) 通信协议,这是 HagiCode 统一的 CLI 通信标准。通过 ACP,不同的 CLI 可以以一致的方式与平台交互,大大简化了集成工作。说穿了,就是把复杂的事情统一化,让大家都能轻松一点罢了。

使用智谱 AI 的模型,需要配置相应的环境变量。

Terminal window
export ANTHROPIC_AUTH_TOKEN="your-zai-api-key"
export ANTHROPIC_BASE_URL="https://open.bigmodel.cn/api/anthropic"
Terminal window
export ANTHROPIC_AUTH_TOKEN="your-aliyun-api-key"
export ANTHROPIC_BASE_URL="https://coding.dashscope.aliyuncs.com/apps/anthropic"

配置完成后,HagiCode 就可以正常调用 GLM-5.1 模型了。这事儿说难也不难,说简单也不简单,反正照着做就是了。

说到实践,最好的例子就是 HagiCode 平台自身的构建流程。HagiCode 的开发过程已经充分利用了 AI 能力:

HagiCode 平台的设计优化得比较好,即使使用 GLM 4.7 也能获得良好的开发体验。平台已帮助完成多个重要构建项目,包括:

  • 多 CLI Provider 的集成
  • 图片上传功能的实现
  • 文档生成和内容发布

这其实也挺好,毕竟不是所有人都需要用最新的东西。适合自己的,才是最好的。

升级到 GLM-5.1 后,这些能力将得到进一步增强:

  • 更强的代码理解能力,减少来回沟通
  • 更准确的依赖分析,一次性指对方向
  • 更高效的错误诊断,快速定位问题
  • 支持图片输入,加速问题描述

这就像从自行车换到汽车,能到的地方是一样的,只是速度和舒适度不一样罢了。

HagiCode.Libs.Providers 提供了统一的注册和使用机制:

services.AddHagiCodeLibs();
var gemini = serviceProvider.GetRequiredService<ICliProvider<GeminiOptions>>();
var codebuddy = serviceProvider.GetRequiredService<ICliProvider<CodebuddyOptions>>();
var hermes = serviceProvider.GetRequiredService<ICliProvider<HermesOptions>>();

这种依赖注入的设计让各个 CLI 的使用变得非常简洁,也方便进行单元测试和模拟。毕竟,代码写得干净一点,对自己也是一种负责。

在实际使用中,有几个地方需要注意:

  1. API Key 配置:确保正确设置 ANTHROPIC_AUTH_TOKEN,否则无法调用模型
  2. 模型可用性:GLM-5.1 需要在对应的模型提供商处开通权限
  3. 图片功能:只有支持 supportsImage: true 的模型才能使用图片上传功能
  4. CLI 安装:使用 Gemini CLI 前,确保 geminigemini-cli 在系统 PATH 中

这些都是小事,但小事处理不好,也可能变成大事。所以还是要注意一下的。

通过 GLM-5.1 的全面支持和 Gemini CLI 的成功集成,HagiCode 进一步强化了其作为多模型、多 CLI AI 编程平台的能力。这些更新不仅为用户提供了更多的选择,也展示了 HagiCode 在架构设计上的前瞻性和可扩展性。

GLM-5.1 的图片支持能力,结合 HagiCode 的截图上传功能,让”看图说话”成为可能——大大降低了问题描述的成本。而十个 CLI 的支持,意味着用户可以根据自己的偏好和场景,灵活选择最合适的 AI 编程助手。毕竟,选择多了,总是好事。

最重要的是,HagiCode 平台自身的构建实践证明:即使使用 GLM 4.7,平台也能良好运行并完成复杂任务;而升级到 GLM-5.1 后,开发效率将得到进一步提升。这就像人生一样,不一定非要追求最好,适合自己的就好。当然,如果能在适合自己的基础上变得更好,那自然更好。

如果你对多模型、多 CLI 的 AI 编程平台感兴趣,不妨试试 HagiCode——开源、免费、不断进化。反正试试又不花钱,万一真适合你呢?


如果本文对你有帮助:

感谢您的阅读,如果您觉得本文有用,欢迎点赞、收藏和分享支持。 本内容采用人工智能辅助协作,最终内容由作者审核并确认。