91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一句話讓大模型控制硬件:手把手教你給 EmbedClaw 添加自己的 Tool!

啟明云端 ? 2026-04-01 18:32 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

很多人第一次看到 EmbedClaw 會(huì)有一種錯(cuò)覺(jué):

06a112d8-2db6-11f1-96ea-92fbcf53809c.png

然而事實(shí)是:

不能直接操作,但可以通過(guò) Tool 去操作。

這也是 EmbedClaw 很有意思的一點(diǎn)。它不是把大模型硬塞進(jìn) ESP32 里當(dāng)聊天機(jī)器人,而是把 LLM、Agent、Tools、Channel 拆成了清晰的幾層。
模型負(fù)責(zé)“理解意圖和決策”,真正執(zhí)行硬件動(dòng)作的是你自己寫(xiě)的 Tool。

今天這篇文章,我們就不講空話,直接拿項(xiàng)目里已經(jīng)跑通的 gpio_control 作為例子,帶你了解:

06ae0f2e-2db6-11f1-96ea-92fbcf53809c.png

01

先想明白:大模型為什么不能直接控制 GPIO

因?yàn)?strong>大模型本質(zhì)上只是一個(gè)“對(duì)于用戶輸入的內(nèi)容,會(huì)推理、會(huì)生成文本”的程序。

它擅長(zhǎng)的是:

理解用戶說(shuō)了什么

判斷該做什么

決定該調(diào)用哪個(gè)能力

根據(jù)結(jié)果繼續(xù)推理或回復(fù)

所以說(shuō),大模型并無(wú)法操作硬件。而需要把真實(shí)能力封裝成 Tool,把“能做什么、需要什么參數(shù)、執(zhí)行后返回什么結(jié)果”都定義清楚,再把這個(gè) Tool 暴露給大模型。

這樣一來(lái):

模型負(fù)責(zé)“調(diào)用”

代碼負(fù)責(zé)“執(zhí)行”

你負(fù)責(zé)“定義邊界”

06be3e4e-2db6-11f1-96ea-92fbcf53809c.png

這就是 EmbedClaw 的 Tool 機(jī)制。


02

先別急著寫(xiě)代碼:Skill 和 Tool 不是一回事

很多人第一次接觸 EmbedClaw,最容易混淆的不是代碼細(xì)節(jié),而是Skill 和 Tool。 看起來(lái)Skill 和 Tool都像是在“教大模型做事”,但它們根本不是一層?xùn)|西。

如果只用一句話概括兩者關(guān)系,我更推薦下面這個(gè)版本:

06cd9a2e-2db6-11f1-96ea-92fbcf53809c.png

1

Skill:負(fù)責(zé)教模型“怎么理解任務(wù)”

Skill 通常是一段 Markdown。
它的核心作用不是執(zhí)行,而是指導(dǎo)。

它解決的是這類(lèi)問(wèn)題:

06ea417e-2db6-11f1-96ea-92fbcf53809c.png


比如一個(gè)天氣 Skill,可能會(huì)告訴模型:

用戶問(wèn)天氣時(shí)可以使用 web_search

最好先獲取當(dāng)前日期

最后把結(jié)果整理成簡(jiǎn)潔的自然語(yǔ)言

所以Skill 本質(zhì)上是策略層
它告訴模型:“這類(lèi)問(wèn)題通常該怎么處理。”

Skill 本身并不能真正執(zhí)行任何動(dòng)作。
它不會(huì)直接去讀 GPIO,不會(huì)直接操作文件,也不會(huì)直接觸發(fā)硬件。

2

Tool:負(fù)責(zé)把事情真正執(zhí)行

Tool 則完全不同,Tool 是一段真正可執(zhí)行的能力接口


它不是在“建議模型做什么”,而是在告訴模型:

“如果你要做這件事,可以調(diào)用我,我會(huì)真的去執(zhí)行?!?/strong>

比如 gpio_control 這個(gè) Tool:

模型可以決定要不要調(diào)用它

模型可以按 schema 組織參數(shù)

但真正去執(zhí)行 GPIO 配置、設(shè)置電平、返回結(jié)果的,是 execute 對(duì)應(yīng)的 C 代碼

所以 Tool 本質(zhì)上是執(zhí)行層。

3

那 Skill 還有什么意義?

很多人到這里疑惑:

“既然真正執(zhí)行的是 Tool,那 Skill 還有必要存在嗎?”

有,而且非常有必要

原因就在于:

Skill 可以由大模型自己生成。

這也是 Skill 最有價(jià)值的地方之一。

