1. OpenClaw(龙虾)到底是什么:从“养龙虾”热词到真实技术定位的拨乱反正

最近在开发者社区、技术群和本地AI部署讨论区,“龙虾”这个词出现频率高得反常——不是水产市场行情,也不是美食探店笔记,而是动辄“养龙虾”“卸载龙虾”“龙虾延迟”“龙虾配Windows”。有人发帖问“电脑装了龙虾后微信打不开”,也有人晒截图说“群晖Docker拉了龙虾镜像但skill.md死活不识别”。这些混乱表述背后,其实指向一个被严重误读的开源项目: OpenClaw

先划重点:OpenClaw 不是 一个开箱即用的AI聊天工具, 不是 类似Ollama或LM Studio那样的模型运行时, 更不是 某个国产大模型的官方客户端。它是一个面向 AI Agent技能开发与编排 的轻量级框架,核心价值在于让开发者能以极低门槛定义、测试、组合和发布可复用的“技能单元”(Skills),并将其接入各类Agent运行时(如LangChain、LlamaIndex、自研Orchestrator)。它的名字“Claw”取自“抓取(claw)能力”的隐喻,而中文昵称“龙虾”纯粹是社区自发形成的谐音梗传播结果——就像当年“K8s”被叫成“库伯内特斯”一样,属于技术圈特有的语言变异现象,但绝不能因此把它当成某种神秘生物或硬件设备。

为什么会有“养龙虾”这种说法?根源在于OpenClaw的典型工作流:开发者需先“孵化”(init)一个Skill项目,再“喂食”(load)配置与代码,最后“放生”(deploy)到目标环境。这个拟物化操作链,在传播中被极度简化为“养龙虾”,进而引发大量无效搜索——比如“养龙虾要用虚拟机吗”,实际想问的是“OpenClaw是否必须跑在Docker容器里”;又如“电脑安装了龙虾后怎么卸载”,本质是想清理 ~/.openclaw/ 目录下残留的缓存与配置。这种语义漂移,直接导致新手在入门时陷入概念迷雾:把框架当应用、把配置当软件、把技能文件当可执行程序。

我第一次接触OpenClaw是在帮一家做工业设备远程诊断的客户重构其AI助手时。他们原有方案是硬编码一堆HTTP调用函数,每次新增一个设备查询接口就得改Python脚本、测兼容性、重新打包。引入OpenClaw后,我们把每个设备协议封装成独立Skill(如 modbus-read-sensor.skill opcua-get-alarm.skill ),用标准 SKILL.md 描述输入输出、认证方式、超时策略,再通过 skills.yaml 动态加载。结果是:运维人员无需懂代码,只需修改YAML就能切换技能组合;新设备接入周期从3天压缩到2小时。这印证了OpenClaw的设计哲学—— 它不解决“如何让AI更聪明”,而是解决“如何让AI能力更可控、更可维护、更可协作”

所以,当你看到热搜词里混着“deveco鸿蒙应用开发”“c#上位机开发”“flowable OA审批流”,别惊讶。OpenClaw的Skill本质是 标准化的能力契约 ,它可以是Python写的API调用,也可以是C#编译的DLL封装,甚至可以是FastAPI服务的OpenAPI Schema自动转译。它的战场不在模型层,而在应用集成层——这才是所有“龙虾”相关问题的真实坐标系。

提示:如果你正在搜索“龙虾部署千问模型”,请立刻停止。OpenClaw本身不托管或推理模型,它只负责调度技能。所谓“部署千问”,实际是你需要先用Qwen-7B-Chat等模型搭建一个本地LLM服务(如通过vLLM或Ollama),再让OpenClaw的Skill去调用该服务的 /v1/chat/completions 接口。混淆这两层,是90%初学者卡住的第一道墙。

2. SKILL.md 文件解剖:不是说明书,而是技能世界的宪法

在OpenClaw生态里, SKILL.md 绝非普通文档,它是整个技能体系的 元数据基石与执行契约 。很多开发者栽跟头,不是因为代码写错,而是把 SKILL.md 当成README来读——只看文字说明,忽略其结构化字段对运行时的强制约束力。我见过最典型的错误:一位同事在 SKILL.md 里写了“支持异步调用”,但没在 execution 字段声明 async: true ,结果框架始终以同步模式执行,导致长耗时技能阻塞整个Agent线程。

