接手一坨看不懂的代码,我用知识库问了七个问题
上周让 AI 帮我写了个小工具,7 个文件、190 行代码。跑起来是对的,我自己 python3 main.py 验过,三笔订单的折扣算得都没问题。
然后我就卡在"要不要发给同事用"这一步。
不是怕它跑不起来,是怕我说不清这 190 行里有什么。这篇记一下我后来怎么处理的,中间踩了一个挺安静的坑。
先说卡在哪
我担心的其实是很具体的几件事。
有没有函数定义了但从来没人调用?某个判断条件写成 > 还是 >=,差的是二十块还是两百块?作者自己有没有留一句"这块回头再改"的记号?
这三条我一条都答不上来。
一开始的笨办法是一个文件一个文件贴进对话框问。问到第三个就崩了:我问"这个函数被谁调用",它答不上来,因为调用它的那个文件我没贴进去。它只看得到我给的那一段。
后来换了个思路:别一段一段喂了,把整个项目丢进去,然后像问同事一样问它。阿里云百炼的知识库正好干这个。工具装一次就行:
npm install -g bailian-cli
bl auth login --api-key sk-你的key
我这边是 bl 2.1.0,macOS,标准 API Key 登录,全程没用到控制台。命令说明在CLI 安装页,密钥在控制台密钥管理页领。
下面全部是我 10 月 20 号在自己电脑上跑出来的结果。
第一条命令就翻车了
我上来就把项目目录整个丢进去:
bl knowledge doc upload --file ./demo-shop --output json
1.7 秒返回,退出码 0。看着挺顺利。

