【HarmonyOS学习笔记】2026-08-27 | 端插件踩坑与设计取舍

【HarmonyOS学习笔记】2026-08-27 | 端插件踩坑与设计取舍


date: 2026-08-27

tags: HarmonyOS, 端插件, InsightIntentEntry, 小艺开放平台, LLM, 踩坑, 设计取舍
type: 实战笔记

一、optional 参数被跳过------description 太弱

现象

测试中,title 有值但 scheduledDate 仍然为空:

复制代码
onExecute START: title=去XX地点做XX事, parentId=, scheduledDate=

用户说了"明天",但 LLM 没有把"明天"提取到 scheduledDate。

根因

scheduledDate 的 description 太弱:"计划日期,如明天"。对 optional 参数,LLM 倾向跳过;description 不够强时,LLM 倾向于把时间信息融进 title 而不是单独提取。

修复

这个问题有三种思路,各有取舍:

方案 做法 优点 缺点
提示词加强 description 写得更明确,强调"单独提取" 简单,不改架构 依赖 LLM 理解,不稳定
端侧实体提取 textProcessing 等 API 在端侧提取时间实体,不靠 LLM 确定性强,不依赖 LLM 需要额外代码,只能处理格式化时间
独立时间端插件 单独建一个端插件,告诉模型当前日期和时间,由模型自己判断用户说的"明天"是哪天 模型有完整时间上下文,判断更准 多占一个端插件名额

我当前的做法:提示词加强 + 独立时间端插件组合。 description 写清楚时间格式和提取要求,同时通过独立时间端插件让模型知道"今天是几号",模型有了当前时间上下文后自己判断"明天"对应哪个日期,比纯 description 更稳定。

教训

optional 参数的 description 需要比 required 参数更强。 但 description 不是万能的------对于时间这种需要上下文才能判断的信息,光靠 description 让 LLM 提取是不够的。端侧实体提取可以兜底确定性格式的时间,独立时间端插件可以补足"当前时间"这个上下文缺口。三者组合比单靠任何一个都稳。


二、LLM "假装"调工具------文字模拟成功

现象

某次测试中,小艺回复"已为你创建了一个明天去吃牛肉的记录",但端侧没有任何 onExecute 日志。看起来像调了 CreateRecord,实际没调。

根因

LLM 模式的智能体,LLM 有时会选择不调用工具,而是用文字描述"已经做了"来回复用户。这在以下场景更容易发生:

  • 插件刚重新发布,LLM 的缓存还没更新
  • LLM 对工具调用的信心不足(参数不确定等)
  • LLM 觉得文字回复就够了

验证方法

  1. 查端侧日志:有 onExecute START → 真实调用;没有 → LLM 假装
  2. 查返回值:真实调用会返回 _source: 'MyEndPlugin'_timestamp
  3. 查小艺回复:真实调用后小艺会说"工具返回结果";假装时小艺直接说"已为你创建"

修复

我在提示词中约束了"必须基于工具返回值回复,不得编造结果"。同时在返回值中加入可观测标记(_source_timestamp),方便区分真实调用和文字模拟。

第二种形态:拿提示词示例当事实

比凭空编造更隐蔽的一种情况------模型直接拿系统提示词(角色指令)中的示例数据当作事实回复。

比如提示词里写了:"用户说'帮我记录明天去XX',你应该调用 CreateRecord",模型可能直接回复"已为你创建了明天去XX的记录"------内容看起来很具体,但端侧没有执行记录。

这种比泛泛的假装更难识别,因为回复内容不是凭空编的,而是有"出处"(提示词示例),看起来更真实。但本质一样------没有真实调用端插件,回复就不是基于真实数据的。

修复方案和上面一样:端侧可观测标记(_source + _timestamp)+ 提示词约束"必须基于工具返回值回复,不得编造结果"。可观测标记是物理证据,提示词约束是逻辑防线,两个一起上才能确认工具是否真实执行过。

教训

不能只看小艺回复判断工具是否被调用。 LLM 可能用文字模拟工具调用结果,必须看端侧日志或返回值中的可观测标记确认。这不是 bug,这是 LLM 的特性------无论是凭空编还是拿提示词示例当素材,本质都是"没有真实执行却假装执行了"。需要在系统层面用可观测标记 + 提示词约束双防线防范。


三、覆盖安装导致端插件注册失效------code=204

现象

新增端插件后,从 DevEco Studio 直接 Run 覆盖安装,所有插件报 code=204("未安装或未升级")。App 能正常打开,界面正常,但小艺调不了任何端插件。

根因

覆盖安装时,Insight Intent 的注册缓存可能不一致------旧版本的注册信息残留在系统中,新版本没有完全覆盖。这是系统层面的注册缓存问题。

修复

这种缓存干扰的发生率其实不高,不一定每次覆盖安装都会触发。一般的覆盖安装是正常的,不需要每次都卸载重启。

出现 204 时的排查顺序:

  1. 先直接覆盖安装测试,多数情况下是 OK 的
  2. 如果 204 出现,且确认是新增/修改了 insight_intent.json 注册条目,再走完全卸载 → 重启设备 → 重新安装 → 手动打开应用一次
  3. 开发阶段如果频繁改注册条目,才需要经常走完整卸载流程

教训

新增或修改 insight_intent.json 注册条目后首次部署,有可能遇到注册缓存不一致导致 204。 但不需要把"卸载重启"当作每次覆盖安装的标配------只在改了注册条目后首次部署时留意即可。遇到 204 先判断是缓存问题还是其他原因(比如下一个坑),别上来就卸载重启。


四、intentVersion 不一致------又报 204

现象