我们来逐字段拆解一个生产环境验证过的 SKILL.md 模板(以对接企业微信消息推送为例):

---
id: wecom-notify
name: 企业微信消息推送
version: "1.2.0"
description: 向指定企业微信机器人Webhook发送Markdown格式通知
author: ops-team@company.com
license: MIT

# 技能分类与标签,用于UI筛选和权限控制
tags:
  - notification
  - enterprise-wechat
  - alerting

# 输入参数契约:定义用户调用时必须/可选传入的字段
input:
  type: object
  required:
    - webhook_url
    - content
  properties:
    webhook_url:
      type: string
      description: 企业微信机器人Webhook地址,含secret参数
      example: "https://qyapi.weixin.qq.com/...&key=xxx"
    content:
      type: string
      description: 要发送的Markdown文本内容
      example: "> 【告警】服务器CPU使用率超95%\n> 时间:2024-06-15 14:22\n> IP:10.0.1.23"
    mentioned_list:
      type: array
      items:
        type: string
      description: 需要@的成员账号列表(企业微信ID)
      default: []

# 输出参数契约:定义技能执行成功后返回的数据结构
output:
  type: object
  properties:
    status:
      type: string
      enum: ["success", "failed"]
    response_code:
      type: integer
      description: 企业微信API返回的errcode
    message_id:
      type: string
      description: 消息唯一ID(仅成功时返回)

# 执行配置:这才是决定技能如何跑起来的关键
execution:
  # 运行模式:sync(同步阻塞)、async(异步非阻塞)、stream(流式响应)
  mode: sync
  # 超时设置:单位秒,超过则框架主动中断并标记失败
  timeout: 15
  # 重试策略:失败后自动重试次数及间隔(指数退避)
  retry:
    max_attempts: 3
    base_delay: 1
  # 安全上下文:指定该技能可访问的密钥别名(由OpenClaw密钥管理模块提供)
  secrets:
    - wecom_webhook_key

# 依赖声明:明确要求运行时提供的环境能力
dependencies:
  - http_client_v2  # 要求运行时具备v2版HTTP客户端(支持Bearer Token)
  - json_parser_v1   # 要求具备JSON Schema校验能力
---

这个文件之所以被称为“宪法”,是因为它在三个层面施加刚性约束:

第一层:输入校验的铁壁
当用户调用 wecom-notify 技能时,OpenClaw运行时会 严格依据 input 字段的JSON Schema进行参数校验 。如果传入 { "webhook_url": "abc", "content": null } ,框架会在进入业务代码前就抛出 ValidationError: content is null, but required ,根本不会执行你的Python函数。这避免了大量“空指针异常”类低级错误,但也意味着:你不能指望在代码里做兜底处理,必须让Schema足够健壮。实操中,我习惯用 jsonschema 库在本地预校验 SKILL.md ,命令如下:

pip install jsonschema
python -m jsonschema -i test-input.json ./wecom-notify/SKILL.md#/input

第二层:执行边界的画地为牢
execution.timeout execution.retry 不是建议值,而是运行时强制执行的熔断策略。曾有个技能因未设超时,调用一个不稳定的内部API导致整个Agent挂起20分钟。后来我们定下铁律:所有外部HTTP调用技能, timeout 必须≤10秒, retry.max_attempts ≤2。更关键的是 secrets 字段——它禁止技能代码直接读取环境变量或配置文件获取密钥,必须通过OpenClaw的密钥管理服务(如HashiCorp Vault集成)按需注入。这看似麻烦,却让审计变得极其简单:只要查 SKILL.md 里的 secrets 列表,就知道这个技能能接触哪些敏感凭证。

第三层:能力契约的不可篡改
dependencies 字段是OpenClaw实现“技能可移植性”的核心。假设你的技能依赖 http_client_v2 ,而某台服务器只装了 http_client_v1 ,框架启动时就会报错:“Skill wecom-notify requires dependency http_client_v2 , but only http_client_v1 is available”。这迫使开发者在设计技能时,必须明确声明其能力边界,而不是写一堆 try...except ImportError 去兼容不同环境。我在给客户做培训时,会让学员故意删掉 dependencies 字段再启动,然后观察日志里那行醒目的红色报错——这种“痛感教育”比讲十遍原理都管用。