再看返回内容:成功 1 个是 README.md,跳过 6 个是那 6 个 .py。
代码文件一个都没进去,而它不报错。我要是不看返回内容,就会以为整个项目都进库了,然后对着一个只有 README 的库问半天,还会以为是它检索能力不行。
我又单独试了一次,目录里只放 .py 和 .js,这回它明确报错了:
Error: No supported files found
Hint: Supported formats: .pdf .doc .docx .ppt .pptx .xls .xlsx .csv .md .txt .html .png .jpg .jpeg .bmp .gif
支持的是文档、表格、图片这些,代码扩展名一个都不在里面。
顺便记一个细节:这个支持列表在不同报错里给的不一样。目录里全是代码时提示 16 种,含 .csv;另一种报错提示 31 种,含一堆音视频格式,反而没有 .csv。我只报现象,不猜为什么。还有一个是 --output json 在整批被拒的时候会返回空的 files 和 skipped,错误信息只在文本模式里看得见,排查的时候先别加 --output json。
土办法:给代码包一层 .md
我的处理很土。每个 .py 新建一个同名 .md,里面写上文件名当标题,代码原样包进 python 代码围栏。README 本来就是 .md,不动。
for f in demo-shop/*.py; do
n=$(basename "$f" .py)
{ echo "# $n.py"; echo; echo '```python'; cat "$f"; echo '```'; } > "shop-md/$n.md"
done
cp demo-shop/README.md shop-md/
7 个文件、5,519 字节,再传一次:3.8 秒,成功 7 个,跳过 0 个。
代码本身一个字没改,只是换了个容器。后面对标准答案时会看到,这不影响它读代码。
建库、查状态、建服务
建库的时候加个 --wait,让它等到索引跑完再返回,省得自己轮询:
bl knowledge create --name aicodeqa1020 --description "demo-shop 项目源码问答" --doc-id <上一步返回的 7 个 id> --wait
7.4 秒,返回 final_status: COMPLETED。
接着确认 7 个文件都读进去了。这步我没省,因为上传成功不等于索引成功:
bl knowledge doc list --index-id <库 id>
返回 7 条,每条都是 FINISH 加一句"索引构建成功",还给了每个文档的字符数,最大的 report 1393,最小的 config 357。
最后建一个问答服务:
bl knowledge service create --name "aicodeqa-问答" --scene chat --index-id <库 id>
返回一个服务 id,状态是 draft、版本是 beta。beta 版就能直接问,不用先发布,调试的时候改完就能试。
从改扩展名到能问,我一共花了不到一分钟。
问之前,先自己把答案挖出来
这是我觉得整件事里最关键的一步。
我没有直接开始问,而是先自己用 grep 把 7 个问题的答案挖出来存好。不然它说什么我都只能点头。没有标准答案的问答演示,等于让它自己给自己打分。
| # | 我问的 | 我 grep 出来的答案 |
|---|---|---|
| 1 | apply_discount 被哪几个文件调用 |
orders.py 第 19 行、report.py 第 43 行 |
| 2 | 有没有 import 了但没用到的模块 | utils.py 第 3 行的 json,全文件只出现这 1 次 |
| 3 | VIP 门槛多少?正好等于门槛打折吗 | 500;不打折,源码写的是 > 不是 >= |
| 4 | 有没有定义了但从来没被调用的函数 | export_csv 和 vip_edge_report,各 0 次引用 |
| 5 | 有没有留下 TODO 或已知问题 | discount.py 第 18 行:满减和折扣同时命中时没取最优 |
| 6 | 单元测试覆盖率多少 | 项目根本没有测试,README 里写着"没有测试,也没有 CI" |
| 7 | 作者是谁、什么时候上线的 | 材料里没有这两条信息 |
第 6 和第 7 是我故意下的套。这两题材料里没有答案,就看它编不编。
问的形式是单轮:
bl knowledge chat --agent-id <服务 id> --agent-version beta --message "apply_discount 这个函数被哪几个文件调用了?"
七题的结果

七题全对,耗时 5.0 到 48.8 秒。记几条我觉得值得讲的。
第 1 题答出三个文件,全对,后面还补了一句"参考信息中未包含具体行号,故仅列出文件名"。我要的是文件名加行号,它给了文件名,然后明说行号它没有,没有编一个行号出来凑格式。
第 3 题我自己都得回头翻代码才敢确定。它答门槛 500,正好等于不打折,因为判断条件是 if payable > VIP_THRESHOLD:,严格大于。
第 4 题两个死函数全找出来了,而且它自己加了一段限定:"以上结论仅基于当前提供的代码切片进行静态分析。若项目存在其他未展示的测试脚本或外部模块,实际调用情况可能有所不同。"它知道自己看到的是局部。
第 6 题它答"该项目没有单元测试覆盖率",并把 README 原话引了出来。我用脚本扫了这次回答的末段,一个百分号都没有。第 7 题答"无法得知"作者和上线时间,同样扫了一遍,没有任何具体日期。
返回的字数把我愣住了
七题跑完,我看了一眼返回的字数:
| 题 | 耗时 | answer 字段字数 |
|---|---|---|
| 第 1 题 | 31.2 秒 | 9,167 |
| 第 4 题 | 48.8 秒 | 13,597 |
| 第 6 题 | 5.0 秒 | 5,469 |
一个问题的答案有一万三千字?打开看才明白,answer 这个字段里装的是一整条检索加推理的过程:先说共检索到 10 条相关切片,然后是切片原文,接着是它自己的思考,比如"再确认一下 report.py",最后才是答案,而且答案出现了两遍。
七题最短的也有 5,469 字,真正的最终答案通常只有几十到两百字。
所以想拿干净答案得自己截。我的做法是取末尾那一段,或者按 Answer: 切开取后半。这一步不处理,直接拿 answer 去用会很荒唐。
发布,然后删干净
发布正式版之后我顺手查了一下服务配置:
bl knowledge service deploy --agent-id <服务 id> --version-desc "首次发布" --yes
bl knowledge service get --agent-id <服务 id>
发布 1.3 秒,版本号变成 1,状态 deployed。不带 --agent-version 再问一遍同一题走的就是正式版,14.5 秒,结论和 beta 版一致。
但 service get 里那几行让我停了一下:policy: turbo、model: qwen3.6-plus、temperature: 0.7。这两个我全程都没选过,建服务的时候只给了名字和库 id,其余全是服务端默认值。想换得去控制台改,命令行这边建服务时没有对应参数。
清理这一步我想多说两句,因为知识库和文件是会留在账号里的。我这一轮一共创建了 16 个云端资源:1 个知识库、1 个问答服务、14 个数据中心文件。
删的时候有个顺序要注意。删库的命令说明里明确写了"不会删除数据中心的文件",而删文件的命令又警告"引用它的库索引可能失效"。所以我先删服务,再删库,最后删文件:
bl knowledge service delete --agent-id <服务 id> --yes
bl knowledge delete --index-id <库 id> --yes
bl knowledge file delete --file-id <文件 id> --yes
三条命令都被标了高风险,必须加 --yes 才执行。删完我没信它一句"deleted"就完事,逐项复查了一遍:按 id 查服务返回 total: 0,按名字查库列表没有命中,14 个文件 id 逐个查全部不存在。
几点记录
它答对那七题,是因为答案就写在那几行代码里,检索正好把那些片段捞了出来。需要看完整个项目才能下的结论,比如某个改动会影响哪些调用方,它给的是基于片段的推断。运行时行为、类型推断、性能问题它看不到,它也不跑代码。我这个项目能跑,是我自己验的。
它帮上我的是"读"这一段。190 行里那两个死函数、那个没用上的 import、那句 > 而不是 >=,我自己通读也能找出来,但要花半小时,第三遍开始就走神。
命令与耗时汇总,方便照抄:
| 步骤 | 命令 | 耗时 |
|---|---|---|
| 传项目(原样) | knowledge doc upload --file <目录> |
1.7 秒,成功 1 / 跳过 6 |
| 传项目(转 .md) | 同上 | 3.8 秒,成功 7 / 跳过 0 |
| 建库并等索引 | knowledge create --name --description --doc-id --wait |
7.4 秒 |
| 复核索引状态 | knowledge doc list --index-id |
7 条全部 FINISH |
| 建问答服务 | knowledge service create --name --scene chat --index-id |
draft / beta |
| 问答 ×7 | knowledge chat --agent-id --agent-version beta --message |
5.0 到 48.8 秒 |
| 发布正式版 | knowledge service deploy --agent-id --yes |
1.3 秒,版本 1 |
| 正式版对照 | knowledge chat --agent-id --message |
14.5 秒 |
| 清理 | service delete / delete / file delete ×14 |
16 个资源删净并复核 |
模型问答调用一共 8 次,7 题加 1 次正式版对照,其余都是管理类调用,不消耗模型额度。
素材交代一句:demo-shop 是我自己写的虚构演示项目,公司名、订单号、金额、折扣规则都是我编的,不指向任何真实业务。你拿自己的项目跑,结果会完全不同。
回到最开始那个卡住我的地方。这个项目我现在敢交给别人了,不是因为它帮我改了代码,一行都没改,是因为我能说清楚里面有什么了。

浙公网安备 33010602011771号