ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

用 ZCode 做代码分析:基于 nanobot 实例的宣讲手册

用 ZCode 做代码分析:基于 nanobot 实例的宣讲手册 用 ZCode 做代码分析——基于 nanobot session 实例的宣讲手册本文档定位一份可拿去做内部分享/培训的宣讲稿。它不是抽象的工具说明书而是把本会话“clone HKUDS/nanobot 并分析其功能与非功能特性”的真实过程复盘提炼出实战打法 避坑要点。配套阅读plans/nanobot-feature-analysis.md本 session 产出的分析报告目录一、Session 全景回顾二、ZCode 代码分析的五个阶段打法三、关键工具用法详解结合 nanobot 实例四、分析注意事项十条铁律五、本 session 踩过的坑与解法六、产出物标准与交付检查清单七、宣讲要点演讲者备注一、Session 全景回顾1.1 用户原始需求“clone https://github.com/HKUDS/nanobot 然后分析其 function 和 non function feature”一句话需求但隐含了三件事获取代码clone 到本地工作区E:\traeworkspace\nanobot分析功能性 非功能性两个维度产出最终用户要的是详细说明的 MD 格式文件1.2 实际执行轨迹时间线阶段动作结果耗时/教训① Clone 尝试git clone https://github.com/HKUDS/nanobot.git .2 分钟超时失败❌② 重试 shallowgit fetch --depth1 改 git config5 分钟超时失败❌③ 换下载方式curl -L .../archive/main.zipgithub.com:443连接失败❌④ 探测可达端点curl api.github.com/raw.githubusercontent.comAPI200raw301✅ 关键转折⑤ 改走 Trees APIGET /repos/.../git/trees/main?recursive1拿到892 个文件完整清单✅⑥ 用 webReader 读文件逐个读 README / pyproject / docs / 源文件关键文件全部读到✅⑦ 产出 MD 报告写入plans/nanobot-feature-analysis.md517 行交付✅⑧ 追问深入用户问进度回调和出站事件是什么补读两个 .py 源文件后详解✅⑨ 本宣讲文档把过程复盘成培训材料本文件✅1.3 核心产出物已落盘文件行数/大小内容plans/nanobot-feature-analysis.md517 行 / 27 KB功能性 非功能性完整分析报告plans/zcode-code-analysis-session-walkthrough.md—本宣讲手册tree.json根目录临时残留261 KBTrees API 响应应清理见第四节铁律 8providers_registry.py根目录临时残留26 KB下载的源文件副本应清理二、ZCode 代码分析的五个阶段打法通用方法论任何分析一个陌生代码库的任务都可套用这五步。阶段 1抵达Get to the code目标让代码以某种形式出现在工作区能被读取。nanobot 实例中的关键教训不要死磕一种方式。git clone (HTTPS) ──失败──► git fetch --depth1 ──失败──► curl zip │ 失败 │ 探测可达端点 (api/raw) │ 成功 ✓打法先试标准git clone。失败立即降级--depth1浅克隆 →--filterblob:none部分克隆 → 单分支 fetch。网络层失败时用curl探测哪些 GitHub 端点可达curl-sL--max-time15-o/dev/null-w%{http_code}\nhttps://github.com# 000 不通curl-sL--max-time15-o/dev/null-w%{http_code}\nhttps://api.github.com# 200 通curl-sL--max-time15-o/dev/null-w%{http_code}\nhttps://raw.githubusercontent.com# 301 通api.github.com通而github.com不通时用 Trees API raw 读取绕过GET /repos/{owner}/{repo}/git/trees/{branch}?recursive1 # 一次性拿全文件清单 GET /repos/{owner}/{repo}/contents/{path} # 拿单文件base64 编码 https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{path} # 拿原始内容阶段 2测绘Map the territory目标不读具体代码先建立结构地图。nanobot 实例做法拿到tree.json后用 Python 统计fromcollectionsimportCounter cCounter()foreintree[tree]:ife[path].startswith(nanobot/)ande[path].endswith(.py):partse[path].split(/)c[parts[1]iflen(parts)3elseroot]1# agent: 43, webui: 32, channels: 24, providers: 16, ...这一步的产出一张哪个目录是干什么的对照表。看目录名就能推断职责channels/ 渠道、providers/ LLM 后端、security/ 安全、cron/ 定时。关键原则先广度后深度。不要一上来就读某个文件先知道有多少文件、分布在哪。阶段 3抽样Read the right files first目标用最少的文件读取建立最大化的理解。nanobot 实例中的优先级按 ROI 从高到低优先级文件类型nanobot 实例为什么P0READMEREADME.md作者自述定位P0包元数据pyproject.toml版本、依赖、入口P0架构文档docs/architecture.md作者自己画的地图比自己瞎摸快 10 倍P1概念文档docs/concepts.md心智模型、术语P1注册表providers/registry.py、channels/registry.py单一真相源——一个文件看完知道全部 provider/channelP2核心入口__init__.py、agent/loop.py导出符号、依赖关系P2关键配置config/schema.py配置项 功能面P3具体实现按需深读用户追问时再读关键技巧——读注册表文件providers/registry.py顶部注释直接给出了设计哲学“Adding a new provider: 1. Add a ProviderSpec to PROVIDERS. 2. Add a field to ProvidersConfig. Done.”一句话就知道这是单一真相源架构。然后正则提取所有name字段42 个 provider 一次列全specsre.findall(rProviderSpec\(\s*\n?\s*name([^]),block)阶段 4深挖Drill down on demand目标针对用户的具体追问读具体源文件。nanobot 实例用户问进度回调和出站事件是什么我没有凭记忆回答虽然上一轮分析里提过这两个符号名而是先声明我之前只看到 import没读实现诚实铁律实际读取bus/outbound_events.py6789 字节全文bus/progress.py2142 字节全文基于源码逐字段解读 11 个事件类型 适配器函数末尾列出 4 条未核实项如MessageBus.publish_outbound的实现这一步的核心纪律每一条声明都要能指到具体文件行。说ProgressEvent有tool_hint字段——因为我在源码里看到了tool_hint: bool False。阶段 5产出Deliver目标把理解固化成可追溯的文档。nanobot 实例产出标准放在plans/子目录遵循全局文档位置约定文件名lowercase-hyphen-separated.md含 frontmattertitle / status / date每条特性锚定到具体文件路径单独一节未经独立核实的事项——显式列出没验证的内容三、关键工具用法详解结合 nanobot 实例3.1Bash——不只是跑命令是探测环境的探头场景 A网络可达性探测nanobot session 里最关键的一次 Bash 调用curl-sL--max-time15-o/dev/null-w%{http_code}\nhttps://github.com# → 000curl-sL--max-time15-o/dev/null-w%{http_code}\nhttps://api.github.com# → 200curl-sL--max-time15-o/dev/null-w%{http_code}\nhttps://raw.githubusercontent.com# → 301三个 HTTP code 一出立刻知道哪条路通。这比反复重试git clone高效得多。⚠️ 避坑Git Bash 在 Windows 上grep -E (a|b|c)会报conflicting matchers specified。多模式匹配要么用-e多次要么用egrep别混用-E和(...)。场景 B用jq/Python 解析 JSON 而不是grep错误示范本 session 踩过curl...|grep-E(default_branch|language|size)# ❌ conflicting matchers正确做法管道给 Pythoncurl-sL...|python-cimport json,sys; djson.load(sys.stdin); print(branch:,d[default_branch])3.2WebFetch/webReaderZ.ai 内置——读远程文件的主力raw.githubusercontent.com直连不稳但通过Z.ai webReader 代理稳定可达。本 session 所有关键文件都是这样读到的。用法对比工具适用nanobot 实例WebFetch(url, prompt)抓网页 用小模型回答抓 README 提取定位mcp__web_reader__webReader抓 URL 转 markdown/text返回全文读源码文件全文关键Bash curl Contents API需要 base64 解码、文件元数据读outbound_events.py全文关键差异WebFetch会把内容喂给小模型做摘要会丢细节webReader返回原文适合需要精确引用源码的场景。分析代码时优先用webReader。3.3Read/Edit/Write——本地文件操作Read读本地文件本 session 因没 clone 成功几乎没用上Write创建/覆盖文件产出 MD 报告用Edit精确字符串替换修改已有文件用⚠️ 文档落盘纪律全局规则所有 Plan/设计文档必须放plans/子目录禁止放项目根目录文件名lowercase-hyphen-separated.md或UPPERCASE.md3.4Agent子代理——大范围搜索的并行利器何时用需要扫描很多文件但只要结论时派Explore子代理去读摘要。何时不用像本 session 这种需要逐行精确引用源码的场景必须主代理亲自读不能委托子代理子代理返回的是摘要会丢原文细节无法支撑某字段名是 X这类精确声明。3.5TodoWrite——长任务的状态追踪本 session 的 todo 演进[下载文件 → 映射结构 → 分析功能 → 分析非功能 → 产出报告] in_progress pending pending pending pending ↓ [完成 → 完成 → 完成 → 完成 → 完成]纪律同一时刻只有一个in_progress做完一个 mark completed 再推进下一个。这让用户能看到进度也防止自己跳步。四、分析注意事项十条铁律这些是本 session 实际触发的约束每条都对应一个具体场景。铁律 1诚实优先——不知道就说未核实绝不编造触发场景分析 provider 时pyproject.toml被 webReader 截断没看到完整依赖列表。错误做法编一个nanobot 大概依赖 fastapi、pydantic、httpx…。正确做法本 session 实际做法在报告第七节明确写“⚠️ 完整依赖列表pyproject.toml经 webReader 返回被截断…具体requires-python版本未在 excerpt 中完整展示。”验证方式每个声明问自己我能指到哪个文件/哪行“指不到就标注未核实”。铁律 2每条论断锚定到文件路径触发场景写 nanobot 功能分析时。错误做法“nanobot 支持飞书、钉钉、Slack 等渠道。”正确做法“飞书nanobot/channels/feishu.py_feishu_ws.py_feishu_instances.py长连接 多实例钉钉dingtalk.pySlackslack.py。”文件路径让读者可以独立验证这是诚实铁律的落地。铁律 3先探测环境再选策略触发场景git clone失败时。错误做法盲目重试三次git clone或者直接放弃。正确做法用curl探测可达端点发现api.github.com通立即切换到 Trees API 方案。铁律 4区分已读源码vs基于文件名推断触发场景列出 24 个 channel 时。诚实表述“24 渠道的文件已核实存在Trees API 清单但每个渠道的完整收发逻辑未逐个验证——属于基于文件存在性的推断。”这两种可信度必须区分不能混为一谈。铁律 5不凭记忆回答追问——重新读源码触发场景用户问进度回调和出站事件是什么。错误做法凭上一轮分析里提过的符号名脑补一份解释。正确做法本 session 实际做法先声明我之前只在 import 列表看到名字没读实现实际读bus/outbound_events.pybus/progress.py基于源码回答末尾列 4 条未核实项铁律 6临时文件不能堆在仓库根目录触发场景本 session 在根目录留了tree.json261 KB和providers_registry.py26 KB。全局规则原文“临时输出/诊断/生成草稿/回放包/一次性导出不放在仓库根目录除非仓库明确规定了根级输出位置。优先用.runtime/、tmp/、artifacts/等专用目录。”本 session 的违规这两个文件应该放tmp/或.runtime/或者用完即删。这是我自己的疏漏正好作为反面教材。修复建议mkdir-ptmpmvtree.json providers_registry.py tmp/# 或分析完成后直接清理rmtree.json providers_registry.py铁律 7文档必须落盘plans/命名lowercase-hyphen-separated全局规则原文“所有 Plan 和设计文档必须放在项目的plans/子目录下禁止放在项目根目录或其他位置。”本 session 遵守情况✅ 两份产出物都在plans/plans/nanobot-feature-analysis.mdplans/zcode-code-analysis-session-walkthrough.md铁律 8长任务用 TodoWrite 显式管理状态触发场景五阶段分析任务。纪律任务开始时建 todo同时只有一个in_progress做完立即 mark completed全部完成后清空或保留为完成态铁律 9WebFetch 会丢细节精确引用用 webReader触发场景读pyproject.toml时WebFetch返回被截断的内容。纪律要这段网页讲了什么→ 用WebFetch小模型摘要要这个文件的完整源码→ 用mcp__web_reader__webReader或Bash curl Contents API要读本地文件→ 用Read铁律 10报告必须含未经核实事项章节触发场景最终交付 nanobot 分析报告时。正确做法单设一节报告第七节列出 7 条未核实项仓库未本地 clone完整依赖列表被截断Stars 数会变每个 channel 完整逻辑未验证性能数字不存在且不编造市场份额对照基于自述跨平台二进制依赖未核查这一节的存在本身就是诚实度的证明。缺了它报告看起来太完美反而可疑。五、本 session 踩过的坑与解法坑 1git clone网络超时现象git clone2 分钟超时git fetch --depth15 分钟超时根因本环境github.com:443被阻断但api.github.com/raw.githubusercontent.com可达解法改走 Trees API webReader教训失败一次后立即探测不要盲目重试同一种方式坑 2Git Bash 的grep多模式报错现象grep -E (a|b|c)→conflicting matchers specified根因Git Bash 的 grep 版本对-E 交替模式的处理解法改用 Pythonjson.load解析或用多个-e教训结构化数据用 JSON 解析器不要用正则硬抠坑 3curl 直连 raw.githubusercontent 不稳现象curl raw.githubusercontent.com/.../fallback_provider.py超时根因同坑 1部分 GitHub 域名直连不稳解法改用 Z.ai 的mcp__web_reader__webReader代理或 Contents API返回 base64教训工具要会切换直连不通就走代理代理不通就走 API坑 4根目录残留临时文件现象tree.json、providers_registry.py留在仓库根目录根因我下载时没指定目录全局规则临时文件卫生没落实解法应移到tmp/或删除见铁律 6教训临时文件创建时就指定专用目录不要事后再补坑 5webReader 返回内容被截断现象读pyproject.toml时dependencies 列表被截断根因webReader 对超长内容有长度限制解法对关键长文件改用 Contents API 拿 base64 全文或分段读教训重要文件不要依赖单次摘要要拿原文六、产出物标准与交付检查清单一份合格的 ZCode 代码分析交付物必须满足结构标准位于plans/子目录禁止根目录文件名lowercase-hyphen-separated.md含 frontmatter至少title、status、date含目录TOC使用中文数字编号不混用阿拉伯数字内容标准每条论断锚定到具体文件路径xxx/yyy.py区分已读源码vs基于文件名推断含未经独立核实的事项独立章节不含编造的性能数字、API、函数名引用的代码符号类名/函数名/字段名来自实际读取的源码过程标准长任务用了 TodoWrite 追踪临时文件放tmp/或.runtime/不堆根目录clone 失败时有降级策略记录用户追问时重新读源码不凭记忆邀请用户独立验证诚实铁律落地报告末尾应有类似表述“所有引用均可追溯到具体文件路径。如需把仓库真正 clone 到本地做更深的代码审计或运行验证建议…”七、宣讲要点演讲者备注7.1 开场建议2 分钟“今天我用一个真实案例讲怎么用 ZCode 分析陌生代码库。这个案例是分析香港大学的开源 AI agent 框架 nanobot。整个过程最有价值的不是结论而是方法——尤其是当我连 git clone 都失败的时候怎么不放弃地找到替代路径。”7.2 三个 Must-Teach 点Must-Teach 1诚实比完整更重要用 nanobot 报告第七节做示范——“我没有编造性能数字因为 README 没提供我也没跑基准。这是诚实铁律真实性和可验证性优先于完整性。”Must-Teach 2工具要会组合降级画一张降级链git clone → shallow fetch → curl zip → 探测端点 → Trees API webReader强调探测端点那一步是转折点——三个 curl 命令决定了后续整个策略。Must-Teach 3每条声明要能指到文件对比两种写法❌ “nanobot 支持多渠道”✅ “nanobot 的channels/目录有 24 个渠道文件已核实 Trees API 清单包括飞书feishu.py、Slackslack.py…”后者让读者可以立刻打开链接验证。7.3 互动环节建议练习题让听众用 ZCode 分析一个他们熟悉的小项目要求产出包含plans/下的 MD 报告至少 3 条未核实事项每条论断带文件路径讨论题“什么时候该用 WebFetch什么时候该用 webReader”“如果连 api.github.com 都不通还有什么办法”“为什么报告里必须有’未核实事项’章节”7.4 收尾建议“ZCode 不是魔法——它会失败git clone 超时、会截断webReader 长度限制、会留垃圾临时文件。但它不会骗你只要你遵守诚实铁律每条声明锚定证据不知道就说不知道。这套方法迁移到任何代码分析任务都成立。”7.5 QA 预案可能的问题建议回答“为什么不直接用 IDE 打开看”小项目可以nanobot 有 892 个文件、43 个 agent 模块IDE 看不过来需要先测绘再深挖“Trees API 有限额吗”有未认证 60 次/小时认证 5000 次/小时。本 session 用了 ~5 次远未触顶“ZCode 和直接用 ChatGPT 分析代码有什么区别”ZCode 有真实工具调用文件读写、命令执行产出可追溯纯 LLM 对话无法验证文件是否真存在“如果项目是私有仓库怎么办”Trees API 需 token或让用户提供本地路径用Read直接读“诚实铁律会不会让报告显得不完整”会但不完整诚实 完整可疑。未核实项是邀请用户补充不是缺点附录本 session 的工具调用统计工具大致调用次数主要用途Bash~12clone 尝试、curl 探测、JSON 解析、文件检查mcp__web_reader__webReader~6读 README/pyproject/docs/源文件全文Write2落盘两份 MD 产出物TodoWrite3五阶段任务状态管理Skilldoc-anatomy1检查文档结构合规性Read0因未 clone 成功本地无文件可读工具调用总数约 24 次产出两份文档517 行 本文件平均每次调用产出约 30 行有效内容。附录进一步阅读全局规则~/.agents/rules/project_rules.md诚实优先核心规则测试诚实~/.agents/rules/test-honest-first.md本 session 主产出plans/nanobot-feature-analysis.mdnanobot 官方文档https://nanobot.wikiGitHub Trees API 文档https://docs.github.com/en/rest/git/trees
返回列表