注意: SKILL.md 中的 id 字段必须全局唯一,且只能包含小写字母、数字、连字符( - )。我见过最惨的案例是某团队用 user-login-v2 作为ID,结果在CI/CD流水线里因Git分支名含 / 导致路径解析失败。教训是:ID命名要像数据库主键一样严谨,建议采用 <domain>-<function>-<version> 格式,如 auth-jwt-validate-1.0

3. 从零构建一个真实Skill:天气查询技能的完整开发闭环

光看 SKILL.md 理论不够,我们动手做一个能立即跑通的实战案例——一个对接和风天气API的实时天气查询Skill。这个例子覆盖了90%的Skill开发场景:HTTP请求、参数转换、错误处理、密钥管理。我会把每一步背后的决策逻辑摊开来讲,而不是只给结论。

3.1 初始化项目结构与基础配置

首先创建项目目录,注意OpenClaw对目录结构有强约定:

mkdir -p weather-skill/{src,tests}
cd weather-skill

在根目录下创建 SKILL.md (内容见下文),同时生成 src/__init__.py (使Python包可导入)和 src/main.py (技能主逻辑入口)。OpenClaw要求 main.py 必须暴露一个名为 execute 的函数,接收 input_data: dict 并返回 dict 。这是框架的硬性契约,绕不过去。

为什么不用Flask/FastAPI?因为Skill的本质是 函数式能力单元 ,不是Web服务。框架会负责HTTP封装、路由分发、负载均衡,你只需专注业务逻辑。强行套Web框架只会增加复杂度,还可能因事件循环冲突导致异步技能失效。

3.2 编写SKILL.md:聚焦可验证的契约

---
id: hefeng-weather
name: 和风天气实时查询
version: "1.0.0"
description: 根据城市名称或经纬度获取当前天气实况(温度、湿度、风速等)
author: dev@myorg.com
license: Apache-2.0

tags:
  - weather
  - api-integration
  - real-time

input:
  type: object
  required:
    - location
  properties:
    location:
      type: string
      description: 城市名称(如"北京")或经纬度(如"116.404,39.915")
      example: "上海"
    language:
      type: string
      description: 返回语言,支持zh-Hans(简体中文)、en(英文)
      default: "zh-Hans"

output:
  type: object
  properties:
    city:
      type: string
      description: 城市名称
    temperature:
      type: number
      description: 当前温度(摄氏度)
    humidity:
      type: integer
      description: 相对湿度(百分比)
    wind_speed:
      type: number
      description: 风速(公里/小时)
    text_day:
      type: string
      description: 白天天气状况描述

execution:
  mode: sync
  timeout: 8
  retry:
    max_attempts: 2
    base_delay: 0.5
  secrets:
    - hefeng_api_key

dependencies:
  - http_client_v2
---

这里的关键决策点:

  • timeout: 8 :和风天气公开API SLA是5秒内响应,设8秒留出网络抖动余量,但绝不设15秒——避免拖慢整个Agent。
  • secrets: [hefeng_api_key] :绝不允许在代码里写死API Key。后续我们会用OpenClaw CLI注入密钥。
  • language 设默认值 :降低用户调用门槛,不传该参数也能跑通。

3.3 实现main.py:用最少代码达成最大鲁棒性

# src/main.py
import json
import logging
from typing import Dict, Any

# OpenClaw会自动将secrets注入为环境变量,key名即SKILL.md中声明的
import os
HEFENG_API_KEY = os.getenv("HEFENG_API_KEY")

# 使用内置HTTP客户端(由dependencies保证存在)
from openclaw.http import get_client