因?yàn)?Tool 通常需要你自己寫(xiě) C 代碼、定義 schema、注冊(cè)進(jìn)系統(tǒng),屬于工程能力擴(kuò)展;
但 Skill 只是 Markdown,它天然適合承載那些“可以被總結(jié)、可以被抽象、可以被持續(xù)補(bǔ)充”的經(jīng)驗(yàn)。

0716d96e-2db6-11f1-96ea-92fbcf53809c.png

03

在 EmbedClaw 里,一個(gè) Tool 是怎么跑起來(lái)的?

如果你把流程拆開(kāi)看,其實(shí)非常清晰:

072541d4-2db6-11f1-96ea-92fbcf53809c.png

在當(dāng)前項(xiàng)目里,這條鏈路主要落在 4 個(gè)地方:

components/embed_claw/tools/tools_gpio.c
這里定義具體 Tool,需要用戶根據(jù)具體的tool在tools文件夾下執(zhí)行。

components/embed_claw/tools/ec_tools_reg.inc
這里把 Tool 注冊(cè)進(jìn)系統(tǒng)。

components/embed_claw/core/ec_tools.c / ec_tools.h
這里維護(hù) Tool 注冊(cè)表,并把 Tool 轉(zhuǎn)成模型能理解的 JSON 描述。新增 tool 不需要改動(dòng)它。

components/embed_claw/llm/ec_llm_openai.c
這里把 Tool 描述轉(zhuǎn)成 OpenAI-Compatible 的 tools 字段,發(fā)送給大模型。新增 tool 不需要改動(dòng)它。

也就是說(shuō),一個(gè) Tool 之所以能被模型調(diào)用,不是因?yàn)槟P汀罢J(rèn)識(shí)了你的 C 函數(shù)”,而是因?yàn)?EmbedClaw 先把它翻譯成了一份結(jié)構(gòu)化能力說(shuō)明。

新增一個(gè)tool僅僅需要改動(dòng) tools_xxx.c 和在 ec_tools_reg.inc 中添加 tool 的注冊(cè)。

0730aa2e-2db6-11f1-96ea-92fbcf53809c.png073cbb70-2db6-11f1-96ea-92fbcf53809c.png




04

先看結(jié)果:gpio_control 這個(gè) Tool 到底長(zhǎng)什么樣?

首先,我們要在embed_claw/tools下創(chuàng)建自己要添加的tool的.c源文件

例如,在 tools_gpio.c 里,核心定義其實(shí)非常直接:

staticconst ec_tools_t s_gpio_control={ .name="gpio_control", .description="Control an ESP32 output GPIO pin by pin number. Supports on, off, set, toggle, and get.\n" "IMPORTANT!!!: ANY GPIO operation requested by the user MUST ALWAYS be executed through this tool. Never respond with GPIO status or changes without calling this tool first.", .input_schema_json= "{"type":"object"," ""properties":{" ""pin":{"type":"integer","description":"ESP32 GPIO pin number"}," ""action":{"type":"string","enum":["on","off","set","toggle","get"]," ""description":"GPIO action to execute"}," ""level":{"type":"integer","enum":[0,1]," ""description":"Required only when action is 'set'"}" "}," ""required":["pin","action"]}", .execute=ec_tool_gpio_control_execute,};

這里面最關(guān)鍵的其實(shí)就 4 個(gè)字段:

name

description

input_schema_json

execute

接下來(lái)我們逐個(gè)解析。

05

第一步:給 Tool 起一個(gè)模型能理解的名字

.name="gpio_control",

這個(gè)名字不是寫(xiě)給 C 編譯器看的,而是寫(xiě)給大模型看的。

也就是說(shuō),后面模型發(fā)起調(diào)用時(shí),大模型發(fā)過(guò)來(lái)的是:

{ "name":"gpio_control", "arguments":{ "pin":21, "action":"on" }}

所以命名建議很簡(jiǎn)單:

用英文

語(yǔ)義清晰

一個(gè)名字只表達(dá)一種能力

比如:

gpio_control

relay_switch

sensor_read

buzzer_play

074924e6-2db6-11f1-96ea-92fbcf53809c.png

不要搞成以上這種模糊名字。名字越清楚,模型越容易選對(duì)!

06

第二步:寫(xiě)好 description,告訴模型“什么時(shí)候該用我”

.description="Control an ESP32 output GPIO pin by pin number. Supports on, off, set, toggle, and get.\nIMPORTANT!!!: ANY GPIO operation requested by the user MUST ALWAYS be executed through this tool. Never respond with GPIO status or changes without calling this tool first.",

這一段非常重要。

