yd:ai 命令行使用文档
内部文档,仅供本机 / 团队开发参考,不纳入 git 版本控制(
docs/整体已在.gitignore中)。
yd:ai 是元点框架内置的 AI 代码生成 CLI,通过 php think 调用,编排 AI 引擎请求、Schema 读取、文件预览与安全写入的完整流程。相关命令共三个:
| 命令 | 作用 |
|---|---|
php think yd:ai | 主命令:自然语言 → 生成代码 → diff 预览 → 确认写入 |
php think yd:login | 配置 / 查看 / 清除本机保存的 AI 访问 Token |
php think yd:ai:doctor | 本地环境体检(PHP/curl、git、数据库、引擎连通性、Token、runtime 可写) |
命令注册位置:server/config/console.php;实现源码:
server/app/command/YdAiCommand.phpserver/app/command/YdAiLoginCommand.phpserver/app/command/YdAiDoctorCommand.php
底层依赖 server/core/ai/ 下的组件:AiClient(HTTP/SSE 客户端)、SchemaReader(表结构 → Schema 契约)、ProjectContext(项目唯一标识)、FileWriter(安全暂存/写入)、DiffPreview(差异预览)、YdConfig(本机配置持久化)、FeedbackReporter(生成结果反馈上报)。
1. yd:ai 主命令
1.1 基本用法
cd server
php think yd:ai "为文章模块新增置顶字段的编辑接口" --tables=articles流程:
- 校验参数(
instruction必填,--tables必填)。 - 读取
--tables指定表的字段信息,组装成引擎的schema_input。 - 以流式(SSE)方式请求 AI 引擎
/api/v1/generate,边生成边在终端打印内容。 - 生成结果(多文件)先暂存到
runtime/ai/<时间戳>-<随机后缀>/临时目录(不会立即改动工作区)。 - 打印 diff 预览(新文件显示行数,已存在文件用
git diff --no-index展示差异)。 - 若非
--dry-run:首次运行会询问是否允许匿名上报生成结果反馈(一次性 opt-in,写入本机配置);随后询问是否写入;确认后才把暂存文件拷贝进项目工作区。
1.2 参数表
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
instruction(Argument) | string | 是 | — | 自然语言需求描述 |
--tables / -t | string(逗号分隔) | 是 | — | 相关数据表,多个用英文逗号分隔,如 --tables=articles,article_categories |
--layers | string(逗号分隔) | 否 | controller,service,repository,model | 指定要生成的分层,可裁剪,如仅 --layers=service,repository |
--dry-run | flag | 否 | 关闭 | 只生成并预览 diff,不询问、不写入任何文件 |
--write | flag | 否 | 关闭 | 跳过“是否写入”的交互确认,直接写入(用于脚本/CI) |
--export-json=DIR | string | 否 | 无 | 额外把生成结果导出为 DIR/files.json(评测集格式),不影响正常流程 |
1.3 退出码
| 退出码 | 含义 |
|---|---|
0 | 成功(含 dry-run 成功、用户主动取消写入) |
1 | 参数错误(缺 --tables)或引擎报告的“数据表”相关错误(如表不存在) |
2 | 其他引擎错误(连接失败、HTTP 非 200、SSE 未收到 done 事件)或引擎未返回任何文件 |
1.4 常用组合
# 只看生成效果,不落盘
php think yd:ai "订单导出接口" --tables=orders --dry-run
# 只生成 service + repository 两层
php think yd:ai "订单统计" --tables=orders --layers=service,repository
# 非交互直接写入(CI / 脚本场景)
php think yd:ai "订单统计" --tables=orders --write
# 生成的同时导出评测集格式,供后续跑评测对比
php think yd:ai "订单统计" --tables=orders --dry-run --export-json=/tmp/eval_case_001写入完成后命令会提示:新增菜单需手动加入
server/public/install/data/init.sql(务必检查已用 ID,避免主键冲突,参见根CLAUDE.md的“安装数据”约定)。
2. Token 配置与优先级
Token 用于 AI 引擎鉴权(本地 dev 模式下引擎可能不校验 Token,此时留空也能跑通)。
优先级(从高到低):
- 项目
server/.env中的YD_AI_TOKEN(团队/CI 共享配置,优先级最高) - 本机全局配置
~/.ydsaas/config.json的token字段(通过yd:login写入,仅对当前用户生效) - 都未配置则以
null传给AiClient,请求不带Authorization头(仅适用于本地无鉴权的 dev 引擎)
管理命令:
php think yd:login # 交互式粘贴并保存 Token(写入 ~/.ydsaas/config.json,权限 0600)
php think yd:login --show # 查看当前 Token 来源与脱敏值
php think yd:login --clear # 清除本机保存的 Token(不影响 .env 中的 YD_AI_TOKEN)3. AI 引擎地址配置(YD_AI_ENDPOINT)
引擎地址与超时配置在 server/config/ai.php:
return [
'endpoint' => env('YD_AI_ENDPOINT', 'http://127.0.0.1:8000'),
'timeout' => (int) env('YD_AI_TIMEOUT', 300),
];- 默认指向本地
http://127.0.0.1:8000(本地开发引擎)。 - 生产/联调环境在
server/.env中设置:
YD_AI_ENDPOINT=https://ai.example.com
YD_AI_TIMEOUT=300AiClient请求超时默认 300 秒(生成较大代码量时预留充足时间),可用YD_AI_TIMEOUT(单位秒)调整。
4. 故障排查:yd:ai:doctor
遇到 yd:ai 报错或无响应时,先跑体检命令:
php think yd:ai:doctor依次检查:
- PHP 版本(≥8.0)与
curl扩展是否启用 git是否可用(diff 预览依赖git diff --no-index;不可用时会退化为“[覆盖]xxx(git 不可用,无法展示差异)”提示,不影响生成/写入)- 数据库连通性(通过
CodeGeneratorService::getTableColumns('menus')探测) - AI 引擎可达性(
GET {endpoint}/api/v1/health是否返回 200),并提示 endpoint 来源(.env YD_AI_ENDPOINT或默认配置) - Token 配置状态(已配置 / 未配置,未配置在本地 dev 模式下仍可用)
runtime/目录是否可写(生成文件会先暂存到runtime/ai/)
全部通过时退出码为 0 并打印“全部通过,可以使用 php think yd:ai”;任一项失败退出码为 1,并在失败项下方打印修复提示(→ ...)。
常见问题:
无法连接 AI 引擎:确认引擎进程已启动,或YD_AI_ENDPOINT配置是否指向正确地址;doctor会额外打印 endpoint 来源,便于确认是否读取到预期的.env。AI 引擎返回 HTTP xxx:引擎侧异常,检查引擎日志;命令会截取响应体前 200 字符一并打印。SSE 流结束但未收到 done 事件(可能被截断):多为超时或引擎中途异常断开,可尝试调大YD_AI_TIMEOUT或检查引擎稳定性。数据表 'xxx' 不存在或无法访问/没有字段信息:检查--tables拼写及数据库连接(server/.env数据库配置)。已拒绝不安全路径:xxx:引擎返回的文件路径未通过FileWriter::isSafeRelPath安全校验(绝对路径、..穿越、空路径、Windows 绝对路径等),该文件会被跳过、不写入,其余文件不受影响。
5. --export-json 与评测集配合
--export-json=DIR 用于把一次生成结果导出为评测集可消费的 DIR/files.json(JSON_PRETTY_PRINT + JSON_UNESCAPED_UNICODE,结构与引擎返回的 files 数组一致:[{"path": "...", "code": "..."}, ...])。
典型用法:结合 --dry-run 只生成、导出,不触碰工作区,用于批量构建/更新评测用例:
php think yd:ai "为文章模块新增置顶字段的编辑接口" \
--tables=articles \
--dry-run \
--export-json=/Users/xxx/ydsaas-evals/cases/article-top-field/actual导出目录建议与 ydsaas-evals 仓库中的用例目录对齐(如 cases/<case-id>/actual/files.json),再由评测脚本对比 expected/ 与 actual/ 的差异,计算通过率/相似度等指标。由于导出发生在写入确认之前,--export-json 可与 --dry-run 组合使用,做到“批量生成 + 导出 + 完全不改动工作区”,适合在评测流水线中重复运行。
验收记录
以下记录为 2026-07-10 针对 spec 验收标准 1/2/4 的端到端人工验收结果(本地库 dev007_framework,用例 t06_goods_audit,验收后所有产物已清理,不影响仓库状态)。
1. 建表
按 ydsaas-evals/tasks/t06_goods_audit.yaml 的 schema_input 在本地库创建 goods 表(14 字段 + 3 索引),字段/索引与 YAML 定义逐一对齐。验收完成后已 DROP TABLE goods。
2. yd:ai:doctor 双状态
引擎未启动:
元点 AI 环境体检:
✓ PHP 8.4.20(需 ≥8.0)且 curl 扩展
✓ git 可用(diff 预览依赖)
✓ 数据库连通
✗ AI 引擎可达(http://127.0.0.1:8000,来源:默认配置)
→ 确认引擎已启动或修改 YD_AI_ENDPOINT
✓ Token 状态:未配置(本地 dev 模式可用)
✓ runtime 目录可写
存在问题,请按提示修复
exit=1启动引擎(uv run uvicorn app.main:app --port 8000)后:
元点 AI 环境体检:
✓ PHP 8.4.20(需 ≥8.0)且 curl 扩展
✓ git 可用(diff 预览依赖)
✓ 数据库连通
✓ AI 引擎可达(http://127.0.0.1:8000,来源:默认配置)
✓ Token 状态:未配置(本地 dev 模式可用)
✓ runtime 目录可写
全部通过,可以使用 php think yd:ai
exit=0两次结果均与预期一致(六项检查逻辑正常,退出码随引擎状态正确切换)。
3. CLI 生成 + evals 判分
命令:
php think yd:ai "根据 goods 表生成商品审核模块,支持通过、驳回、审核日志" --tables=goods --dry-run --export-json=/tmp/cli-out/t06_goods_audit
uv run eval run --runner=fileset --fileset-dir=/tmp/cli-out --tasks=t06_goods_auditCLI 生成 6 个文件(Goods 模型、goods 路由、GoodsRepository、GoodsService、GoodsValidate、GoodsController),export-json 成功导出至 files.json。
判分矩阵(首次运行即全过,未重跑):
| 任务 | required_files | php_lint | layer_compliance | path_convention | forbidden_patterns | route_runtime | custom_grep | 结果 |
|---|---|---|---|---|---|---|---|---|
| t06_goods_audit | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✅ |
总任务 1,通过 1,通过率 100%(质量门槛 80%,达标)。
4. 写入 / 拒绝流程人工验收
拒绝流程(printf 'n\nn\n' | php think yd:ai ... --tables=goods,无 --dry-run、无 --write):
- 依次弹出「是否允许匿名上报生成结果的接受/拒绝信号」与「写入以上 6 个文件?」两个
[y/N]确认,均输入n - 输出
已取消,未写入任何文件,退出码 0 git status --porcelain中server/app/...相关路径无新增(与拒绝前基线一致,仅runtime/ai/<ts>暂存目录存在,属预期的“先暂存后确认写入”行为,未触达工作区正式文件)
写入流程(php think yd:ai ... --tables=goods --write):
- 跳过交互确认,直接生成并写入,终端逐行打印
已写入 <path> - 落位清单(均为新增,
git status --porcelain核实):server/app/model/goods/Goods.phpserver/app/adminapi/route/goods.phpserver/app/repository/goods/GoodsRepository.phpserver/app/service/goods/GoodsService.phpserver/app/adminapi/validate/v1/goods/GoodsValidate.phpserver/app/adminapi/controller/v1/goods/GoodsController.php
- 命令结尾提示「新菜单需手动加入
server/public/install/data/init.sql」,符合文档 1.4 节说明 - 验收后清理:逐一核对
git clean -fdn输出(runtime/、上述 6 个新增路径、以及会话前已存在的server/.phpunit.cache/),排除非本次生成的server/.phpunit.cache/后手动删除本次生成的全部路径与runtime/暂存目录,无遗留
5. 收尾
DROP TABLE goods已执行,本地库恢复原状- AI 引擎进程已
pkill终止,端口 8000 无监听 git status --porcelain仅剩会话前既有脏文件:admin/.env.development、admin/pnpm-lock.yaml、pc/nuxt.config.ts(以及会话前已存在、与本任务无关的server/.phpunit.cache/),framework 仓库无本次任务产生的新增未跟踪文件