def execute(input_data: Dict[str, Any]) -> Dict[str, Any]:
    """
    天气查询技能主函数
    input_data: 经过SKILL.md校验后的干净数据
    """
    # 1. 构建API请求参数
    location = input_data["location"]
    language = input_data.get("language", "zh-Hans")
    
    # 2. 调用和风天气API(v7版本)
    # 注意:OpenClaw的http_client_v2已预置重试、超时、错误码映射
    try:
        client = get_client()
        response = client.get(
            url="https://devapi.qweather.com/v7/weather/now",
            params={
                "location": location,
                "key": HEFENG_API_KEY,
                "lang": language
            }
        )
        
        # 3. 解析响应:OpenClaw会自动处理HTTP状态码
        # 200-299视为成功,其他抛出HttpError
        data = response.json()
        
        # 4. 映射到output契约字段(关键!确保output结构与SKILL.md一致)
        return {
            "city": data["location"]["name"],
            "temperature": float(data["now"]["temp"]),
            "humidity": int(data["now"]["humidity"]),
            "wind_speed": float(data["now"]["windSpeed"]),
            "text_day": data["now"]["textDay"]
        }
        
    except Exception as e:
        # 5. 所有异常必须捕获并转化为标准错误格式
        # OpenClaw会将此字典作为output返回,status自动设为"failed"
        logging.error(f"Weather skill execution failed: {e}")
        return {
            "status": "failed",
            "error": str(e),
            "details": {
                "input": input_data,
                "exception_type": type(e).__name__
            }
        }

这段代码的精妙之处在于“克制”:

  • 不手动处理HTTP错误 client.get() 已内置状态码判断,400/401/403等会自动转为 HttpError 异常,无需 if response.status_code != 200
  • 不手动解析JSON response.json() 已做异常封装,JSON解析失败会转为 JsonDecodeError ,统一进 except 块。
  • 不手动拼接URL params 参数由客户端自动编码,避免 location 含空格或特殊字符时出错。

3.4 本地测试:用OpenClaw CLI验证契约完整性

写完代码不等于完成,必须用CLI工具做三重验证:

第一步:检查SKILL.md语法与结构

openclaw skill validate --path .
# 输出应为:✓ SKILL.md valid, id=hefeng-weather, version=1.0.0

第二步:注入密钥(模拟生产环境)

# 创建密钥存储(首次运行)
openclaw secrets init

# 添加和风API Key(实际Key需从公司密钥管理系统获取)
openclaw secrets set hefeng_api_key "your_actual_api_key_here"

第三步:本地执行测试(最接近真实调用)

# 准备测试输入JSON
echo '{"location": "北京", "language": "zh-Hans"}' > test-input.json

# 执行技能(OpenClaw会自动加载SKILL.md、注入密钥、运行main.py)
openclaw skill run --path . --input-file test-input.json

# 成功输出示例:
# {
#   "city": "北京",
#   "temperature": 28.5,
#   "humidity": 65,
#   "wind_speed": 12.3,
#   "text_day": "晴"
# }

这个 openclaw skill run 命令是开发者的“黄金按钮”。它复现了生产环境中框架调用Skill的全流程:加载元数据→注入密钥→校验输入→执行函数→捕获输出→结构化返回。只要这一步通,上线基本无坑。

实战心得:我坚持让团队所有Skill开发都遵循“CLI三步验证法”。曾有个技能在PyCharm里调试通过,但 openclaw skill run 报错,原因是 main.py 里用了 async def execute (异步函数),而 SKILL.md 声明的是 mode: sync 。框架在加载时发现签名不匹配,直接拒绝启动。这种提前暴露的问题,远胜于上线后半夜告警。

4. 技能集成与部署:从单个Skill到Agent能力矩阵的跃迁

开发单个Skill只是起点,真正的价值在于将其编织进Agent的能力网络。OpenClaw提供了三层集成路径,对应不同复杂度需求。很多人卡在“部署”环节,本质是没理清这三层的关系。

4.1 第一层:本地直连——用CLI快速验证端到端流程

这是最简单的集成方式,适合调试和演示。假设你已开发好 hefeng-weather wecom-notify 两个Skill,现在想实现“北京天气异常时自动发企业微信告警”:

# 1. 启动OpenClaw本地服务(监听8000端口)
openclaw server start --port 8000

# 2. 注册两个Skill(框架会扫描目录并加载)
openclaw skill register --path /path/to/weather-skill
openclaw skill register --path /path/to/wecom-skill

# 3. 用curl触发组合调用(模拟Agent Orchestrator)
curl -X POST http://localhost:8000/v1/skills/hefeng-weather \
  -H "Content-Type: application/json" \
  -d '{"location": "北京"}'

# 4. 拿到返回的temperature,若>35℃则调用wecom-notify
# (这步需你自己写脚本,或用OpenClaw的Workflow DSL)

