news 2026/9/3 5:32:01

AI 写我的双端项目,只认鸿蒙不认小程序:祸根是注册表里的排列顺序

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI 写我的双端项目,只认鸿蒙不认小程序:祸根是注册表里的排列顺序

结论先说:tri-coding 拿哪套编码规范写你的代码,不取决于它多聪明,而取决于tech-skills/registry.md那张 25 行表格的排列顺序。我一个鸿蒙加微信小程序双端的项目,两端特征文件都命中了,它只加载了排在第 67 行的arkts,把wechat按互斥规则跳过。最终 design.md 的「编码规范」那一节,从头到尾没出现过一次wxml

起因:design.md 里一个 wxml 都没有

雷达鸭是我自己在做的 App,收录中国一人公司和超级个体的真实赚钱案例,技术栈是 Uni-app 配 arkTS 插件加 UniCloud,微信小程序和鸿蒙版本同步在跑。日常就是靠 tri-xxx 这一票 skill 帮着打理开发流程。

那天要给它加一个「案例收藏夹」,双端都要。按 tri-coding 的流程走,门①需求审批过了,到门②拿到 design.md,我扫「编码规范」那一节,越看越不对劲:@Component@Statebuild()@Prop是单数别写成复数……全是 ArkTS 那一套。小程序侧的app.json分包、setData批量更新、wxml里不能写复杂表达式,一条都没有。

我头一个念头是需求写漏了。回头翻 requirements.md,双端写得清清楚楚。

顺着链路往上翻,卡点在氛围校准

tri-coding 的技术栈不写死在 SKILL.md 里。它在产出 design.md 的「氛围校准」步骤做一次匹配,链路是这样:读tech-skills/registry.md→ 扫项目特征文件 → 按注册表的触发规则逐条匹配 → 命中的技术栈规范注入 design.md 的「技术选型」与「编码规范」两个环节。执行阶段编码时,遵循的就是这批已加载的规范。

我那项目的特征文件是齐的,按注册表的触发规则一条条对:

我项目里的特征文件该命中的 tech_id分类实际加载了吗
tsconfig.json*.tstypescriptlanguage
*.etsoh-package.json5module.json5arktsplatform
project.config.json*.wxmlwechatplatform没有
.git/.gitignoregittool
始终加载generalbase

四个该命中的,三个到位,wechat凭空少了。

注册表里那条我之前没细读的规则

翻到 registry.md 的「加载规则」往下,有一段标题写着互斥规则(同类互斥,仅加载首个命中项)

  • 框架层互斥组:reactvuejs
  • 框架层互斥组:djangofastapiflask
  • 平台层互斥组:arktswechath5
  • 互斥组内多个命中时,优先加载注册表中靠前的条目,其余跳过并记录告警

平台层那条后面还跟了句解释:「同一项目通常面向单一平台」。

这个假设对大多数项目成立,对跨端项目不成立。Uni-app 整个存在的意义就是一套代码编译到多端,arktswechat同时命中是它的常态,而不是异常输入。

再看「优先加载注册表中靠前的条目」——这句话的意思是,表格行序本身就是优先级。我去数了 platform 分类那几行在注册表里的位置:

注册表行号tech_id分类互斥组内结果
67arktsplatform命中且靠前 →加载
68electronplatform未命中
69h5platform未命中
70wechatplatform命中但靠后 →跳过

arkts在第 67 行,wechat在第 70 行。arkts 赢了,赢的理由只是它在表里写得更早。

我个人挺不喜欢这种设计。把优先级藏在表格行序里,而不写成显式的priority字段,读的人不去数行号根本发现不了。

三个解法,前两个我都否了

方案做法结果
wechat那行剪到arkts前面小程序规范上来了,鸿蒙侧没了,方向掉个头而已
删掉平台层那条互斥组,让两个叠加两端语法混进同一份「编码规范」,执行阶段分不清哪条管哪端
新增一个跨端 tech_id 显式注册采用

方案一我真试了,把wechat提到arkts上面,重跑氛围校准,这回 design.md 里全是小程序那套,鸿蒙侧的build()和状态装饰器又没了。互斥组只放一个进来这件事没变。