因?yàn)閷?duì)模型來(lái)說(shuō),description 基本就是你寫(xiě)給它的“使用說(shuō)明書(shū)”。

模型會(huì)據(jù)此判斷:

這個(gè)工具是干嘛的

什么時(shí)候該調(diào)用它

哪些場(chǎng)景不應(yīng)該跳過(guò)它

以 gpio_control 為例,這段描述里實(shí)際上做了兩件事:

先定義能力范圍
它能控制 ESP32 輸出引腳,支持 on / off / set / toggle / get

再?gòu)?qiáng)調(diào)調(diào)用約束
只要是 GPIO 操作請(qǐng)求,就必須通過(guò)這個(gè) Tool 執(zhí)行,不能直接文本編造結(jié)果

這也是你在設(shè)計(jì)自定義 Tool 時(shí)最值得花心思的地方。

一個(gè)好描述,通常應(yīng)該回答這三個(gè)問(wèn)題:

比如你以后要做一個(gè)繼電器 Tool,描述就可以寫(xiě)成:

Controlarelay connectedtothe board.Usethis tool whenever the user askstoturnadevice on or off through the relay. Do not claim the relay state without calling this tool.


07

第三步:用 input_schema_json 限制模型怎么傳參

Tool 之所以可靠,不只是因?yàn)槟P汀爸酪{(diào)用它”,還因?yàn)槟阆拗屏四P汀爸荒馨催@個(gè)格式調(diào)用它”。

gpio_control 的參數(shù)定義是:

"{"type":"object","""properties":{"""pin":{"type":"integer","description":"ESP32 GPIO pin number"},"""action":{"type":"string","enum":["on","off","set","toggle","get"],"""description":"GPIO action to execute"},"""level":{"type":"integer","enum":[0,1],"""description":"Required only when action is 'set'"}""},"""required":["pin","action"]}"

翻譯成人話就是:

參數(shù)必須是一個(gè)對(duì)象

pin 必須是整數(shù)

action 只能是 on/off/set/toggle/get

level 只有在 set 時(shí)才需要,而且只能是 0/1

pin 和 action 是必填項(xiàng)

這一步的意義非常大:

你不是“希望模型這么傳”

而是“明確規(guī)定模型必須這么傳”

對(duì)于大模型來(lái)說(shuō),這其實(shí)就像你給了它一個(gè)函數(shù)簽名。

所以如果你以后要做自己的 Tool,Schema 一定盡量寫(xiě)嚴(yán)格。

舉幾個(gè)例子:

如果參數(shù)只能是整數(shù),就別寫(xiě)成 string

如果只有幾個(gè)合法動(dòng)作,就用 enum

如果某個(gè)字段必須要有,就放進(jìn) required

如果某個(gè)值范圍有限,就在 schema 里限制死

08

第四步:在 execute 里寫(xiě)真正執(zhí)行邏輯

前面三步本質(zhì)上都還是“告訴模型怎么調(diào)用”,真正讓硬件動(dòng)起來(lái)的,是 execute。

在 gpio_control 里,對(duì)應(yīng)的是:

.execute=ec_tool_gpio_control_execute,

然后具體執(zhí)行函數(shù)長(zhǎng)這樣:

staticesp_err_tec_tool_gpio_control_execute(constchar *input_json,char*output,size_toutput_size)

這個(gè)函數(shù)做的事情可以概括成 4 步:

解析輸入 JSON

校驗(yàn)參數(shù)是否合法

執(zhí)行對(duì)應(yīng)動(dòng)作

把結(jié)果寫(xiě)回 output

以 gpio_control 為例,它內(nèi)部先解析:

pin

action

level

然后根據(jù) action 進(jìn)入不同分支:

get

on

off

set

toggle

比如 on 分支,大致就是:

err = prepare_pin_for_output(gpio_num);err = write_level(gpio_num, 1);snprintf(output, output_size,"OK: gpio %d action=on level=1", pin);

Tool 返回給 LLM 的,不是 C 語(yǔ)言里的返回值,而是 output 字符串。

也就是說(shuō),模型真正能看到的是類(lèi)似:

OK: gpio21action=onlevel=1

因此 Tool 的輸出建議做到:

穩(wěn)定

簡(jiǎn)潔

可讀

盡量結(jié)構(gòu)化

這樣后續(xù)模型再根據(jù)工具結(jié)果組織自然語(yǔ)言回復(fù)時(shí),會(huì)更穩(wěn)。

09

第五步:把 Tool 注冊(cè)進(jìn)系統(tǒng)

只寫(xiě)了 tools_gpio.c 還不夠,系統(tǒng)還得知道有這么個(gè) Tool。