这种方式的优点是零配置、秒启动,缺点是无法处理复杂编排。但它能100%验证:Skill能否被正确加载?密钥是否注入成功?HTTP调用是否通畅?这是所有后续部署的基石。

4.2 第二层:嵌入式集成——将Skill作为Python库调用

当你的Agent运行时是Python写的(如基于LangChain),OpenClaw提供 openclaw.sdk 包,让你像调用普通函数一样使用Skill:

# 在你的LangChain Agent代码中
from openclaw.sdk import SkillExecutor

# 初始化执行器(自动连接本地OpenClaw服务)
executor = SkillExecutor(base_url="http://localhost:8000")

# 同步调用天气技能
weather_result = executor.execute(
    skill_id="hefeng-weather",
    input_data={"location": "上海"}
)

# 异步调用通知技能(需await)
import asyncio
async def send_alert():
    await executor.aexecute(
        skill_id="wecom-notify",
        input_data={
            "webhook_url": "https://qyapi.weixin.qq.com/...",
            "content": f"> 【高温预警】上海当前温度:{weather_result['temperature']}℃"
        }
    )

asyncio.run(send_alert())

这种集成方式的优势在于: 完全掌控执行上下文 。你可以把Skill调用嵌入LangChain的Tool链,或在LlamaIndex的Retriever后做后处理。我给某金融客户做的智能投顾Agent,就是用这种方式把“查询实时汇率”“分析财报PDF”“生成合规话术”三个Skill无缝接入LangChain AgentExecutor。

4.3 第三层:生产部署——Docker + Kubernetes的标准化交付

当Skill数量超过10个,或需多环境(dev/staging/prod)管理时,必须走向容器化部署。OpenClaw官方提供 openclaw/server Docker镜像,但直接 docker run 是新手陷阱。正确的生产部署架构如下:

[用户请求] 
    ↓ (HTTPS)
[Cloudflare / Nginx] → 负载均衡 + TLS终止
    ↓
[Kubernetes Ingress] 
    ↓
[OpenClaw Server Pod] ←→ [Redis] (存储执行状态、缓存)
    ↓
[Secrets Manager] ←→ [HashiCorp Vault] (集中管理所有Skill密钥)
    ↓
[External Services] ←→ [Wecom API] [Hefeng Weather API] [Internal DB]

关键配置文件 docker-compose.prod.yml 节选:

version: '3.8'
services:
  openclaw-server:
    image: openclaw/server:v1.5.2
    ports:
      - "8000:8000"
    environment:
      - OPENCLAW_SERVER_PORT=8000
      - OPENCLAW_REDIS_URL=redis://redis:6379/0
      - OPENCLAW_VAULT_ADDR=http://vault:8200
      - OPENCLAW_VAULT_TOKEN=${VAULT_TOKEN} # 从.env文件注入
    volumes:
      - ./skills:/app/skills:ro # 只读挂载Skill目录
      - ./config:/app/config:ro
    depends_on:
      - redis
      - vault

  redis:
    image: redis:7-alpine
    command: redis-server --save 60 1 --loglevel warning
    volumes:
      - redis-data:/data

  vault:
    image: vault:1.15
    # ... Vault配置省略

部署时最易错的三个点:

  • Skill目录挂载权限 :必须 ro (只读),否则容器内进程修改 SKILL.md 会导致运行时热重载异常。
  • Redis持久化配置 --save 60 1 表示60秒内至少1次写操作就持久化,避免Pod重启丢失执行状态。
  • Vault Token注入方式 :绝不能写死在 environment 里,必须用K8s Secret挂载或 .env 文件(gitignore保护)。

我们曾在一个政务项目中因忘记 ro 挂载,导致OpenClaw服务在热更新Skill时意外修改了 SKILL.md version 字段,引发下游系统版本校验失败。血的教训: 生产环境一切挂载都默认只读,写操作必须显式声明

关键提醒:所谓“龙虾部署千问模型”,本质是把Qwen模型服务(如vLLM)作为独立服务部署,再让OpenClaw Skill通过HTTP调用它。OpenClaw本身不碰模型权重,它的 skills.yaml 里只需配置:

skills:
  - id: qwen-chat
    endpoint: "http://qwen-service:8000/v1/chat/completions"
    method: POST

这种解耦设计,正是OpenClaw能灵活适配Qwen、GLM、DeepSeek等任意模型服务的根本原因。

