Datawhale干货
作者:王大鹏,Datawhale成员
给一个项目建 Agent 知识库,通常能拿到架构文档、接口说明和历史复盘,代码也在仓库里。接下来很容易想到:把资料整理好,做索引,让 Agent 遇到问题时去查。
这能解决资料从哪里找的问题。但如果目的是让 Agent 定位生产故障,还要考虑:查到资料以后,它凭什么判断这次问题发生在哪里?
比如,删除接口返回 HTTP 500,Agent 据此判断删除失败。但检查数据后发现,删除已经完成。服务端处理请求时出了错,不代表之前执行的动作都没有生效。只凭状态码决定重试或把结果改回去,都可能处理错。
接口说明没有缺,错误码解释也没有缺。要判断这次故障,还得知道删除过程经过哪些环节,错误发生前哪些步骤已经完成,以及从哪里能查到实际结果。
如果你刚接手这个项目,对它并不熟悉,该怎么把这些知识整理出来?
01
先确定需要支持什么判断
建设知识库之前,先确定它要帮 Agent 做什么。这里的目标是定位生产问题,并为是否修改、修改哪里提供依据。这个目标决定了资料要整理到什么程度。
判断一个行为有没有问题,需要一个预期作为参照。接口原本要完成什么,允许哪些中间状态,出现错误后保证到哪一步,这些都得先说清楚。否则,“当前状态是什么”只是一条记录,还不足以判断它是否异常。
有了预期,还需要知道系统靠什么实现它。同一个结果可能经过多个服务和后台任务,用户看到的错误可能出现在后面的环节,原因却在前面。只列组件名称,没法解释这种关系;需要把过程连起来,写清每一步的输入、结果,以及失败后会发生什么。
把这些判断需要的信息放在一起,可以这样描述一个待分析的问题:
哪个机制原本应该完成什么;实际行为在哪个环节偏离了预期;有什么证据,造成了什么影响。
这里的“机制”,就是系统完成一件事所依靠的过程。它可能在一个服务内完成,也可能跨越多个组件。
这句话还没有涉及当前项目的具体实现,却已经给出了整理资料的方向。架构文档要能回答这段过程涉及谁,设计文档要能解释正常行为,代码和观测资料要能帮助确认实际执行到了哪里。
问题描述中的这些位置,可以叫作“槽位”。它们不是固定的排查步骤,而是做出判断时需要补齐的信息。刚拿到故障时,可以只知道现象,其余位置暂时留空;后续调查的任务就是逐步缩小这些未知。
02
不熟悉项目,先整理它正常时怎么工作
有了上面的结构,仍然不能凭空知道某个模块有哪些状态,也不能推导出线上使用了什么配置。第一性原理能帮助确定需要了解什么,项目事实还得去查。
可以从一条完整的业务流程开始,而不是试图一次读懂整个仓库。
先用文档确定这条流程的目的和边界,再沿代码核对它实际经过的环节。调用顺序、状态变化和失败处理放在一起看,才能得到一份正常工作过程的说明。函数所在的文件可以作为查证入口,但文档的主体应当是过程本身。
不熟悉的地方要留下问题,而不是猜一个解释让文章读起来完整。文档和实现对不上,就记录冲突;代码看不出设计原因,就找设计记录或请维护者确认。暂时没有答案,并不妨碍先整理已经核实的部分。
逐条补充关键流程以后,系统的整体结构也会清楚起来:哪些过程共享同一项状态,哪些失败会传到其他环节,哪些结果可以重试,哪些动作一旦完成就不能简单撤销。这些关系是定位新问题时会反复用到的知识。
整理是否足够,可以用问题来检查。假设某个环节没有按预期工作,Agent 能否从文档中找到正常行为和查证位置?如果只能找到一段职责介绍,还要重新读完整个模块才能理解流程,这部分知识就没有整理到位。
专家认知 = 问题结构 × 对应的领域知识
这个公式是一种设计上的简写,不是数学计算。问题结构帮助确定要回答什么,领域知识提供具体内容。只写一组问题,没有对应内容,Agent 依然需要从头了解项目。
03
把“文档这样写”变成“有依据的判断”
沿流程整理之后,通常会遇到一个问题:同一件事,不同资料说法不同。
设计文档写的是当初希望怎样实现,代码反映某个版本实际怎样实现,线上运行的又未必是仓库最新版本。不能简单规定“永远以代码为准”,然后把所有冲突都解决掉。
需要先明确正在确认什么。如果问的是当前生产行为,就要核对部署版本、实际配置和运行记录;如果问的是系统应该遵守的接口约定,还需要查对应版本的契约。实现违反了契约,也可能正是待修的问题。
每条重要结论都要保留依据、适用条件和待确认事项。整理者相信它,不足以让另一个 Agent 直接拿去使用。
专家知识 = 专家认知 × 事实验证
专家知识可以保留稳定的判断依据,把容易变化的值留在事实来源里。代码入口、接口字段和日志字段并非一律不能写;它们如果有助于查证,就应保留在参考资料中,并注明适用范围。需要避免的是把某次查到的值写成长期不变的规律。
这些内容整理到一起,才不只是对资料的概括。后来接手的人能沿着依据核验结论,也能知道哪些地方不能直接套用。
04
让 Agent 找得到,也知道怎样使用
经过核验的知识仍然可能分散在很多文件里。Agent 每次都从全库搜索开始,容易先命中旧复盘或零散细节,而没有读到当前机制的完整说明。
可以在这些资料前面放一份较短的入口文档。它说明系统的关键过程,列出正常行为和重要约束,再指向详细资料与查证位置。这份优先读取的文档,就是专家底座。
专家知识指内容,专家底座指组织和提供这些内容的方式。底座不需要装下全部资料,但也不能只剩一张目录:Agent 读完以后,至少应当理解当前问题所在模块正常时怎样工作。
使用时,Agent 先把现象放到对应流程中。知识库提供的是正常过程和已知约束,现场调查确认的是这一次发生了什么。两者不一致时,需要继续取证,不能为了让事实符合文档而忽略差异。
求证方法也要单独准备。哪些信息只是线索,怎样检查一个解释是否有反例,什么情况下仍不能动手修改,这些不属于某个模块的工作原理。懂得正常流程,并不保证每次推断都正确。
未知问题的解题能力 = 专家知识 × 求证方法 × 当前事实
前面的删除请求就可以用来验收:Agent 能否把返回错误和动作结果分开,找到检查实际结果的位置,而不是看到错误码就直接处理?如果必须由使用者反复提醒,说明知识或使用说明还需要补充。
专家底座在这里提供认知参照,不规定每次都执行同一组命令。成熟的操作手册仍然有用,但只能在它的适用条件已经得到确认时使用。
05
知识要分开保存,才能按不同速度更新
整理专家知识,并不意味着其余项目资料都没用了。完整的实现说明、接口定义和操作记录仍然需要保存,只是不能把它们当作同一种知识使用。
领域知识记录在不同项目中也能使用的概念和机制。它的适用条件通常比较稳定,但应用到当前项目时仍需核对。
项目设计与实现记录这个系统自己的组成、流程和约束。它不一定能迁移到别的项目,却是定位当前项目问题必不可少的内容。
接口文档保存精确契约,字段和错误语义需要跟版本一起维护。使用与运维资料保存操作方法、适用条件和回滚步骤;排期与责任分工也放在这一类,不能当成长期规则。
日期目录和草稿区用于留下分析过程。尚未确认的猜测在这里可以保留,但不应和已经核实的结论混在一起。
分类时看一条内容的用途、变化速度,以及由什么来源来确认它。不同分类是维护方式的区别,并不是价值高低的排序。专家知识也可能来自对项目实现的深入理解,不只来自通用原理。
一份故障复盘不必整篇搬到某个目录。过程记录留在原处,已经确认的结论分别更新到对应资料,再由索引建立联系。否则同一个结论在几份文档里各存一遍,后面很难保证同时更新。
06
用新问题检查旧知识
知识库是否有用,要看它在下一次问题中起了什么作用。
每次排查结束后,记录 Agent 是从哪里开始走偏的。如果找错了模块,检查入口是否清楚;如果正常流程理解错了,核对相关文档;如果知道流程却得出了没有证据的结论,检查求证要求。把这些问题一律归为“知识不够”,很容易又回到增加文档数量的做法。
更新也不必每次重写整份底座。局部理解有误,就修正相关内容;出现原有结构容纳不了的问题,再调整结构。改完后重跑之前的案例,确认旧问题仍能被正确分析。检查数量可以少,但最好有未参与编写的人或 Agent 独立完成,避免照着已知答案验收。
除了随问题更新,还需要定期复核。依赖版本、关键配置和接口变更之后,检查关联结论;日常整理时处理未确认项和日期目录中的新发现。每条正式结论留下来源与最近核验时间,后续维护者才知道该从哪里查起。没有新证据的猜测,不因重复出现就升级为事实。
刚接手一个陌生项目时,不可能一次写出完整的专家知识。能够做到的是让每个判断有出处,让不知道的地方清楚可见。新问题来了,可以沿着已有过程继续核对;处理完以后,下一位使用者少走一段相同的弯路。
一起“点赞”三连↓