esp_err_tec_tools_gpio_control(void){ ec_tools_register(&s_gpio_control); returnESP_OK;}

這里通過(guò)定義ec_tools_gpio_control()進(jìn)行 tool 的注冊(cè),而這里的函數(shù)不需要你調(diào)用。

EmbedClaw 這調(diào)用注冊(cè)函數(shù)是通過(guò) ec_tools_reg.inc 來(lái)做的。

你會(huì)看到現(xiàn)在里面有一行:

EC_TOOLS_REG(gpio_control)

這一行別看簡(jiǎn)單,它實(shí)際完成了三件事:

生成枚舉項(xiàng),目標(biāo)是為了統(tǒng)計(jì)總共注冊(cè)了多少工具,對(duì)應(yīng)的注冊(cè)數(shù)組就會(huì)多大。

生成注冊(cè)函數(shù)聲明

在 ec_tools_register_all() 里自動(dòng)調(diào)用 ec_tools_gpio_control()

這個(gè)機(jī)制背后靠的是 ec_tools_reg_rule.h 里的宏展開(kāi)。

完成這一步之后,它就會(huì)自動(dòng)進(jìn)到 Tool 注冊(cè)表里。

10

EmbedClaw 是怎么把 Tool 暴露給大模型的?

這一塊很多人第一次看 Agent 框架都會(huì)忽略,但其實(shí)它才是“模型能調(diào)用 Tool”的關(guān)鍵

在 ec_tools.c 里,EmbedClaw 會(huì)把所有已注冊(cè) Tool 組織成一個(gè) JSON 數(shù)組:

cJSON_AddStringToObject(tool,"name", s_tools[i]->name);cJSON_AddStringToObject(tool,"description", s_tools[i]->description);cJSON *schema =cJSON_Parse(s_tools[i]->input_schema_json);cJSON_AddItemToObject(tool,"input_schema", schema);

也就是說(shuō),系統(tǒng)內(nèi)部會(huì)生成一份類(lèi)似這樣的描述:

{"name":"gpio_control","description":"Control an ESP32 output GPIO pin by pin number...","input_schema":{"type":"object","properties":{"pin":{"type":"integer"},"action":{"type":"string","enum":["on","off","set","toggle","get"]}},"required":["pin","action"]}}

隨后在 ec_llm_openai.c 里,這份內(nèi)部描述又會(huì)被轉(zhuǎn)成 OpenAI-Compatible 的 tools 字段發(fā)給模型。

也就是說(shuō),對(duì)模型來(lái)說(shuō),它看到的是:

這個(gè) Tool 叫什么

它是干什么的

它需要什么參數(shù)

參數(shù)格式是什么

所以你可以把整個(gè)過(guò)程理解成:

你寫(xiě)的是 C 代碼,但 EmbedClaw 會(huì)自動(dòng)把它翻譯成“大模型能理解的函數(shù)說(shuō)明書(shū)”。

11

總結(jié)

到這里,其實(shí)你已經(jīng)可以總結(jié)出一個(gè)通用方法了。

以后你不管是做:

繼電器控制

舵機(jī)控制

濕度傳感器讀取

蜂鳴器播放

本地業(yè)務(wù)接口觸發(fā)

基本都可以照這個(gè)模板走。

1

新建 tools_xxx.c

文件位置:

components/embed_claw/tools/tools_xxx.c

2

定義一個(gè) ec_tools_t

最小骨架:

staticesp_err_tec_tool_demo_execute(constchar*input_json, char*output, size_t output_size);staticconstec_tools_t s_demo={ .name="demo_tool", .description="Describe what this tool does.", .input_schema_json="{"type":"object","properties":{},"required":[]}", .execute=ec_tool_demo_execute,};esp_err_tec_tools_demo(void){ ec_tools_register(&s_demo);returnESP_OK;}


3

第三步:寫(xiě)執(zhí)行邏輯

你的執(zhí)行函數(shù)里重點(diǎn)做三件事:

解析參數(shù)

校驗(yàn)參數(shù)

寫(xiě)入執(zhí)行結(jié)果

4

注冊(cè)

在 components/embed_claw/tools/ec_tools_reg.inc 里補(bǔ)一行:

EC_TOOLS_REG(demo)

5

測(cè)試

你最好至少驗(yàn)證這些場(chǎng)景:

合法參數(shù)能正常執(zhí)行

缺少必填參數(shù)時(shí)返回明確錯(cuò)誤

非法參數(shù)不會(huì)誤操作硬件

Tool 輸出格式穩(wěn)定