方案二更糟。ArkTS 的build()链式调用和小程序的wxml模板语法混在同一节里,执行阶段 AI 分不清哪条约束管哪一端,我真怕它给我写出wxml里套Column()的东西。

方案三是我最后用的:加一个新的 tech_id,把「跨端」这件事显式注册进去。registry.md 自己写了它是「唯一扩展入口」,新增技术栈无需改 tri-coding/SKILL.md,那就用它给的路子走。

在注册表追加一行:

| uniapp-multiend | Uni-app 跨端(小程序+鸿蒙) | platform | package.json 含 `@dcloudio/uni-app` 且同时存在 `*.ets` 与 `project.config.json` | `uniapp-multiend.md` |

再在tech-skills/uniapp-multiend.md里把两端约束按目录分区写清楚,而不是混成一锅:哪些规范管src/pages/(小程序侧),哪些管harmony/下的.ets(鸿蒙侧)。分区这一步是关键,不分区就退回方案二的问题了。

落到代码上,差别在这

加载对了之后,鸿蒙侧给的还是那套 ArkTS 写法,这部分本来就没错:

@Componentexportstruct FavoriteCard{@PropcaseTitle:string='';@PropmonthlyRevenue:number=0;@Linkstarred:boolean;build(){Row(){Column(){Text(this.caseTitle).fontSize(16).fontWeight(FontWeight.Medium);Text(`月流水 ¥${this.monthlyRevenue}`).fontSize(13).fontColor('#8A8A8E');}.alignItems(HorizontalAlign.Start).layoutWeight(1);Image(this.starred?$r('app.media.star_on'):$r('app.media.star_off')).width(24).height(24).onClick(()=>{this.starred=!this.starred;});}.width('100%').padding(12);}}

小程序侧的规范补回来之后,多出来的是这类约束,也正是之前 design.md 里完全缺失的那部分:

// 小程序侧:收藏状态变更必须合并 setData,逐条调用会触发多次渲染Page({data:{list:[]},toggleStar(e){constidx=e.currentTarget.dataset.index;constlist=this.data.list;// 只推送变更路径,不整包重设 listthis.setData({[`list[${idx}].starred`]:!list[idx].starred,[`list[${idx}].starredAt`]:Date.now()});}});

wxml里不写复杂表达式、setData走变更路径而不是整包重设,这些条目 ArkTS 那份规范里一个字都不会提。

顺手写了个脚本,别再靠肉眼数行号

数行号这活儿干一次就够了。写了个小脚本,扫注册表加项目特征,把命中的和被互斥吃掉的都打出来:

importjson,re,sysfrompathlibimportPath MUTEX_GROUPS=[{"react","vuejs"},{"django","fastapi","flask"},{"arkts","wechat","h5"},]# tech_id -> 用于判定的特征文件 glob(简化版,够用即可)FEATURES={"typescript":["tsconfig.json","**/*.ts"],"arkts":["**/*.ets","**/oh-package.json5","**/module.json5"],"wechat":["**/project.config.json","**/*.wxml"],"h5":["**/*.html"],"git":[".gitignore"],}defparse_registry(md:Path):"""按注册表出现顺序取出 (行号, tech_id, 分类)"""rows=[]forlineno,lineinenumerate(md.read_text(encoding="utf-8").splitlines(),1):m=re.match(r"^\|\s*([a-z0-9\-]+)\s*\|[^|]*\|\s*(base|language|framework|platform|tool)\s*\|",line)ifm:rows.append((lineno,m.group(1),m.group(2)))returnrowsdefhits(project:Path,tech_id:str)->bool:forpatinFEATURES.get(tech_id,[]):ifnext(project.glob(pat),None):returnTruereturnFalsedefresolve(project:Path,registry:Path):loaded,skipped=["general"],[]claimed=set()forlineno,tech_id,categoryinparse_registry(registry):iftech_id=="general"ornothits(project,tech_id):continuegroup=next((gforginMUTEX_GROUPSiftech_iding),None)ifgroupandgroup&claimed:winner=(group&claimed).pop()skipped.append((tech_id,lineno,winner))continueifgroup:claimed.add(tech_id)loaded.append(tech_id)returnloaded,skippedif__name__=="__main__":proj=Path(sys.argv[1]iflen(sys.argv)>1else".")reg=Path(sys.argv[2]iflen(sys.argv)>2else"tri-coding/tech-skills/registry.md")loaded,skipped=resolve(proj,reg)print("已加载:"," + ".join(loaded))fortech_id,lineno,winnerinskipped:print(f"[告警]{tech_id}(第{lineno}行) 被互斥跳过,让位给更靠前的{winner}")