新增一个端插件后,小艺调用报 code=204("未安装或未升级")。这次不是覆盖安装的问题------已经卸载重装了,重启也试了,其他插件正常,唯独这个新插件报 204。

根因

端侧 @InsightIntentEntry 装饰器中的 intentVersion 必须与小艺平台侧填写的版本号完全一致。本次端侧写了 '0.0.2',但小艺平台填的是 '0.0.1',版本号不匹配 → 系统认为插件未注册 → 204。

即使该版本号从未被注册过,不一致也会导致引用失败。版本号是两端合约的一部分,不匹配就等于"找不到插件"。

修复

将端侧 intentVersion 改为 '0.0.1',与平台一致。

教训

端插件 intentVersion 必须和小艺平台填的版本号完全一致。 新建插件时统一用 '0.0.1' 起步,改版时两端同步更新。这和参数名两端一致的道理一样------版本号也是两端合约的一部分。坑 3 和坑 4 的报错信息一样(都是 204),但根因完全不同------一个是系统缓存问题,一个是版本号合约问题。遇到 204 时先排查哪个,能省很多时间。


五、端插件数量限制与功能聚合策略

20 个数量限制

小艺开放平台工作流中加入的端插件有 20 个的数量限制。当端插件数量接近这个上限时,需要考虑如何优化。

功能聚合方案

可以在一个端插件中集成多个功能,用一个字段(如 action 参数)控制具体执行哪个功能:

复制代码
@InsightIntentEntry({
  intentName: 'RecordManager',
  parameters: {
    action: { type: 'string' },  // 'create' | 'update' | 'delete' | 'query'
    title: { type: 'string' },
    ...
  }
})

对外只算 1 个端插件,实际内部根据 action 字段分发到不同逻辑。

对谁有效,对谁无效

智能体模式 功能聚合是否有效 原因
LLM 模式(模型节点) ✅ 有效 一个端插件只算 1 个名额,多个功能打包后能显著减少总数
工作流模式(流程中插件节点) ❌ 无效 同一个端插件在不同步骤出现时,重复计算个数

代价:误调用风险

功能越多 → LLM 越容易混淆 → 误调用风险越高。一个端插件包含 create/update/delete/query 四个功能时,LLM 可能本该调 update 却调了 create,或者把 action 填错。

设计取舍

三个维度需要平衡:

维度 趋势 冲突
端插件数量 越少越好(受 20 个限制) ---
功能聚合度 越高越省名额 聚合越高 → 误调用风险越高
误调用风险 越低越好 风险低 → 功能拆细 → 数量多

我的做法:在 LLM 模式下,把语义相近、不易混淆的功能聚合到一个端插件(如 create+update 都是"写操作"),把语义差异大的功能保持独立(如 query 是"读操作")。在工作流模式下,功能聚合没有数量优化效果,但仍有维护便利性,视情况决定。


六、模型版本差异与分工

两个版本的特点

小艺开放平台提供了两种模型版本:

模型 工具调用 文本分析与输出
deepseek 版 不稳定(可能假装/跳过工具调用) 稳定(分析准确、输出格式规范)
deepseek 增强版 稳定(更可靠地调用端插件) 不稳定(输出格式/逻辑可能出问题)

两种版本各有所长,也各有所短。

临时做法:各取所长

我目前的做法是把两种版本组合使用:

  • deepseek 版 :负责分析问题、输出任务规划------需要准确理解和结构化输出,但不涉及工具调用
  • deepseek 增强版 :负责执行端插件调用------需要可靠地调用工具并拿到返回值,对输出格式要求相对低

本质

这不是"哪个模型更好"的问题,而是不同模型有不同的能力边界。分析能力强的做分析,执行能力强的做执行------和端插件功能聚合的取舍逻辑一样,都是在约束条件下寻找最优分工。


学习小结:这篇笔记的核心是"取舍"。optional 参数提取不是只靠 description,三种方案(提示词/端侧实体/独立时间端插件)各有适用场景,我选择了提示词+独立时间端插件的组合。覆盖安装缓存干扰发生率不高,不需要每次都卸载重启,但要能快速判断 204 是缓存问题还是版本号问题。端插件 20 个数量限制引出了功能聚合策略------聚合能省名额但增加误调用风险,对模型节点有效对流程节点无效,三者平衡是关键。两个模型版本各有所短,各取所长的分工比强求一个模型包打天下更实际。端插件开发中"取舍"比"最优"更常见------没有银弹,只有适合当前场景的方案。

懿路向前 · AI辅助整理

2026-08-27

相关推荐
QuZhengRong30 分钟前
【AI】Agent 全栈进阶|Agent 设计模式
人工智能·学习·设计模式·llm·agent
ouynagda1 小时前
Linux多线程:互斥锁与信号量学习笔记
linux·笔记·学习
夜雨声烦丿1 小时前
从需求到页面:日期计算器应用的 ArkTS 原生实现
开发语言·javascript·华为·harmonyos
小蜗 strong1 小时前
ATA各个章节
学习
MartinYeung52 小时前
[论文学习]谄媚研究者驱动表演性错位:大语言模型“对齐伪装”成因的颠复性实证研究
人工智能·学习·语言模型
red_redemption2 小时前
自由学习记录(222)
学习
梦想不只是梦与想3 小时前
鸿蒙 AGC:申请发布证书
harmonyos·appgallery·发布证书
鱼很腾apoc3 小时前
【Linux】第13期 详解应用层协议HTTP+Cookie/Session+HTTPS
linux·服务器·c++·学习·http·https
大锅盖13 小时前
深色医疗青绿主题下ArkUI声明式架构:数字健康监测平台的多维数据可视化与状态管理实践
华为·harmonyos