1. 从一个反直觉的念头说起为什么要让 AI 去读功耗计第一次跟朋友聊起这个项目对方的反应基本都是同一句话功耗计不是给人看的吗AI 看它干嘛这个问题问得很实在也正好戳中了这个项目最核心的动机。传统上功耗计这类仪器的数据流向是人 → 仪器 → 人眼 → 手工记录 → Excel中间每一环都靠人肉搬运。一旦你想做长时间的老化测试、批量设备的功耗对比、或者根据实时功耗动态调整负载策略这套流程立刻就崩了——人不可能 7×24 小时盯着屏幕抄数字。IoT Power 这类智能功耗计的出现把仪器 → 数据这一段自动化了它本身带 Wi-Fi 或串口通信能力能把电压、电流、功率、累计电量这些量以结构化数据的形式吐出来。但问题在于数据出来了谁来理解它传统做法是写一个脚本定时拉数据、存数据库、画个图规则是死的——超过某个阈值就报警。这种方案对付已知的异常很好用但对付我总觉得这台设备在某个工况下不太对劲你帮我看看这种模糊需求就完全无能为力。大模型LLM恰好擅长处理这种模糊需求。它能读一段功耗曲线结合上下文判断这个上升沿是不是异常待机功耗 0.8W 是不是偏高两次测试的差异是否在合理波动范围内。但大模型有个天然短板它活在文本世界里碰不到真实的硬件。你没法直接跟 ChatGPT 说去读一下我桌上那台功耗计现在的读数它既没有网络通道也没有设备驱动。MCPModel Context Protocol就是填这个鸿沟的那座桥。简单说MCP 是一套让 AI 模型能够调用外部工具、访问外部数据的标准协议。你可以把它理解成给 AI 装 USB 接口——AI 是主机MCP 服务端是那个 USB 设备插上去之后 AI 就能通过标准接口读写这个设备的能力。给 IoT Power 写一个 MCP 服务端本质上是把读取功耗计数据这个能力封装成一个 AI 可以调用的工具让 AI 从只会聊天变成能动手测功耗。这个项目适合谁三类人最值得看一是做硬件测试、可靠性验证的工程师你们手里大概率有功耗计也大概率被手工记录折磨过二是做 AI Agent、想给自己的产品接入真实物理世界数据的开发者三是对 MCP 协议好奇、想找一个小而完整的练手项目的人。功耗计这个场景足够简单——数据维度少、接口清晰——但又足够真实能让你把 MCP 服务端的完整链路跑通。我自己的出发点更朴素手上有一台 IoT Power做固件低功耗优化的时候每次改完代码都要手动测一遍待机电流测十几次就烦了。我想让 AI 帮我做这件事——我改代码它测功耗测完告诉我这次比上次高了 0.3mA可能是某个外设没关。这个念头就是整个项目的起点。2. 先把 MCP 服务端这件事讲透它到底在解决什么问题2.1 MCP 的本质给 AI 定义一套能做什么的说明书很多人第一次接触 MCP 会被各种术语绕晕其实剥开看MCP 要解决的是一个非常具体的问题AI 模型怎么知道外部世界有哪些能力可用以及怎么调用它们。在没有 MCP 之前每个 AI 应用接入外部工具的方式都是各写各的。你想让 AI 查天气就写个函数调天气 API想让 AI 读数据库就写个函数连数据库。这些函数怎么描述、参数怎么传、返回值什么格式全靠开发者自己约定。换一个 AI 平台整套东西要重写一遍。这就像早年每个手机厂商都用自己充电接口用户出门得带一把线。MCP 做的事情是把这套能力描述 调用约定标准化。一个 MCP 服务端对外暴露的核心概念主要有三个Tools工具AI 可以主动调用的函数。比如read_power读当前功率、start_logging开始记录。每个工具都有名字、描述、参数 schemaAI 看了描述就知道这个工具是干嘛的、该怎么传参。Resources资源AI 可以读取的数据。比如最近一小时的功耗日志。资源和工具的区别在于资源是只读的数据源工具是会执行动作的函数。Prompts提示模板预定义的提示词模板方便用户快速发起某类任务。对 IoT Power 这个场景我们主要用到的是Tools。因为读功耗计本质上是一个动作——你去问设备要数据设备返回给你。这个动作天然适合封装成工具。2.2 为什么是服务端而不是客户端这里有个容易混淆的点。MCP 架构里服务端Server是提供能力的一方客户端Client是消费能力的一方。AI 应用比如某个支持 MCP 的 IDE 或聊天工具扮演的是客户端角色它去连接各种 MCP 服务端把服务端提供的能力汇总起来给模型用。所以给 IoT Power 写一个 MCP 服务端意思是我们写一个程序它一头连着 IoT Power 硬件通过串口、网络或厂商 API另一头用 MCP 协议对外暴露读功耗的能力。AI 应用连上我们这个服务端就能调用读功耗的工具了。这个定位很重要因为它决定了我们的程序边界我们不需要写 AI不需要写聊天界面只需要把读功耗计这件事做扎实然后用 MCP 协议包装好。剩下的交给 AI 应用。这种职责分离让整个项目变得可控——你只要专注把硬件通信和协议封装做对就行。2.3 一个具体的调用链路长什么样为了让你对整体有个画面感我把一次完整的交互链路拆开讲用户在 AI 应用里说帮我看看现在这台设备的功耗。AI 应用把这句话连同当前可用的 MCP 工具列表一起发给大模型。大模型看到有个工具叫read_power描述是读取 IoT Power 当前实时功率于是决定调用它。AI 应用通过 MCP 协议把调用请求转发给我们的服务端。我们的服务端收到请求去跟 IoT Power 通信拿到当前功率值比如 1.23W。服务端把结果按 MCP 格式返回给 AI 应用。AI 应用把结果喂回给大模型大模型组织成自然语言当前设备功耗为 1.23 瓦。整条链路里我们负责的是第 5 步和第 6 步。听起来简单但魔鬼全在细节里——设备通信稳不稳、数据格式对不对、异常怎么处理这些才是真正花时间的地方。3. 动手之前IoT Power 的数据通道怎么打通3.1 先搞清楚你的功耗计到底怎么吐数据这一步是整个项目的地基也是最容易被跳过的一步。很多人一上来就想着写 MCP 协议层结果发现连设备数据都读不稳后面全是空中楼阁。IoT Power 这类设备数据出口通常有这么几种形态你需要先确认自己手上这台属于哪种数据通道典型特征适用场景坑点串口UART/USB-CDC设备插上电脑出现 COM 口需要按协议发指令本地测试、低延迟需要处理串口占用、波特率、粘包Wi-Fi HTTP API设备有 IP能发 HTTP 请求拿 JSON远程监控、多设备需要处理网络抖动、鉴权Wi-Fi MQTT设备主动推数据到 broker实时流、多订阅者需要维护 broker、处理断线重连厂商云 API数据先上云你再从云拉跨地域、免本地部署依赖厂商服务、有延迟、可能限流我手上这台走的是本地 HTTP API 这条路——设备在局域网里有个固定 IP访问/api/v1/realtime这类端点就能拿到 JSON 格式的实时数据。选这条路的原因是它最干净不用处理串口的字节流解析不用维护 MQTT broker一个 HTTP 请求就搞定。如果你的设备只支持串口那也没关系思路是一样的只是把发 HTTP 请求换成发串口指令 解析返回帧。提示在写任何代码之前先用curl或者串口助手手动把数据读出来一次。确认你能拿到数据、看清数据长什么样再动手写程序。这一步花十分钟能省后面几小时的调试。3.2 把原始数据摸清楚字段、单位、刷新率拿到原始数据后别急着写代码先做一件事把数据字段和物理含义一一对应清楚。我拿到的实时数据大概长这样{ voltage: 5.012, current: 0.2456, power: 1.231, energy: 0.0342, timestamp: 1718000000 }看起来简单但有几个细节必须确认单位voltage 是伏特Vcurrent 是安培A还是毫安mA我一开始以为是 mA结果发现是 A差点把 0.2456A 当成 0.2456mA 报给 AI闹了笑话。单位错了后面所有分析都是错的。刷新率设备多久更新一次数据是 100ms 还是 1s这决定了你轮询的频率上限。如果设备 1 秒才更新一次你 100ms 轮询一次就是浪费还可能读到重复值。精度与波动current 保留四位小数但真实波动可能就在第三位。你要知道哪些位是有效信号哪些位是噪声。这直接影响你给 AI 的描述——如果告诉 AI电流精确到 0.0001A它可能会对 0.0001A 的变化大惊小怪而实际上那是噪声。累计量语义energy 是自设备开机累计还是自上次清零累计这决定了你能不能拿它做差值计算。这些信息设备手册里不一定写得清楚最靠谱的办法是实测 交叉验证接一个已知负载比如一个 5V 1A 的电阻负载看读数对不对连续读一百次看波动范围。3.3 通信层的健壮性别让一次超时毁掉整个体验硬件通信和纯软件最大的区别是硬件会抽风。网络会抖、设备会忙、串口会丢包。如果你的 MCP 服务端在设备偶尔不响应时直接抛异常AI 那边收到的就是一句工具调用失败用户体验很差。我在通信层做了三件事超时 重试单次请求超时设 2 秒失败后重试 2 次重试间隔 300ms。三次都失败才向上报错。实测下来绝大多数偶发失败都能被重试救回来。连接复用如果用 HTTP保持一个长连接session别每次请求都新建连接。新建连接的开销在局域网里不明显但高频轮询时累积起来很可观。降级返回如果实在读不到数据不要直接报错而是返回一个带时间戳的失败标记让 AI 知道这次没读到而不是这个工具坏了。这两种情况对 AI 的决策影响完全不同。import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry def build_session(): session requests.Session() retry Retry(total2, backoff_factor0.3, status_forcelist[500, 502, 503, 504]) adapter HTTPAdapter(max_retriesretry) session.mount(http://, adapter) return session def read_power(session, base_url, timeout2.0): try: resp session.get(f{base_url}/api/v1/realtime, timeouttimeout) resp.raise_for_status() return {ok: True, data: resp.json()} except Exception as e: return {ok: False, error: str(e), ts: time.time()}这段代码没什么花哨的但它是整个服务端稳定性的底座。硬件项目里通信层的健壮性永远比业务逻辑重要因为业务逻辑错了你能看出来通信层偶发失败你往往要跑很久才撞上一次。4. 把读功耗封装成 AI 能用的工具MCP 服务端实现4.1 工具设计给 AI 的不是一个函数而是一套能力菜单MCP 服务端最核心的设计决策是暴露哪些工具给 AI。这个决策直接决定了 AI 能做什么、做得好不好。设计工具时我遵循一个原则工具要对应人做这件事时会做的动作而不是对应底层 API 的调用。举个例子底层 API 可能只有一个/realtime端点但我不应该只暴露一个call_realtime_api工具。因为 AI 不知道什么时候该调它调完怎么解读。我应该暴露的是语义化的工具read_power_now读当前实时功耗。描述里写清楚返回什么、单位是什么。read_power_stats读最近一段时间的统计平均、峰值、最小值。这个工具内部会多次采样再聚合。start_power_logging开始持续记录返回一个 session id。stop_power_logging停止记录返回这段时间的完整数据。compare_power_sessions对比两次记录的差异。你看这些工具名都是动作AI 一看就知道什么时候用哪个。而call_realtime_api这种名字AI 得先理解 API 文档才知道怎么用这就把负担转嫁给了模型。工具的描述description是重中之重。MCP 协议里工具描述会直接进入模型的上下文模型就是靠这段描述来决定调不调、怎么调的。我写描述时会包含三要素这个工具做什么、参数什么含义、返回什么格式。比如read_power_now: 读取 IoT Power 功耗计的当前实时读数。 返回包含 voltage(V)、current(A)、power(W)、energy(kWh) 的 JSON。 适用于需要瞬时功耗快照的场景。若需要一段时间内的统计特征 请改用 read_power_stats。最后那句若需要……请改用……很关键它帮模型在多个相似工具间做选择减少误用。4.2 参数 schema让 AI 传参不犯错MCP 工具的参数用 JSON Schema 描述。这里有个经验参数越少越好类型越明确越好。每多一个参数模型传错的概率就上升一点。以read_power_stats为例我最初设计成read_power_stats(duration_seconds, sample_interval_ms, aggregation)三个参数。实测发现模型经常把duration_seconds和sample_interval_ms搞混或者传一个荒谬的采样间隔。后来我简化成{ name: read_power_stats, description: 读取最近一段时间的功耗统计特征平均/峰值/最小。, inputSchema: { type: object, properties: { window: { type: string, enum: [10s, 1m, 5m, 30m], description: 统计时间窗口默认 10s } } } }把连续的时间参数换成枚举模型只能从四个选项里挑传错的可能性几乎为零。采样间隔这种底层细节直接由服务端内部决定比如固定 200ms不暴露给模型。能用枚举就别用自由输入能内部决定就别暴露成参数——这是让 AI 工具好用的关键技巧。4.3 服务端骨架一个最小可运行的 MCP 服务端MCP 官方提供了 Python 和 TypeScript 的 SDK用 SDK 能省掉大量协议细节。下面是一个精简后的服务端骨架Python 版我把它拆成协议层和设备层两部分方便你替换成自己的设备。import asyncio import time from mcp.server import Server from mcp.server.stdio import stdio_server from mcp.types import Tool, TextContent from device import IoTPowerClient # 我们自己封装的设备客户端 app Server(iot-power-mcp) device IoTPowerClient(base_urlhttp://192.168.1.50) app.list_tools() async def list_tools(): return [ Tool( nameread_power_now, description读取 IoT Power 当前实时功耗返回电压(V)、电流(A)、功率(W)、累计电量(kWh)。, inputSchema{type: object, properties: {}}, ), Tool( nameread_power_stats, description读取最近一段时间的功耗统计平均/峰值/最小。, inputSchema{ type: object, properties: { window: {type: string, enum: [10s, 1m, 5m, 30m]} }, }, ), ] app.call_tool() async def call_tool(name: str, arguments: dict): if name read_power_now: result await device.read_now() return [TextContent(typetext, textformat_now(result))] if name read_power_stats: window arguments.get(window, 10s) result await device.read_stats(window) return [TextContent(typetext, textformat_stats(result))] raise ValueError(funknown tool: {name}) async def main(): async with stdio_server() as (read, write): await app.run(read, write, app.create_initialization_options()) if __name__ __main__: asyncio.run(main())这段代码里device那一层是真正跟硬件打交道的部分app这一层是 MCP 协议层。把这两层分开好处是设备换了、通信方式变了协议层一行都不用动。我后来把设备从 HTTP 换成串口只改了IoTPowerClient内部实现MCP 层完全没碰。4.4 返回值格式化给 AI 的数据要自带解读工具返回给 AI 的内容不是越原始越好。原始 JSON 丢给模型模型还得自己算、自己判断单位。更好的做法是在服务端就把数据整理成半成品结论。对比一下两种返回// 原始返回 {voltage: 5.012, current: 0.2456, power: 1.231, energy: 0.0342}// 格式化返回 当前功耗读数时间 14:32:05 - 电压5.012 V - 电流245.6 mA - 功率1.231 W - 累计电量0.0342 kWh 说明电流已换算为 mA 便于阅读功率为瞬时值波动范围约 ±0.02W。第二种返回模型拿到就能直接用不用再做单位换算还附带了波动范围这种它自己算不出来的上下文。服务端的价值一半在于把硬件数据取出来另一半在于把数据整理成 AI 好消化的形态。这一步做得好AI 的回答质量会明显提升。5. 实测中撞上的那些坑从能跑到好用的距离5.1 坑一AI 把噪声当信号虚惊一场项目刚跑通那会儿我让 AI 帮我监控待机功耗。结果它隔三差五就报功耗异常升高我跑过去一看读数从 0.2456A 变成 0.2471A——这点变化完全是测量噪声设备根本没动。问题出在我给 AI 的数据太精确了。原始数据保留四位小数AI 看到 0.2456 和 0.2471 的差异自然觉得变了。但真实情况是这个量级的波动在噪声范围内。解决办法是在服务端做噪声过滤 有效位处理。具体做法对连续采样做滑动平均窗口取 5 个点抹掉高频抖动。在返回给 AI 的描述里明确标注有效精度。比如电流实际稳定在 ±0.5mA 内就告诉 AI电流读数有效精度约 0.5mA小于此范围的差异可视为噪声。对于是否异常的判断不要只给瞬时值给一段时间的统计特征均值、标准差让 AI 基于统计判断而不是单点。改完之后AI 的误报率大幅下降。这个坑的教训是给 AI 的数据要匹配它的判断粒度。你给它四位小数它就会对第四位敏感你告诉它有效位是第三位它就会忽略后面的噪声。5.2 坑二工具调用超时AI 那边直接卡死有段时间我发现AI 应用在调用读功耗工具时偶尔会卡住十几秒。排查后发现是设备在忙的时候比如正在做内部校准HTTP 请求会挂起而我的超时设得太长10 秒导致 AI 应用一直在等。这里要理解一个 MCP 交互的特性工具调用是同步阻塞的。AI 应用发出调用请求后会一直等到服务端返回。如果服务端卡 10 秒AI 那边就卡 10 秒用户体验极差。我的修复方案是把超时压到 2 秒并且在服务端做异步化如果设备响应慢服务端先返回一个正在读取的中间状态后台继续读读完再通过 MCP 的进度通知机制推给客户端。不过大多数 MCP 客户端对进度通知的支持参差不齐所以更稳妥的做法还是把单次调用控制在 2 秒内读不到就快速失败让 AI 决定要不要重试。提示MCP 工具调用的超时预算建议控制在 3 秒以内。超过这个时间用户会明显感觉到卡。如果某个操作天然耗时比如 30 秒的功耗记录应该拆成启动任务和查询结果两个工具而不是让一个工具阻塞 30 秒。5.3 坑三多设备场景下的张冠李戴我手上有两台 IoT Power一台测主控板一台测外设。最初的服务端只支持单设备配置里写死一个 IP。后来想同时监控两台就临时加了个device_id参数。结果 AI 经常搞混——问主控板功耗它去读了外设那台。根因是工具描述里没有把设备身份讲清楚。修复方式有两个层面在工具描述里明确列出可用设备及其含义比如device_id 可选值main主控板、periph外设板。更彻底的做法是为每台设备注册独立的工具比如read_power_main和read_power_periph。这样 AI 根本不需要传 device_id从工具名就能选对。我最后选了第二种。虽然工具数量翻倍但 AI 的调用准确率接近 100%。当选择本身容易出错时把选择消灭掉变成命名的一部分往往是最省心的方案。5.4 坑四日志记录把内存吃爆start_power_logging这个工具我最初的实现是把所有采样点存在内存里的一个 list。跑短时间没问题但有一次我让它记录了一整夜8 小时200ms 一个点第二天发现服务端进程被系统杀掉了——内存爆了。8 小时 × 5 点/秒 × 3600 秒 ≈ 14.4 万个点每个点一个 dict确实不小。修复方案是边采边落盘采样点直接追加写入本地文件JSONL 格式内存里只保留最近 N 个点的滑动窗口用于实时统计。查询历史时从文件读。import json class PowerLogger: def __init__(self, path): self.path path self.recent [] # 只保留最近 100 个点 def append(self, sample): with open(self.path, a) as f: f.write(json.dumps(sample) \n) self.recent.append(sample) if len(self.recent) 100: self.recent.pop(0)这个改动看起来朴素但它让服务端从跑几小时就崩变成跑几天都稳。硬件数据采集类项目内存管理是绕不过去的坎早做落盘早安心。6. 让这套东西真正好用几个提升体验的细节6.1 给 AI 一份使用说明比优化代码更有效MCP 服务端跑起来之后我发现 AI 用得对不对很大程度上不取决于代码而取决于它有没有被告知正确的使用姿势。MCP 协议支持在服务端初始化时提供一段说明文本这段文本会进入模型的上下文。我在说明里写了几条使用约定读瞬时值用read_power_now判断趋势用read_power_stats。判断功耗是否异常时优先看统计特征不要基于单点下结论。需要长时间监控时先start_power_logging过一段时间再stop_power_logging取结果不要反复轮询read_power_now。这几句话加进去之后AI 的行为明显更合理了。与其在代码里堵各种误用路径不如直接把正确用法告诉模型。模型的理解能力比我们想象的强前提是你得把话说清楚。6.2 错误信息要可行动而不是可读工具调用失败时返回的错误信息质量差别很大。对比// 差的错误信息 Error: request failed// 好的错误信息 读取失败设备 192.168.1.50 在 2 秒内未响应。 可能原因设备正在校准、网络抖动、或 IP 变更。 建议稍后重试若持续失败请检查设备是否在线。第二种错误信息AI 拿到之后能自己决定要不要重试要不要告诉用户检查设备。第一种AI 只能干巴巴地转述失败了。错误信息是给 AI 看的不是给人看的所以要写成AI 能据此做决策的形式。6.3 采样策略别让高频轮询拖垮设备功耗计这类设备内部采样和对外通信是两回事。设备可能内部 100ms 采一次但对外接口有速率限制。如果你不管不顾地高频轮询轻则数据重复重则设备拒绝服务。我的策略是按需采样 缓存服务端维护一个最近读数的缓存缓存有效期设为设备刷新周期的一半。如果 AI 在缓存有效期内再次请求直接返回缓存值不打扰设备。这样既保证了数据新鲜度又避免了无谓的请求。class CachedReader: def __init__(self, device, ttl0.5): self.device device self.ttl ttl self._cache None self._cache_ts 0 async def read(self): now time.time() if self._cache and now - self._cache_ts self.ttl: return self._cache self._cache await self.device.read_now() self._cache_ts now return self._cache这个缓存逻辑简单但效果立竿见影——设备请求量降了一个数量级读数反而更稳定了因为少了并发请求的干扰。6.4 一个容易被忽略的点时间戳的时区功耗数据带时间戳时间戳的时区处理不当会让 AI 的分析全乱套。我踩过一次服务端返回的是 UTC 时间戳AI 按本地时间解读结果凌晨 3 点的功耗峰值实际上是上午 11 点。修复很简单统一用带时区的 ISO 8601 格式比如2024-06-10T14:32:0508:00而不是裸的 Unix 时间戳。这样无论 AI 在哪个时区解读都不会错。硬件项目里时间戳这种小细节最容易埋雷因为它平时不出问题一出问题就是分析结论全错。7. 这套方案还能往哪走几个我自己在试的扩展方向7.1 从读数据到做实验让 AI 主动设计功耗测试现在这套工具只能读AI 是被动响应。下一步我想让它能做实验——比如我告诉它帮我找出这块板子在哪个工作模式下功耗最低它能自己设计一组测试依次切换模式、每个模式测 30 秒、对比结果、给出结论。这需要新增一类工具set_device_mode切换设备工作模式、run_experiment执行一组预设测试。难点在于让 AI 理解实验设计的约束——比如切换模式后要等稳定再测、每个模式测多久才有统计意义。这些约束要写进工具描述里或者封装成一个高层的run_power_experiment工具把实验逻辑固化在服务端。7.2 把功耗数据和代码变更关联起来我做固件优化时最想要的能力是这次代码改动让功耗变了多少。如果 MCP 服务端能同时访问功耗数据和 Git 提交记录就能做这种关联分析。具体做法是再加一个工具get_recent_commits然后让 AI 把功耗变化和代码变更对照着看。这个方向的价值在于它把功耗测试从孤立的一次测量变成开发流程的一部分。每次提交代码AI 自动测一遍功耗异常就提醒。这才是AI 自己看功耗计的完整形态。7.3 多功耗计协同分布式功耗监控单台设备好办多台设备就有意思了。比如一块板子有多个供电域主控、射频、传感器每个域挂一个功耗计。AI 可以同时读多个域的数据分析总功耗上升是哪个域贡献的。这需要在服务端做设备注册 统一命名 并发读取。并发读取用asyncio.gather就能搞定关键是给每个设备一个语义化的名字让 AI 能理解射频域功耗上升 20%这种结论。async def read_all(devices): results await asyncio.gather( *[d.read_now() for d in devices.values()], return_exceptionsTrue, ) return dict(zip(devices.keys(), results))这套东西跑起来之后功耗分析就从看一个数字升级成看一张分布图AI 能给出的洞察也丰富得多。7.4 关于 MCP 生态的一点个人观察MCP 这个协议本身还在快速演进不同客户端对它的支持程度差异很大。我实测下来有的客户端对工具描述的理解很到位有的则经常忽略描述里的细节。这意味着服务端不能假设客户端会完美传递所有信息关键约束最好在工具名和参数 schema 层面就固化下来而不是只写在描述里。另外MCP 服务端的调试体验目前还比较原始。我的做法是在服务端加一个调试模式把所有收到的请求和返回的响应打到日志里出问题时翻日志比猜快得多。这个调试开关在开发阶段一直开着上线前关掉。最后分享一个我自己的小习惯每加一个新工具我都会先自己用自然语言扮演 AI想一遍——如果我是模型看到这个工具名和描述我会在什么情况下调它会不会调错这个自问自答的过程往往能在写代码之前就发现设计问题。工具设计得好不好不取决于代码多优雅而取决于模型能不能用对。这一点是我做完这个项目之后最深的体会。
阅读完成 · 觉得有帮助?