在我那项目根目录跑一下:

已加载: general + typescript + arkts + git [告警] wechat(第70行) 被互斥跳过,让位给更靠前的 arkts

那句「其余跳过并记录告警」注册表里是写了的,但告警得落到我看得见的地方才算数。现在这行[告警]我在门②之前就能看到,不用等 design.md 交上来才发现少了半套。

一句话

registry 驱动这套设计的可扩展性是真的,加一行就能扩,SKILL.md 一个字不用改。但可扩展不等于会自动判断对:它的平台层互斥规则里压着一个「同一项目通常面向单一平台」的假设,跨端项目撞上去,AI 会安安静静地少给你半套规范,design.md 照样交得漂漂亮亮,格式齐全、章节完整、一处不缺。门②那关别只看格式,先数一下技术栈加载对没对。

我是老三,10 年软件开发经验,软件设计师、人工智能应用工程师,主要做鸿蒙应用(ArkTS)北向开发和 Web 前端,也在折腾 AI 自动化,不定期在 CSDN 写点鸿蒙和 AI 方向的东西。

本文遵循 MIT 协议,转载请注明出处即可。

这个系列的文章都来自开源的 tri 技能库。整套 tri-xxx 技能都能在 skillhub 找到并安装,一条命令装完即用,比如skillhub install tri-coding。装完每个技能都有 README,想摸清它到底能干嘛,读那个就够了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 5:30:51

工业缺陷分割实战:UNet与DeepLabV3+从原理到部署全解析

简介:本资源是一套面向计算机视觉初学者与工业质检工程师的地面缺陷图像分割实战系统,基于PyTorch实现UNet与DeepLabV3双模型端到端训练、评估与可视化分析,聚焦于道路裂缝、坑洼等典型地面缺陷识别任务。压缩包共2000个文件,含10…

作者头像 李华
网站建设 2026/9/3 5:29:22

本地Markdown笔记+本地AI:用Python和FastAPI构建隐私优先的AI笔记本

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 5:28:55

国内四向车厂家供应现状:产能、交付与选型参考

四向穿梭车从概念产品到规模交付,中间隔着一条完整的供应链。不少采购方在项目启动时关注的第一个问题就是:国内四向车厂家供应能力怎么样?交付周期多长?核心组件是自产还是外购?这些问题的答案直接影响项目时间表和后…

作者头像 李华
网站建设 2026/9/3 5:28:52

国内四向车品牌评测:五家本土厂商综合实力排名

智能仓储升级热潮之下,国内四向穿梭车品牌已经形成相当成熟的竞争格局。从专注型制造商到机器人平台厂商,不同类型的品牌各有侧重。对于采购方来说,面对"国内四向车品牌选哪个"这个问题,最需要的不是厂商宣传册上的参数…

作者头像 李华
网站建设 2026/9/3 5:27:42

干预感知临床世界模型:心脏术后结局预测的工程化落地

心脏外科或介入术后,患者接下来几天会不会出问题——比如术后心梗、恶性心律失常、急性肾损伤、计划外再入院——本质上是一个多步动态预测问题,而不是简单的“查表打分”。这几年 World Model(世界模型)在自动驾驶、游戏智能体里…

作者头像 李华
网站建设 2026/9/3 5:26:22

MatCont实战:非线性动力系统分岔分析从入门到精通

简介:本资源是面向数学建模、非线性动力系统研究及工程仿真领域的科研人员与高年级研究生的MATLAB专业工具箱——MatCont7p1,专用于常微分方程(ODE)与离散映射的分岔分析。它解决动态系统中参数变化引发的稳定性突变、周期解分支、…

作者头像 李华