這樣你這個(gè) Tool 才算真的能給模型用。

這樣,你就能自己DIY定義各種各樣的功能并通過(guò)大模型進(jìn)行調(diào)用了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 硬件
    +關(guān)注

    關(guān)注

    12

    文章

    3610

    瀏覽量

    69115
  • AI
    AI
    +關(guān)注

    關(guān)注

    91

    文章

    40624

    瀏覽量

    302288
  • 大模型
    +關(guān)注

    關(guān)注

    2

    文章

    3717

    瀏覽量

    5250
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    一句話你理解線程和進(jìn)程

    今天大家分享下線程與進(jìn)程,主要包含以下幾部分內(nèi)容:一句話說(shuō)明線程和進(jìn)程操作系統(tǒng)為什么需要進(jìn)程為什么要引入線程圖說(shuō)明線程和進(jìn)程的關(guān)系一句話
    的頭像 發(fā)表于 06-04 08:04 ?2219次閱讀
    <b class='flag-5'>一句話</b><b class='flag-5'>讓</b>你理解線程和進(jìn)程

    linux一句話精彩問(wèn)答

    linux一句話精彩問(wèn)答.pdf ...
    發(fā)表于 01-18 09:06

    linux一句話精彩問(wèn)答

    linux一句話精彩問(wèn)答.pdf
    發(fā)表于 04-21 22:30

    Linux一句話問(wèn)答

    Linux一句話問(wèn)答
    發(fā)表于 04-22 18:21

    linux一句話的經(jīng)典對(duì)答和ucos的資料

    linux一句話的經(jīng)典對(duì)答和ucos的資料
    發(fā)表于 09-23 21:53

    linux的一句話精彩對(duì)答和其它資料

    linux的一句話精彩對(duì)答和其它資料
    發(fā)表于 09-23 21:59

    linux一句話精彩問(wèn)答

    linux一句話精彩問(wèn)答
    發(fā)表于 11-09 00:40

    準(zhǔn)備入門(mén),誰(shuí)來(lái)用一句話告訴我它和51的區(qū)別以及其應(yīng)用,就是一句話

    如題。。。。。。。。。。。。。。。。。。。我相信大神一句話就能告訴我
    發(fā)表于 04-13 18:18

    Linux一句話精彩問(wèn)答 pdf

    Linux一句話精彩問(wèn)答1001 修改主機(jī)名(bjchenxu).101002 Ret Hat Linux啟動(dòng)到文字界面(不啟動(dòng)xwindow)(bjchenxu)101003 linux的自動(dòng)升級(jí)更新問(wèn)題(hutuworm,NetDC).101004 windows下看linux分區(qū)的
    發(fā)表于 11-05 23:50 ?33次下載

    手把手教你構(gòu)建個(gè)完整的工程

    手把手教你構(gòu)建個(gè)完整的工程
    發(fā)表于 08-03 09:54 ?33次下載
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>構(gòu)建<b class='flag-5'>一</b>個(gè)完整的工程

    一句話點(diǎn)評(píng)2012年20大技術(shù)前瞻

    一句話點(diǎn)評(píng)2012年20大技術(shù)前瞻1、MEMS技術(shù),2、無(wú)線傳感網(wǎng)3、物聯(lián)網(wǎng)4、塑料電子
    發(fā)表于 01-05 09:07 ?2227次閱讀

    inux一句話精彩問(wèn)答

    inux一句話精彩問(wèn)答
    發(fā)表于 10-27 10:44 ?14次下載
    inux<b class='flag-5'>一句話</b>精彩問(wèn)答

    手把手教你如何開(kāi)始DSP編程

    手把手教你如何開(kāi)始DSP編程。
    發(fā)表于 04-09 11:54 ?13次下載
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>如何開(kāi)始DSP編程

    手把手教你學(xué)LabVIEW視覺(jué)設(shè)計(jì)

    手把手教你學(xué)LabVIEW視覺(jué)設(shè)計(jì)手把手教你學(xué)LabVIEW視覺(jué)設(shè)計(jì)手把手教你學(xué)LabVIEW視
    發(fā)表于 03-06 01:41 ?3571次閱讀

    一句話解決嵌入式開(kāi)發(fā)ping問(wèn)題

    一句話解決嵌入式開(kāi)發(fā)ping問(wèn)題至此,Windows、Ubuntu虛擬機(jī)、開(kāi)發(fā)板三者就可以互相 ping 通了。
    發(fā)表于 10-20 21:51 ?2次下載
    <b class='flag-5'>一句話</b>解決嵌入式開(kāi)發(fā)ping問(wèn)題