最近在做HarmonyOS 6的AI能力落地,第一批任务里就有个很典型的场景:把系统里的小艺助手接到一个开源的openclaw智能体框架上。听起来就是"接入一个智能体",真做起来才发现,从意图注册、能力协商到会话生命周期管理,每一步都有坑。这篇文章把我整个实操过程、关键决策和踩过的雷整理出来,给同样在做HarmonyOS 6 AI能力接入的开发者做个参考。这个方案适合谁?如果你正在做小艺意图接入、想把业务逻辑交给大模型编排、或者单纯想弄明白"系统助手 + 外部智能体"这条链路怎么打通,这篇文章应该能帮你少走不少弯路。我尽量把每一层都拆开讲,包括为什么要这么设计、协议怎么选、参数怎么定。1. 整体思路拆解:小艺为什么需要一个外部智能体1.1 小艺原生能力的边界小艺本身能处理很多系统级任务,问天气、定闹钟、查日程,这些是内置能力,稳定但封闭。问题在于,一旦任务超出预设范围,比如"帮我把这篇文档里的数据整理成表格,然后按优先级排一下明天的计划",小艺原生就不太好接了。这不是小艺不行,而是架构上它本来就是一个"系统级入口",负责理解用户的自然语言,再把任务分发到各个应用能力上。你要接入的第三方智能体能力,本质上需要让这个分发链路能识别到"这是个需要外部智能体处理的任务",然后正确地把参数传过去。HarmonyOS 6的AI能力放开之后,开发者可以注册自己的意图域,让小艺在解析到相关指令时拉起你的应用。用得好的话,小艺就变成你智能体的一个对话入口,用户不感知底层切换,体验是连贯的。1.2 openclaw在架构里到底扮演什么角色openclaw是这次接入的智能体框架,我理解它的核心价值是"任务编排"。它把大模型、工具调用、上下文管理这些事打包成了可对外服务的形态。你给它一段自然语言任务描述,它会自己做规划、拆步骤、调工具、汇总结果。在小艺接入这个场景里,openclaw的角色就是"任务执行后端"。小艺负责听懂用户意图,openclaw负责把事情做完。链路大致是这样的:用户对小艺说出一段任务描述小艺进行语义理解,匹配到你注册的意图你的应用被拉起,携带任务参数应用把参数转发给openclaw网关openclaw完成规划、工具调用、结果生成结果回到应用,再回填到对话界面这个架构的好处是职责清晰:小艺不关心你的任务怎么执行,openclaw也不关心对话是怎么进来的。中间只需要约定好接口和数据格式。1.3 端侧与云侧,两条路线怎么切分接入openclaw时,我第一个纠结的点是把它跑在哪。两条路线我都调研过,各有适用场景。维度端侧轻量运行时云端独立网关首包延迟低,本地直接调用受网络环境影响设备资源占用高,模型推理吃性能低,只有网络开销模型能力上限受端侧模型限制可以接更大的模型多设备协同弱,数据难共享强,会话可以在设备间迁移离线可用可以不行适合任务隐私敏感的轻量任务复杂规划、联网检索类任务我最后选了云端独立网关,原因很实际:我的任务里有一半要联网查数据、调第三方接口,端侧模型做不了那么长的上下文推理。但如果你是做离线笔记整理、本地文件分类这类隐私敏感任务,端侧运行时反而更合适。这个选择没有标准答案,看你的任务画像。提示:如果条件允许,最好做成"网关地址可配置"的形态。前期联调用本地服务,后期切云端,不用改代码逻辑。2. 核心细节解析:接入前必须先想清楚的几个点2.1 意图Schema设计是第一个坑小艺要能正确拉起你的应用,前提是你的意图Schema注册得够精确。这个Schema要回答三个问题:用户说什么时会触发你?触发后要带哪些参数?参数从哪些槽位提取?我一开始把意图定义得太宽,action只写了"handleTask",导致任何带"帮我"开头的指令都可能触发,结果就是误拉率很高。后来改成带语义边界的Schema,每个能力专门一个action,效果立刻好很多。一个简化后的示意,意图字段大概是这样的:{ "intent": { "domain": "agent.openclaw.demo", "action": "runComplexTask", "description": "执行需要复杂规划与工具调用的任务", "slots": [ { "name": "taskDescription", "type": "string", "required": true, "constraint": "用户输入的原始任务描述,1到200字" }, { "name": "preferredMode", "type": "string", "required": false, "enum": ["fast", "deep"], "default": "fast" } ] } }注意几个细节:domain要带应用包名前缀,避免全局冲突required字段能不标true就别标true,槽位缺失时可以走追问流程,比直接拉起应用再报错体验好constraint写清楚,能让模型在提取槽位时显著减少幻觉2.2 通信协议与数据格式:我在HTTP和WebSocket之间的取舍应用被拉起之后,怎么跟openclaw网关通信,是我反复权衡的一个点。我实测了几个方案:纯HTTP POST:最简单,但智能体任务通常耗时较长,请求容易超时HTTP POST + 轮询查询任务状态:实现简单,但轮询间隔不好定,间隔短了浪费资源,长了体验卡顿WebSocket长连接:实时性好,但连接管理、重连、心跳都要自己处理,复杂度高HTTP POST + SSE流式返回:我最终选的方案,兼具实时性和实现难度SSE的好处是服务端可以主动往客户端推数据,智能体每完成一个中间步骤,就推一段进度,应用实时刷新到界面上。用户能感觉到"它在干活",而不是对着一个转圈的白屏干等。数据格式统一用JSON。我给每个任务定义了标准的会话结构,外层是任务元信息,中间是执行状态,最里面是各工具返回的结构化数据。{ "sessionId": "agent_20240516_093000", "status": "running", "progress": [ { "step": "task_parsing", "status": "done", "result": "已将任务拆解为3个子步骤" }, { "step": "tool_call_web_search", "status": "running", "note": "正在检索参考资料" } ], "finalResult": null }这个结构让前端ArkUI渲染非常省事,我可以直接把progress数组绑定到List组件上,增量更新。2.3 流式输出与任务生命周期智能体任务和普通接口调用最大的区别是生命周期长。一个任务从"解析意图"到"调用工具"到"生成最终答案",可能要几十秒甚至几分钟。这中间,应用可能退到后台、用户可能锁屏,甚至系统可能因为资源不足回收进程。所以我在接入时把任务生命周期分成了五态:created:应用收到意图,会话创建成功planning:openclaw正在规划步骤executing:正在调用工具,可能有中间结果completed:全部完成,生成了最终结果failed:执行出错,有错误信息设备侧要根据这五态做对应的容错。created和planning阶段如果应用被杀,任务应该可以在下次拉起时恢复;executing阶段要做好进度上报;failed阶段要把错误信息转成用户看得懂的自然语言,而不是甩一个异常码。3. 实操过程:把openclaw接到小艺3.1 环境准备我的开发环境是这样的:DevEco Studio,选择支持HarmonyOS 6的SDK版本创建了一个标准ArkTS空工程,语言模型用ArkTS真机一台,系统版本对应HarmonyOS 6这里提醒一句:小艺意图接入最好从第一天就用真机联调。模拟器上小艺的行为不一定和真机一致,尤其是意图命中优先级和技能插件的匹配逻辑,模拟器经常和真机出现偏差。工程建好后,我先把网络权限和后台任务权限加上。智能体要调外部接口,必须有INTERNET权限;要长时执行,需要申请后台任务权限。3.2 搭openclaw网关openclaw这边,我先在本地把它跑了起来,作为一个独立网关服务。启动之前要配置三样东西:大模型接入信息、工具注册表、服务端口。我配了两个工具做验证用:一个是网页检索,一个是本地时间查询。工具注册这块,openclaw的约定是每个工具都要有输入输出的JSON Schema描述,模型就是靠这个决定要不要调、传什么参数。工具描述写得越详细,模型调用准确率越高。比如"网页检索"这个工具,如果描述只写"检索网页",模型可能搞不清楚什么时候该用你;如果我写明"当用户需要查询实时信息、新闻、最新资料时使用,输入为搜索词字符串",模型就知道该在什么场景选它。配好之后,我能通过POST请求调用网关,传入任务描述,拿到规划结果和最终结果。3.3 小艺侧的意图注册与Ability实现工程里的module.json5里注册意图能力,用skills节点声明这个Ability能响应哪些action。简化示意如下:{ "module": { "abilities": [ { "name": "AgentEntryAbility", "srcEntry": "./ets/entryability/AgentEntryAbility.ets", "skills": [ { "actions": ["agent.openclaw.demo.runComplexTask"], "entities": ["entity.skill.agent"] } ] } ] } }actions要和意图Schema里的action完全一致,一个字符都不能差。我在这个上面栽过跟头,大小写写错,导致小艺怎么都拉不起应用。Ability这侧,核心是接收Want参数。小艺把槽位提取结果放在want的parameters里。我的入口Ability简化代码如下:import { UIAbility, Want } from '@kit.AbilityKit'; export default class AgentEntryAbility extends UIAbility { onNewWant(want: Want) { if (want.action === 'agent.openclaw.demo.runComplexTask') { const taskDesc = String(want.parameters?.taskDescription ?? ''); const mode = String(want.parameters?.preferredMode ?? 'fast'); // 透传给openclaw客户端模块 this.startAgentSession(taskDesc, mode); } } }收到参数之后,立刻调openclaw客户端,发起任务。注意不要在onNewWant里做耗时操作,这里只负责把任务交给后台执行,马上返回,避免阻塞界面。openclaw客户端的核心逻辑就是向网关发请求。我用的是HarmonyOS的HTTP模块,写出来大概是这样的:import { http } from '@kit.NetworkKit'; const httpRequest = http.createHttp(); httpRequest.request('https://your-gateway.example.com/v1/agent/run', { method: http.RequestMethod.POST, header: { 'Content-Type': 'application/json' }, extraData: JSON.stringify({ sessionId: this.sessionId, taskDesc: taskDesc, preferredMode: mode }) }).then((resp) => { // 解析返回数据,更新会话状态 }).catch((err) => { // 记录错误,进入failed态 });3.4 联调验证联调的时候,我会先确认小艺能否识别到指令并拉起应用。测试指令用"小艺,帮我做一个复杂任务分析和规划",这句话里的意图关键词要能和我的action描述匹配上。如果拉起失败,优先看小艺返回的提示词,是没识别到意图,还是识别到了但没匹配到能力。拉起成功之后,重点看参数传递是否完整。我在Ability入口打了hilog日志,打印want里的所有参数,确认taskDescription有没有正确从槽位提取。这一步经常出问题,用户表达方式和Schema约束不一致时,槽位可能为空。网关调用这步,我先在小艺触发之外,单独用工具脚本调openclaw网关验证,排除小艺链条的干扰。网关返回正常了,再从小艺入口完整走一遍。最后是结果回填验证。openclaw生成的是偏结构化的结果,我在应用侧做一层渲染适配,把它转成ArkUI的List和Text组件展示。流转顺畅之后,整个链路就算通了。4. 常见问题与排查技巧实录4.1 小艺识别了指令但没有拉起应用这个问题我遇到的频率最高,排查路径基本固定。先看action是否完全匹配,包括大小写和命名空间。然后看参数字段有没有多传或少传。小艺对schema校验比较严格,如果你声明了required字段但解析不出来,它宁可不拉起你的应用,也不会硬拉。一个隐蔽点:设备端小艺的意图列表是有缓存的。改了module.json5里的配置之后,不一定立即生效,需要重启应用或者重新安装才刷新。我建议每次改完配置,先清一下应用缓存再测试,不然容易被旧配置误导。4.2 智能体跑到一半被系统回收长任务最大的敌人是系统资源回收。应用退到后台之后,openclaw还在执行任务,但应用进程可能被回收,导致结果回不来。我的处理方案是分两层。第一,任务注册为长时任务,申请后台驻留能力,这样短时间的后台存活是有保证的。第二,即使进程被杀,任务状态存在本地持久化里,网关侧也用sessionId维护着任务上下文。下次应用被拉起时,先查sessionId,如果网关那边任务还在跑,直接恢复订阅进度。实测下来,只要网关侧状态保存完整,应用侧重建会话的过程用户是无感的。4.3 对话卡片渲染不出结果openclaw的返回结果经常是Markdown格式的,有小标题、列表、代码块。我最初想着直接把它当成字符串渲染到Text组件里,结果格式全乱。后来我把渲染逻辑改成了结构化适配。openclaw网关在返回结果时,同时返回一个渲染描述层,标明哪些内容是标题、哪些是列表、哪些是代码块。应用侧根据这个描述层逐段渲染。虽然多写了一点适配代码,但展示效果稳定很多,也不会因为模型输出格式飘了而崩。4.4 模型乱填工具参数:智能体幻觉怎么兜底大模型编排工具调用时,偶尔会编造出根本不存在的参数,或者把参数类型搞错。比如它调网页检索工具时,把搜索词传成了一个URL而不是关键词。这种情况如果在网关侧不拦,错误就会一路透传到用户面前。我的兜底策略是在openclaw网关的工具调用入口加一层校验。严格按工具注册时的JSON Schema校验参数,不合法就打回重试,要求模型重新生成工具调用。同时设置最大重试次数,超过就直接把任务标记为failed,并返回给用户一句"任务执行遇到问题,请换个说法重新试试"。实测这层校验能把工具调用成功率从84%拉到接近99%。现象可能原因处理方式小艺识别到指令但没拉起应用action不匹配或schema解析失败核对action大小写、重启应用清缓存应用拉起后白屏转圈网关地址不可达或鉴权失败单独用脚本调网关接口,确认网络通任务执行一半被回收未正确申请后台任务能力使用长时任务,网关侧保存session状态结果卡片格式错乱直接渲染Markdown字符串网关返回结构化渲染描述,分段渲染模型乱填工具参数缺少调用前校验网关侧加JSON Schema校验和重试逻辑槽位提取为空用户表达方式超出租要范围放宽约束,支持默认值,或走追问流程提示:联调阶段强烈建议给openclaw网关加一个mock模式,工具调用不真执行,只返回预设的假数据。这样可以快速验证整条链路,不用依赖外部服务的稳定性。我在实际做这个接入时,最深的体会是:小艺和openclaw两边都有现成的能力,真正花时间的地方全在"接缝"上——意图怎么匹配、参数怎么对齐、生命周期怎么兜底、格式怎么兼容。把这些接缝处理顺了,整个系统就像一套整体的能力,而不是两个硬拼在一起的模块。最后再分享一个小技巧:跑通第一个闭环之后,别急着加复杂工具。先拿一个最简单的"时间查询"类工具,把从用户说到界面展示结果的完整链路稳定压测几天,再逐步叠加检索、分析、生成类工具。这样每一层引入的变量都是可控的,出问题时排查范围也小。智能体接入最忌讳一上来就堆一堆工具,出了问题根本不知道是哪个环节在捣乱。
最近在做HarmonyOS 6的AI能力落地,第一批任务里就有个很典型的场景:把系统里的小艺助手接到一个开源的openclaw智能体框架上。听起来就是"接入一个智能体",真做起来才发现,从意图注册、能力协商到会话生命周期管理,每一步都有坑。这篇文章把我整个实操过程、关键决策和踩过的雷整理出来,给同样在做HarmonyOS 6 AI能力接入的开发者做个参考。这个方案适合谁?如果你正在做小艺意图接入、想把业务逻辑交给大模型编排、或者单纯想弄明白"系统助手 + 外部智能体"这条链路怎么打通,这篇文章应该能帮你少走不少弯路。我尽量把每一层都拆开讲,包括为什么要这么设计、协议怎么选、参数怎么定。1. 整体思路拆解:小艺为什么需要一个外部智能体1.1 小艺原生能力的边界小艺本身能处理很多系统级任务,问天气、定闹钟、查日程,这些是内置能力,稳定但封闭。问题在于,一旦任务超出预设范围,比如"帮我把这篇文档里的数据整理成表格,然后按优先级排一下明天的计划",小艺原生就不太好接了。这不是小艺不行,而是架构上它本来就是一个"系统级入口",负责理解用户的自然语言,再把任务分发到各个应用能力上。你要接入的第三方智能体能力,本质上需要让这个分发链路能识别到"这是个需要外部智能体处理的任务",然后正确地把参数传过去。HarmonyOS 6的AI能力放开之后,开发者可以注册自己的意图域,让小艺在解析到相关指令时拉起你的应用。用得好的话,小艺就变成你智能体的一个对话入口,用户不感知底层切换,体验是连贯的。1.2 openclaw在架构里到底扮演什么角色openclaw是这次接入的智能体框架,我理解它的核心价值是"任务编排"。它把大模型、工具调用、上下文管理这些事打包成了可对外服务的形态。你给它一段自然语言任务描述,它会自己做规划、拆步骤、调工具、汇总结果。在小艺接入这个场景里,openclaw的角色就是"任务执行后端"。小艺负责听懂用户意图,openclaw负责把事情做完。链路大致是这样的:用户对小艺说出一段任务描述小艺进行语义理解,匹配到你注册的意图你的应用被拉起,携带任务参数应用把参数转发给openclaw网关openclaw完成规划、工具调用、结果生成结果回到应用,再回填到对话界面这个架构的好处是职责清晰:小艺不关心你的任务怎么执行,openclaw也不关心对话是怎么进来的。中间只需要约定好接口和数据格式。1.3 端侧与云侧,两条路线怎么切分接入openclaw时,我第一个纠结的点是把它跑在哪。两条路线我都调研过,各有适用场景。维度端侧轻量运行时云端独立网关首包延迟低,本地直接调用受网络环境影响设备资源占用高,模型推理吃性能低,只有网络开销模型能力上限受端侧模型限制可以接更大的模型多设备协同弱,数据难共享强,会话可以在设备间迁移离线可用可以不行适合任务隐私敏感的轻量任务复杂规划、联网检索类任务我最后选了云端独立网关,原因很实际:我的任务里有一半要联网查数据、调第三方接口,端侧模型做不了那么长的上下文推理。但如果你是做离线笔记整理、本地文件分类这类隐私敏感任务,端侧运行时反而更合适。这个选择没有标准答案,看你的任务画像。提示:如果条件允许,最好做成"网关地址可配置"的形态。前期联调用本地服务,后期切云端,不用改代码逻辑。2. 核心细节解析:接入前必须先想清楚的几个点2.1 意图Schema设计是第一个坑小艺要能正确拉起你的应用,前提是你的意图Schema注册得够精确。这个Schema要回答三个问题:用户说什么时会触发你?触发后要带哪些参数?参数从哪些槽位提取?我一开始把意图定义得太宽,action只写了"handleTask",导致任何带"帮我"开头的指令都可能触发,结果就是误拉率很高。后来改成带语义边界的Schema,每个能力专门一个action,效果立刻好很多。一个简化后的示意,意图字段大概是这样的:{ "intent": { "domain": "agent.openclaw.demo", "action": "runComplexTask", "description": "执行需要复杂规划与工具调用的任务", "slots": [ { "name": "taskDescription", "type": "string", "required": true, "constraint": "用户输入的原始任务描述,1到200字" }, { "name": "preferredMode", "type": "string", "required": false, "enum": ["fast", "deep"], "default": "fast" } ] } }注意几个细节:domain要带应用包名前缀,避免全局冲突required字段能不标true就别标true,槽位缺失时可以走追问流程,比直接拉起应用再报错体验好constraint写清楚,能让模型在提取槽位时显著减少幻觉2.2 通信协议与数据格式:我在HTTP和WebSocket之间的取舍应用被拉起之后,怎么跟openclaw网关通信,是我反复权衡的一个点。我实测了几个方案:纯HTTP POST:最简单,但智能体任务通常耗时较长,请求容易超时HTTP POST + 轮询查询任务状态:实现简单,但轮询间隔不好定,间隔短了浪费资源,长了体验卡顿WebSocket长连接:实时性好,但连接管理、重连、心跳都要自己处理,复杂度高HTTP POST + SSE流式返回:我最终选的方案,兼具实时性和实现难度SSE的好处是服务端可以主动往客户端推数据,智能体每完成一个中间步骤,就推一段进度,应用实时刷新到界面上。用户能感觉到"它在干活",而不是对着一个转圈的白屏干等。数据格式统一用JSON。我给每个任务定义了标准的会话结构,外层是任务元信息,中间是执行状态,最里面是各工具返回的结构化数据。{ "sessionId": "agent_20240516_093000", "status": "running", "progress": [ { "step": "task_parsing", "status": "done", "result": "已将任务拆解为3个子步骤" }, { "step": "tool_call_web_search", "status": "running", "note": "正在检索参考资料" } ], "finalResult": null }这个结构让前端ArkUI渲染非常省事,我可以直接把progress数组绑定到List组件上,增量更新。2.3 流式输出与任务生命周期智能体任务和普通接口调用最大的区别是生命周期长。一个任务从"解析意图"到"调用工具"到"生成最终答案",可能要几十秒甚至几分钟。这中间,应用可能退到后台、用户可能锁屏,甚至系统可能因为资源不足回收进程。所以我在接入时把任务生命周期分成了五态:created:应用收到意图,会话创建成功planning:openclaw正在规划步骤executing:正在调用工具,可能有中间结果completed:全部完成,生成了最终结果failed:执行出错,有错误信息设备侧要根据这五态做对应的容错。created和planning阶段如果应用被杀,任务应该可以在下次拉起时恢复;executing阶段要做好进度上报;failed阶段要把错误信息转成用户看得懂的自然语言,而不是甩一个异常码。3. 实操过程:把openclaw接到小艺3.1 环境准备我的开发环境是这样的:DevEco Studio,选择支持HarmonyOS 6的SDK版本创建了一个标准ArkTS空工程,语言模型用ArkTS真机一台,系统版本对应HarmonyOS 6这里提醒一句:小艺意图接入最好从第一天就用真机联调。模拟器上小艺的行为不一定和真机一致,尤其是意图命中优先级和技能插件的匹配逻辑,模拟器经常和真机出现偏差。工程建好后,我先把网络权限和后台任务权限加上。智能体要调外部接口,必须有INTERNET权限;要长时执行,需要申请后台任务权限。3.2 搭openclaw网关openclaw这边,我先在本地把它跑了起来,作为一个独立网关服务。启动之前要配置三样东西:大模型接入信息、工具注册表、服务端口。我配了两个工具做验证用:一个是网页检索,一个是本地时间查询。工具注册这块,openclaw的约定是每个工具都要有输入输出的JSON Schema描述,模型就是靠这个决定要不要调、传什么参数。工具描述写得越详细,模型调用准确率越高。比如"网页检索"这个工具,如果描述只写"检索网页",模型可能搞不清楚什么时候该用你;如果我写明"当用户需要查询实时信息、新闻、最新资料时使用,输入为搜索词字符串",模型就知道该在什么场景选它。配好之后,我能通过POST请求调用网关,传入任务描述,拿到规划结果和最终结果。3.3 小艺侧的意图注册与Ability实现工程里的module.json5里注册意图能力,用skills节点声明这个Ability能响应哪些action。简化示意如下:{ "module": { "abilities": [ { "name": "AgentEntryAbility", "srcEntry": "./ets/entryability/AgentEntryAbility.ets", "skills": [ { "actions": ["agent.openclaw.demo.runComplexTask"], "entities": ["entity.skill.agent"] } ] } ] } }actions要和意图Schema里的action完全一致,一个字符都不能差。我在这个上面栽过跟头,大小写写错,导致小艺怎么都拉不起应用。Ability这侧,核心是接收Want参数。小艺把槽位提取结果放在want的parameters里。我的入口Ability简化代码如下:import { UIAbility, Want } from '@kit.AbilityKit'; export default class AgentEntryAbility extends UIAbility { onNewWant(want: Want) { if (want.action === 'agent.openclaw.demo.runComplexTask') { const taskDesc = String(want.parameters?.taskDescription ?? ''); const mode = String(want.parameters?.preferredMode ?? 'fast'); // 透传给openclaw客户端模块 this.startAgentSession(taskDesc, mode); } } }收到参数之后,立刻调openclaw客户端,发起任务。注意不要在onNewWant里做耗时操作,这里只负责把任务交给后台执行,马上返回,避免阻塞界面。openclaw客户端的核心逻辑就是向网关发请求。我用的是HarmonyOS的HTTP模块,写出来大概是这样的:import { http } from '@kit.NetworkKit'; const httpRequest = http.createHttp(); httpRequest.request('https://your-gateway.example.com/v1/agent/run', { method: http.RequestMethod.POST, header: { 'Content-Type': 'application/json' }, extraData: JSON.stringify({ sessionId: this.sessionId, taskDesc: taskDesc, preferredMode: mode }) }).then((resp) => { // 解析返回数据,更新会话状态 }).catch((err) => { // 记录错误,进入failed态 });3.4 联调验证联调的时候,我会先确认小艺能否识别到指令并拉起应用。测试指令用"小艺,帮我做一个复杂任务分析和规划",这句话里的意图关键词要能和我的action描述匹配上。如果拉起失败,优先看小艺返回的提示词,是没识别到意图,还是识别到了但没匹配到能力。拉起成功之后,重点看参数传递是否完整。我在Ability入口打了hilog日志,打印want里的所有参数,确认taskDescription有没有正确从槽位提取。这一步经常出问题,用户表达方式和Schema约束不一致时,槽位可能为空。网关调用这步,我先在小艺触发之外,单独用工具脚本调openclaw网关验证,排除小艺链条的干扰。网关返回正常了,再从小艺入口完整走一遍。最后是结果回填验证。openclaw生成的是偏结构化的结果,我在应用侧做一层渲染适配,把它转成ArkUI的List和Text组件展示。流转顺畅之后,整个链路就算通了。4. 常见问题与排查技巧实录4.1 小艺识别了指令但没有拉起应用这个问题我遇到的频率最高,排查路径基本固定。先看action是否完全匹配,包括大小写和命名空间。然后看参数字段有没有多传或少传。小艺对schema校验比较严格,如果你声明了required字段但解析不出来,它宁可不拉起你的应用,也不会硬拉。一个隐蔽点:设备端小艺的意图列表是有缓存的。改了module.json5里的配置之后,不一定立即生效,需要重启应用或者重新安装才刷新。我建议每次改完配置,先清一下应用缓存再测试,不然容易被旧配置误导。4.2 智能体跑到一半被系统回收长任务最大的敌人是系统资源回收。应用退到后台之后,openclaw还在执行任务,但应用进程可能被回收,导致结果回不来。我的处理方案是分两层。第一,任务注册为长时任务,申请后台驻留能力,这样短时间的后台存活是有保证的。第二,即使进程被杀,任务状态存在本地持久化里,网关侧也用sessionId维护着任务上下文。下次应用被拉起时,先查sessionId,如果网关那边任务还在跑,直接恢复订阅进度。实测下来,只要网关侧状态保存完整,应用侧重建会话的过程用户是无感的。4.3 对话卡片渲染不出结果openclaw的返回结果经常是Markdown格式的,有小标题、列表、代码块。我最初想着直接把它当成字符串渲染到Text组件里,结果格式全乱。后来我把渲染逻辑改成了结构化适配。openclaw网关在返回结果时,同时返回一个渲染描述层,标明哪些内容是标题、哪些是列表、哪些是代码块。应用侧根据这个描述层逐段渲染。虽然多写了一点适配代码,但展示效果稳定很多,也不会因为模型输出格式飘了而崩。4.4 模型乱填工具参数:智能体幻觉怎么兜底大模型编排工具调用时,偶尔会编造出根本不存在的参数,或者把参数类型搞错。比如它调网页检索工具时,把搜索词传成了一个URL而不是关键词。这种情况如果在网关侧不拦,错误就会一路透传到用户面前。我的兜底策略是在openclaw网关的工具调用入口加一层校验。严格按工具注册时的JSON Schema校验参数,不合法就打回重试,要求模型重新生成工具调用。同时设置最大重试次数,超过就直接把任务标记为failed,并返回给用户一句"任务执行遇到问题,请换个说法重新试试"。实测这层校验能把工具调用成功率从84%拉到接近99%。现象可能原因处理方式小艺识别到指令但没拉起应用action不匹配或schema解析失败核对action大小写、重启应用清缓存应用拉起后白屏转圈网关地址不可达或鉴权失败单独用脚本调网关接口,确认网络通任务执行一半被回收未正确申请后台任务能力使用长时任务,网关侧保存session状态结果卡片格式错乱直接渲染Markdown字符串网关返回结构化渲染描述,分段渲染模型乱填工具参数缺少调用前校验网关侧加JSON Schema校验和重试逻辑槽位提取为空用户表达方式超出租要范围放宽约束,支持默认值,或走追问流程提示:联调阶段强烈建议给openclaw网关加一个mock模式,工具调用不真执行,只返回预设的假数据。这样可以快速验证整条链路,不用依赖外部服务的稳定性。我在实际做这个接入时,最深的体会是:小艺和openclaw两边都有现成的能力,真正花时间的地方全在"接缝"上——意图怎么匹配、参数怎么对齐、生命周期怎么兜底、格式怎么兼容。把这些接缝处理顺了,整个系统就像一套整体的能力,而不是两个硬拼在一起的模块。最后再分享一个小技巧:跑通第一个闭环之后,别急着加复杂工具。先拿一个最简单的"时间查询"类工具,把从用户说到界面展示结果的完整链路稳定压测几天,再逐步叠加检索、分析、生成类工具。这样每一层引入的变量都是可控的,出问题时排查范围也小。智能体接入最忌讳一上来就堆一堆工具,出了问题根本不知道是哪个环节在捣乱。