资讯动态

Plandex 回复解析器实战:从 4.md 测试样例看懂 PlandexBlock 文件操作协议的解析实现

发布时间:2026/9/14 4:41:14 来源:尧图企业网站定制
Plandex 回复解析器实战从 4.md 测试样例看懂 PlandexBlock 文件操作协议的解析实现【免费下载链接】plandexOpen source AI coding agent. Designed for large projects and real world tasks.项目地址: https://gitcode.com/GitHub_Trending/pl/plandex本篇围绕 app/server/types/reply_test_examples/4.md 这一解析器测试样例讲清 Plandex 服务端如何把 LLM 流式返回的自然语言回复其中嵌有PlandexBlock文件代码块逐块解析为可执行的文件操作Operation并结合 ReplyParser 的源码与 reply_test.go 的测试框架说明该样例在测试中的角色、解析状态机的关键路径以及解析结果的数据模型。读完后你可以掌握 Plandex 的模型回复 → 结构化文件操作协议格式、其容错设计maybeFilePath 两阶段确认、描述行提取以及如何按同样的方式为新回复样例补充测试用例。一、样例本身一份被解析器喂的模型回复4.md 并非面向用户的文档而是TestReplyParser测试的第 4 组输入样例。它模拟了一次 LLM 回复模型先给出自然语言推理为Section和SectionizeResponse设计结构随后声明要新建server/types/section.go文件并用PlandexBlock标签包裹出完整文件内容In server/types/ directory, create a new section.go file. - server/types/section.go PlandexBlock langgo pathserver/types/section.go package types type Section struct { Name string Content string Subsection []Section } type SectionizeResponse struct { Sections []Section } /PlandexBlock Once you have checked and confirmed this task, I will proceed to the next task ...这份样例在测试中的预期输出定义于 reply_test.go 的examples切片第 4 项{ Operations: []shared.Operation{ { Type: shared.OperationTypeFile, Path: server/types/section.go, }, }, },即解析器应当从这份回复中恰好提取出1 个OperationTypeFile操作路径为server/types/section.go。它验证的正是解析器对- 文件路径行 带path属性的 XML 风格标签这一经典格式的识别能力——这也是样例中- server/types/section.go与PlandexBlock ...两行必须成对出现的原因。二、协议格式文件操作的三种书写形态从 reply.go 的行级识别逻辑看Plandex 的回复解析支持多类块1. 整文件代码块4.md 所用的核心格式文件内容用开闭标签包裹开头一行PlandexBlock langgo path相对路径path属性是真实目标路径中间为完整文件内容逐行原样收集结尾一行/PlandexBlock此时操作整体提交进operations列表。对应源码中LineHasXmlPathPlandexBlock前缀且含path、extractFilePath的正则path([^])以及遇到/PlandexBlock时执行r.operations append(r.operations, r.currentFileOperation)的分支见 reply.go。2. 路径声明行的宽松变体在正式开标签之前模型通常会先口头报出路径。解析器通过LineMaybeHasFilePath兼容多种写法- 路径、**路径**、# 路径:等前缀再由extractFilePath统一剥掉 Markdown 加粗符号、反引号、引号、file:/filepath:等前缀见 reply.go。4.md 中的- server/types/section.go走的就是这条路径。3. 文件移动 / 删除 / 重置块解析器还支持### Move Files、### Remove Files、### Reset Changes三个章节块内部以- 源 → 目标移动、- 路径删除/重置的列表行书写遇到EndPlandexFileOps/结束。相关提取函数extractMoveFile、extractRemoveOrResetFile均在 reply.go。此外文件块前面的自然语言段落会被提取为该文件的DescriptionsetCurrentFile中把开标签前若干行、跳过末尾 2~4 行后 trim 得到见 reply.go。reply_test_examples中带Only: true标记的第 10 组样例就是专门验证 Description 提取路径的。三、状态机内核why maybeFilePath 两阶段确认ReplyParser是行驱动的状态机核心状态字段见 reply.gomaybeFilePath、currentFilePath、currentFileOperation、isInMoveBlock/RemoveBlock/ResetBlock等。4.md 样例完整走完两阶段确认链路第一遍疑似路径。AddChunk逐行处理当LineMaybeHasFilePath命中- server/types/section.go时只把路径存入r.maybeFilePath不立即确认——因为模型可能只是提到路径而没有真正开块reply.go。第二遍开标签确认。随后一行PlandexBlock langgo pathserver/types/section.go命中PlandexBlock前缀判定此时才调用setCurrentFile(r.maybeFilePath, false)创建OperationTypeFile操作、清空currentFileLines、提取并挂上Description并把maybeFilePath清空reply.go。内容累积。此后每一整行都追加进currentFileOperation.Content和currentFileLines同时每个 chunk 为该操作累加NumTokensreply.go。收块提交。/PlandexBlock行到来时把currentFileOperation追加进r.operations并复位currentFilePathreply.go。收尾。末尾的 Once you have checked... 段落属于已提交文件之后的描述文本进入currentDescriptionLines缓冲区不产生新操作——这正是必须恰好 1 个操作断言能通过的保证。这种先疑似、后确认的设计是从源码结构可以看出来的容错思路把模型提到路径与模型真正开始输出文件解耦避免把正文里随手引用的文件名误判为文件操作。四、流式输入chunk 切分与行重组Plandex 的模型输出是 SSE 流式到达的解析器不能假设按行喂数据。AddChunkreply.go负责把任意长度、任意边界切开的 chunk 重组回整行结构维护lines []string与lineIndex游标chunk 内含换行时拆分后逐行落位超出第二行的剩余内容通过defer递归回喂r.AddChunk(nextChunk, false)注意第二次不重复计数 token。只有检测到一整行完成时才执行上文的状态转移判断。FinishAndRead在流结束时补一个\n强制冲刷最后一行reply.go。五、测试框架reply_test.go 如何消费 4.mdTestReplyParser 的工作方式按序号读取reply_test_examples/%d.md4.md 对应Example_4子测试以tokenSize : 5把整个样例按 5 字符一块切分循环调用parser.AddChunk(chunk, true)——刻意用非行边界切分来模拟真实流式乱边界验证第 3 节的行重组逻辑文件头部注释也说明这是模拟 token;调parser.FinishAndRead()取回ReplyParserRes.Operations断言操作数量等于期望值并逐个比较operation.Name()shared.Operation.Name()返回type | path [→ destination]见 data_models.go对显式给出Description的期望项还会用strconv.Quote对比精确字符串。另外样例可通过Only: true标记单独调试某一组当前仓库中第 10 组被标记见 reply_test.go。一个值得留意的实现细节子测试内的错误信息使用外层循环变量i拼接Example %d: ..., i1, ...而该i在for循环结束后已是最终下标因此当断言失败时打印的编号可能是最后一组而非出错的那组——阅读测试输出时需要以t.Run(Example_%d)的子测试名为准。六、解析产物Operation 数据模型解析结果统一收敛到共享包的数据模型 app/shared/data_models.gotype OperationType string const ( OperationTypeFile OperationType file OperationTypeMove OperationType move OperationTypeRemove OperationType remove OperationTypeReset OperationType reset ) type Operation struct { Type OperationType Path string Destination string Content string Description string ReplyBefore string NumTokens int }4.md 解析完成后得到Typefile, Pathserver/types/section.go, Content...的操作ConvoMessageDescription.Operations同文件 第 216-230 行则把每条模型回复与其产生的操作关联持久化供会话展示与后续构建build流程消费。生产链路上app/server/model/plan/下的流式处理器如tell_stream_processor.go同样基于这套ReplyParser在模型流到达时增量识别文件操作。七、小结从样例到可复用的测试方法4.md 的价值在于它精确覆盖路径行声明 XML 风格PlandexBlock开标签 完整文件内容 收尾自然语言这一最典型回复形态并断言不多不少地产出 1 个文件操作解析协议的关键约束开标签必须带path...路径声明行支持-/**/#:等宽松前缀内容行按整行原样收集/PlandexBlock是提交边界若要为新回复格式增加回归用例在reply_test_examples/下新增N.md同时在 reply_test.go 的examples切片按下标顺序补入期望的[]shared.Operation可用Only: true单独调试测试会自动以 5 字符切块流式回放整个文件。这套协议格式 行驱动状态机 按序样例回归的组合是理解 Plandex 如何把 LLM 自由文本稳健地转换成可执行文件变更的关键切入点。【免费下载链接】plandexOpen source AI coding agent. Designed for large projects and real world tasks.项目地址: https://gitcode.com/GitHub_Trending/pl/plandex创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价