小智更新太快,教程总过期:怎么跟上游而不是跟教程
- 知道遇到问题时该按什么顺序查上游,而不是继续搜教程
- 会读 docs 目录:哪几份文档解决哪类问题
- 学会用 issue 区判断「是我的问题还是它的问题」
- 建立一套对任何活跃开源项目都通用的跟进习惯
本文讲解原理与流程、引用关键片段并注明出处,版权归原作者,遵循其开源协议;一切以上游仓库最新版本为准。
你按一篇看起来很详细的教程做小智,卡住了。于是你去搜下一篇教程,又卡住,再搜第三篇——三篇教程说的步骤还不太一样。
这不是你运气差。小智是个更新非常快的项目,任何一篇教程都是某个时间点的快照。 文章不会跟着更新,项目会。
举个已经发生的例子:上游主线现在要求的是 ESP-IDF v6.0 及以上(推荐 v6.0.2),而网上大量热门教程还在教你装 5.3 或 5.4。那些教程在写的时候是对的,现在对不上了。你照着做出错,不是你的问题。
所以这篇不教具体步骤,教一件更耐用的事:怎么直接读上游。
本文提到的文档清单是 2026 年 7 月底的状态,上游会增删,以仓库当前实际内容为准。小智代码版权归原作者 78 及社区贡献者,遵循 MIT 协议。
顺序:先仓库,后教程
遇到问题时的正确查询顺序是这样的,别倒过来:
第一步:README。 尤其是版本要求、支持的芯片平台这类"地基信息"。地基不对,后面每一步的报错都会把你往错误方向引——你会以为是配置错了、驱动没装,其实只是版本对不上。
第二步:docs/ 目录。 按你的问题类型找对应文档(下面细说)。
第三步:issue 区搜一下。 你遇到的问题,很可能别人早就报过了。
第四步,才是搜教程。 教程的价值在于手把手的过程演示和踩坑经验,这是仓库文档给不了的。但具体的版本号、命令、字段名,一律以仓库为准。
把这个顺序反过来(先搜教程、卡住了再去仓库),就是大多数人正在做的事,也是最耗时间的做法。
docs 目录里有什么
上游 docs/ 下的文档大致覆盖这几类,多数有中文版(文件名带 _zh):
板子相关
custom-board.md/custom-board_zh.md—— 自定义开发板怎么加。你的板子在boards/里找不到时,看这份。
协议相关
mcp-protocol.md/mcp-protocol_zh.md—— MCP 协议本身mcp-usage.md/mcp-usage_zh.md—— MCP 怎么用,注册工具的例子在这websocket.md/websocket_zh.md—— WebSocket 传输mqtt-udp.md/mqtt-udp_zh.md—— MQTT+UDP 传输
配网
blufi.md/blufi_zh.md—— BluFi 配网
版本迁移
esp-idf-6-migration.md—— ESP-IDF 6 的板级兼容状态
其他
glyph-push.md/glyph-push_zh.md—— 字形推送code_style.md/code_style_zh.md—— 代码风格(想提 PR 的话要看)
认识这张表本身就很值钱:它意味着遇到问题时你知道该翻哪一份,而不是漫无目的地搜。比如自定义板子音频不工作——先看 custom-board_zh.md;想让设备执行动作——看 mcp-usage_zh.md;配网连不上——看 blufi_zh.md。
会读"状态型"文档
上游有一类文档不是教程,而是状态报告,它们的用法完全不同,但对判断很有价值。
esp-idf-6-migration.md 就是典型:它记的不是"怎么迁移",而是各个板型在新版本下验证到什么程度了。截至它 2026-07-24 的更新,覆盖 138 个板目录、171 个构建变体,其中 157 个已验证,零个编译阻塞。
这种文档怎么用?用来判断责任边界。
"零个编译阻塞"这句话的实际含义是:上游侧已经趟平了。 所以你编译失败时,可以非常干脆地断定问题在自己这边——环境或者自己的板级代码——而不用在"是不是上游还没适配好"这个方向上浪费时间。
知道"不是它的问题",和知道"是什么问题",价值差不多大。 它能立刻砍掉一半的排查方向。
issue 区:判断"是我的问题还是它的问题"
这是最被低估的一环。
文档写的是"设计上应该怎样",issue 区记的是"实际上发生了什么"。 两者之间永远有差距,而你踩的坑往往就在这个差距里。
一个真实例子:按官方说明在 menuconfig 里改唤醒词,改完不生效。这不是你操作错了——上游有一个仍然开着的 issue 记录了这个现象,根因是资源文件那一层(详见小智唤醒词改了不生效)。不去 issue 区,你可能会反复折腾好几天,并且一直在自我怀疑。
搜 issue 有个小技巧:用报错原文或日志里的关键字符串搜,别用你自己总结的话搜。 日志里那串奇怪的资源名、报错里的函数名,都是高命中率的关键词;而"改了不生效"这种自然语言描述,命中率低得多。
另外,看 issue 的状态:还开着(open)意味着可能没有官方解法,你要么绕路要么等;已关闭的则通常能在讨论里找到解法或者对应的提交。
建立一个轻量的跟进习惯
不需要天天盯着,做到这几条就够了:
动手前扫一眼 README。 尤其是隔了一段时间没碰的时候。版本要求变了,你能第一时间知道。
遇到怪问题先搜 issue。 花两分钟,可能省两天。
关注你依赖的那几个 issue。 比如你卡在唤醒词上,就订阅那个 issue。让消息来找你,比你定期去查高效得多。
记下你当时用的版本。 你自己的项目里写清楚"我用的是哪个 commit、哪个 IDF 版本"。半年后回来接着做时,这条信息价值极高——否则你会面对一个自己也说不清跑在什么版本上的项目。
你改过的代码,怎么跟上游更新
这是自定义板子的人迟早会遇到的问题:你改了 config.h、加了自己的板型、动了几处逻辑,现在上游更新了,你想跟,但又不想丢掉自己的改动。
最糟的做法是直接把仓库删掉重新 clone——你的改动全没了,只能凭记忆重做一遍。做过一次的人都知道有多痛苦,而且必然漏掉几处。
几条实际可行的做法:
第一,把你的改动隔离在尽量少的文件里。 这是最有效的一条,而且是事前能做的。小智的板级抽象本来就是为此设计的:你的硬件差异应该全部落在自己那个板子目录里,而不是散在各处。改动越集中,合并冲突越少。如果你发现自己在改协议层或业务逻辑,先停下来想想有没有别的写法。
第二,用 git 管好自己的改动。 把上游作为一个远程仓库,你的改动放在自己的分支上,更新时把上游的变化合进来。冲突只会发生在你俩都改过的地方——如果你遵守了第一条,冲突会很少。
第三,记下你分叉的位置。 你是从哪个版本、哪个 commit 开始改的,写在自己项目的 README 里。出问题时要对比"上游改了什么",没有这个基准点就无从对比。
第四,别急着跟每一次更新。 活跃项目一天可能有好几个提交,全跟会把你累死,还容易引入新问题。跟版本发布、跟你需要的修复,而不是跟每一次提交。 除非你正等着某个 bug 被修,否则手上项目跑得好好的,不动是合理选择。
这个习惯不只对小智有用
最后说说为什么值得专门写一篇讲这个。
"先看上游当前状态,再看二手教程"这个习惯,对任何活跃的开源项目都成立。 小智只是恰好跑得特别快,把这个问题暴露得特别明显。
会用 AI 之后,这件事其实变得更重要了:你问 AI 关于某个快速迭代项目的问题,它给的答案往往基于训练时见过的旧版本。 它会很自信地告诉你装 5.3——语气毫无破绽。把仓库当唯一真相来源,把教程和 AI 的回答都当参考,这个判断力比记住任何一条具体命令都值钱。