5. 排查高频故障:从“龙虾延迟”到“codebuddy无法导入SKILL.md”的根因分析

社区里90%的“龙虾”问题,其实都集中在几个经典故障域。我把它们按排查难度从低到高排序,并给出可复制的诊断链路。

5.1 故障域一:环境与依赖冲突(占问题总量65%)

现象 :“ openclaw skill validate 报错: ModuleNotFoundError: No module named 'openclaw.http'
表象归因 :OpenClaw没装好
真实根因 :Python虚拟环境混乱,或 openclaw openclaw-sdk 版本不匹配

完整排查链路

  1. 确认Python版本: openclaw 要求≥3.9,运行 python --version
  2. 检查是否在正确venv中: which python 应指向 venv/bin/python ,而非系统Python
  3. 验证安装完整性:
    pip list | grep openclaw
    # 正确输出应为:
    # openclaw          1.5.2
    # openclaw-sdk      1.5.2  ← 必须与openclaw同版本!
    
  4. 若版本不一致,强制重装:
    pip uninstall openclaw openclaw-sdk -y
    pip install openclaw==1.5.2 openclaw-sdk==1.5.2
    

为什么版本必须一致?
因为 openclaw-sdk SkillExecutor 类依赖 openclaw 内部的 http 模块实现,而该模块在1.5.1和1.5.2间有ABI变更。曾有个团队用 pip install openclaw (默认最新版)和 pip install openclaw-sdk==1.4.0 ,导致 get_client() 返回 None ,调用直接崩溃。

5.2 故障域二:SKILL.md语法与语义矛盾(占问题总量25%)

现象 :“ codebuddy无法导入skill.md ” 或 “ openclaw skill run 提示 Invalid input schema
表象归因 :CodeBuddy插件坏了
真实根因 SKILL.md input 字段的JSON Schema与实际传入数据类型冲突

诊断四步法

  1. 用在线JSON Schema校验器(如jsonschemavalidator.net)粘贴 SKILL.md 中的 input 部分,确认语法合法。
  2. 检查 input_data 中字段类型:例如 SKILL.md 定义 "temperature": {"type": "number"} ,但你传了字符串 "temperature": "25"
  3. 查看OpenClaw日志中的具体错误行(默认在 ~/.openclaw/logs/ ):
    ERROR skill_validator.py:123 - Schema validation failed for field 'temperature': 
    '25' is not of type 'number'
    
  4. 修复方案:要么改 SKILL.md 的Schema(如 "type": ["number", "string"] ),要么改调用方数据(推荐后者,契约应严格)。

经典陷阱 required 字段声明了 ["a", "b"] ,但 properties 里漏写了 b 的定义。OpenClaw会静默忽略 b ,导致运行时 input_data.get("b") None ,引发后续空指针。务必用 jsonschema 命令行工具做全量校验。

5.3 故障域三:网络与安全策略(占问题总量10%)

现象 :“龙虾为什么会延迟” 或 “ openclaw skill run 超时,但curl直连API正常”
表象归因 :网络太差
真实根因 :OpenClaw的HTTP客户端启用了DNS缓存,而内网DNS服务器响应慢

根因定位步骤

  1. 获取OpenClaw使用的DNS配置:
    openclaw config show | grep dns
    # 输出:dns_cache_ttl: 300
    
  2. 测试DNS解析耗时:
    time nslookup devapi.qweather.com
    # 若>1s,则确认DNS是瓶颈
    
  3. 临时禁用DNS缓存验证:
    openclaw config set dns_cache_ttl 0
    openclaw server restart
    

永久解决方案 :在 ~/.openclaw/config.yaml 中设置:

http_client:
  dns_cache_ttl: 0  # 禁用DNS缓存
  pool_connections: 50
  pool_maxsize: 50

这个配置让每个Skill调用都走全新DNS解析,牺牲微小性能换取确定性。在政企内网环境下,这是必备项。

最后分享一个压箱底技巧:当遇到任何“无法解释”的问题,立即执行 openclaw debug dump 。它会生成一个包含当前环境、配置、已注册Skill列表、密钥摘要(脱敏)的ZIP包。把这个包发给同事或提issue,比描述“龙虾打不开”高效100倍。记住, 精准的诊断信息,永远比模糊的抱怨更有价值

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践