Plandex 提示词评测实战:基于 promptfoo 的测试驱动 Prompt 开发(TDD for Prompts)
Plandex 提示词评测实战基于 promptfoo 的测试驱动 Prompt 开发TDD for Prompts【免费下载链接】plandexOpen source AI coding agent. Designed for large projects and real world tasks.项目地址: https://gitcode.com/GitHub_Trending/pl/plandex本文以 Plandex 仓库中的 promptfoo 评测 PoC 为核心讲解如何用测试驱动的方式系统性地开发和迭代 AI 编码 Agent 的提示词从评测目录结构、provider 生成模板到一个真实「fix修复提示词」评测的完整剖析——包括 promptfoo 配置、结构化函数调用契约listChangesWithLineNums、JSON Schema 约束和可执行的断言测试。读完本文你可以理解 Plandex 是如何把「调 prompt」这件原本凭感觉的事变成一套可运行、可断言、可 A/B 对比的工程化流程。一、核心思路把 Prompt 当成代码来做 TDD在 AI 编码 Agent 中提示词prompt直接决定模型输出是否稳定可用。Plandex 的做法是把 prompt 当作被测代码走一遍完整的测试驱动循环。promptfoo-poc 的 README 把这一工作流概括为四步先写 prompt提示词先以 markdown/文本文件的形式写出来跑评测通过 promptfoo 把 prompt 放到各种评测场景里实际运行打分与 A/B 测试对 prompt 的输出按若干指标metrics打分并做 A/B 对比迭代改进根据评测结果反复修改 prompt直到达到目标指标。Plandex 团队选择 promptfoo 作为主力评测框架的理由也很直接成熟稳健robust、内置定制能力、搭建成本低。整个 PoC 位于 test/evals/promptfoo-poc 目录目前包含两个真实评测样例fix修复错误更新后的文件和verify校验更新结果外加一个 provider 生成模板 provider.template.yml。二、环境与运行方式2.1 前置依赖README 明确列出运行或创建评测需要安装两样东西Go用于仓库内的生成工具promptfoo评测执行框架2.2 运行评测Run EvalsREADME 给出的运行方式有两种均通过 Makefile 目标驱动# 进入对应评测目录后只跑某一个评测 make eval name_of_eval_dir # 或者一次性跑完所有评测 make evals all即make eval fix跑修复提示词评测make eval verify跑校验提示词评测。适用前提说明在当前的仓库快照中通过文件名搜索只找到了 test/pong/Makefile属于测试用 pong 项目未找到 evals 目录自身的 Makefile 文件。从源码结构看该 PoC 仍处于持续迭代中README 描述的make eval/make gen-eval等目标以实际构建文件为准执行前请先确认本地检出中是否包含对应 Makefile。2.3 创建评测Create Evals新建一个评测时不需要手工搭目录README 提供了两个gen-*命令make gen-eval # 生成评测目录结构落到 evals/promptfoo 目录 make gen-provider # 基于目录中的 config 文件生成 provider 文件README 同时给出了三条重要的执行顺序与配置约束必须先执行gen-eval再执行gen-provider执行gen-provider之前需要先把目录下的 config 文件填写完整你的具体参数根据你使用的 provider需要设置一个包含其 API key 的环境变量。gen-provider的原理可以从现有模板得到印证provider.template.yml 是一个 Go text/template 风格的模板占位符包括{{ .provider_id }}、{{ .temperature }}、{{ .max_tokens }}、{{ .top_p }}、{{ .response_format }}、{{ .tool_type }}、{{ .function_name }}、{{ .parameters }}、{{ .tool_choice_type }}、{{ .tool_choice_function_name }}。生成器把这些值从 config 文件读入模板渲染就得到了一个可直接被 promptfoo 引用的 provider 文件。模板顶部的 TODO 注释也说明了当前的边界# TODO: Add support for more dynamic creation, support for multiple tools, # different API providers parameters, etc.也就是说当前版本聚焦于「单个工具、单一 provider 参数集」的静态生成多工具/多 provider 参数化是后续扩展方向。三、真实样例剖析fix评测下面以fix评测为例完整走一遍目录结构和各文件职责。目录布局为test/evals/promptfoo-poc/fix/ ├── promptfooconfig.yaml # promptfoo 主配置 ├── fix.prompt.txt # 被测提示词 ├── fix.provider.yml # 生成的 provider模型 参数 工具定义 ├── fix.config.properties # gen-provider 的输入参数 ├── fix.parameters.json # 工具函数参数的 JSON Schema └── tests/ │ └── fix.test.yml # 测试用例 断言 └── assets/ ├── shared/pre_build.go # 原始文件fixture └── removal/ ├── changes.md # 拟议的变更 ├── problems.txt # 错误描述fixture └── post_build.go # 期望的最终文件3.1 promptfoo 主配置fix/promptfooconfig.yaml 非常短但体现了 promptfoo 的组合模型——prompt × provider × tests 的笛卡尔积# This configuration compares LLM output of 2 prompts x 2 GPT models across 3 test cases. description: fix prompts: - file://fix.prompt.txt providers: - file://fix.provider.yml tests: tests/*.test.ymlprompts、providers、tests三项各自引用文件或通配符promptfoo 会对每一组组合分别调用模型并执行断言这正是 README 所说「A/B 测试」的落点——多改一个 prompt 文件或多挂一个 provider就能得到不同提示词/模型在同一批测试用例上的横向对比。3.2 provider低温、限 token、强制函数调用fix/fix.provider.yml 指定使用openai:gpt-4o关键采样参数为参数取值作用temperature0.1低温保证输出稳定、可复现利于评测对比top_p0.1与低温配合进一步收窄采样范围max_tokens4096限制单次输出长度response_format{ type: json_object }强制 JSON 输出toolslistChangesWithLineNums函数定义以工具调用function calling承载结构化结果tool_choicetype: function, function.name: listChangesWithLineNums强制模型必须调用该函数不允许自由回答这里有两个工程细节值得注意强制函数调用tool_choice指定了唯一函数名意味着评测中模型「答非所问」的概率被机制性地排除断言可以专注检验 JSON 内容本身是否正确工具 schema 与独立文件同源provider 内联的parameters与 fix/fix.parameters.json 描述的是同一个 schema后者是供生成器/复用引用的独立 JSON Schema 文件。而 fix/fix.config.properties 正是gen-provider这类生成流程的输入参数集可以对照模板占位符一一对应provider_idopenai:gpt-4o temperature0.1 max_tokens4096 top_p0.1 response_formatjson_object function_namelistChangesWithLineNums tool_typefunction function_param_typeobject tool_choice_typefunction tool_choice_function_namelistChangesWithLineNums nested_parameters_jsonfix.parameters.json其中nested_parameters_jsonfix.parameters.json表明工具参数的 JSON Schema 以文件形式被引入最终内联进 provider YAML 的tools数组。3.3 被测提示词一份「结构化变更」契约fix/fix.prompt.txt 是 Plandex 构建失败后「自动修复」环节的系统提示词也是这个评测真正被测的对象。它的任务设定是给定原始文件、错误更新后的文件、拟议的变更以及问题描述产出一组要应用到错误更新文件上的变更列表修复所有问题。提示词要求模型必须修复的问题类别包括语法错误括号/引号/缩进等不配对、缺失或作用域错误的声明、无法直接运行的错误、错误应用的变更、错误删除/覆盖/复制的代码、以及指向原代码的占位注释如// rest of the function...、# existing init code...——这类注释必须用原文件中的真实代码替换。提示词的正文[YOUR INSTRUCTIONS]与[END YOUR INSTRUCTIONS]之间本质上是一份输出契约规定模型必须调用listChangesWithLineNums并返回含三个键的 JSONcomments数组逐项列出拟议更新中的每条代码注释字段为txt注释原文与reference布尔是否为指向原代码的占位引用要求「列全所有注释相同注释也要各列一条」无注释则为空数组problems字符串穷尽地描述错误文件中存在的每一个问题并说明成因与修复方式——不允许只说「某行有语法错误」changes非重叠non-overlapping变更数组每项包含summary、hasChange、old含entireFile/startLineString/endLineString、startLineIncluded(Reasoning)、endLineIncluded(Reasoning)、new。契约中最有 Plandex 特色的是带行号的定位机制所有行号带pdx-前缀如pdx-5: for i : 0; i 10; i {old.startLineString/endLineString必须与原始文件的某一行逐字符精确匹配含行号与缩进。提示词中还写死了多条防止变更重叠的硬性规则除第一条外每个变更的startLineString行号必须高于前一个变更的startLineString与endLineString行号例如前一变更endLineString是pdx-75:则本变更至少pdx-76:单行替换时endLineString必须是空字符串startLineIncluded/endLineIncluded两个布尔值决定边界行是否要包含进new避免替换时误删函数开闭括号并各配一个Reasoning字符串要求模型自述判断理由entireFile: true时只允许存在唯一一条变更且new必须是完整文件相邻或邻近的变更必须合并成更大的变更理想情况只调用一次函数、只产出一个变更JSON 必须始终合法双引号等特殊字符正确转义。提示词末尾是四个模板变量的注入位promptfoo 的vars会填充它们**Original file:** {{preBuildState}} **Proposed updates:** {{changes}} **The incorrectly updated file is:** {{incorrectlyUpdatedFile}} **The problems with the file are:** {{problems}}提示词中还包含一个精简的示例变更对象帮助模型对齐格式{ summary: Fix syntax error in loop body., old: { startLineString: pdx-5: for i : 0; i 10; i { , endLineString: pdx-7: } }, new: for i : 0; i 10; i {\n execQuery()\n }\n }\n} }3.4 参数 JSON Schemafix/fix.parameters.json 以标准 JSON Schema 固化了上述契约根对象required: [comments, problems, changes]每个 change 的required覆盖summary、hasChange、old、startLineIncludedReasoning、startLineIncluded、endLineIncludedReasoning、endLineIncluded、new八字段old内部required: [startLineString, endLineString]。提示词里写死的字段约束与 schema 逐条对应——这正是「提示词工程 schema 约束 强制 tool_choice」三层互相咬合共同保证结构化输出可被程序化消费。3.5 测试用例与断言fix/tests/fix.test.yml 定义了一个「带行号的修复」用例。它用file://相对路径引用 fixture 文件promptfoo 语法相对该 test 文件所在目录解析- description: Check Fix with Line numbers vars: preBuildState: file://assets/shared/pre_build.go changes: file://assets/removal/changes.md problems: file://assets/removal/problems.txt postBuildState: file://assets/removal/post_build.go assert: - type: is-json - type: is-valid-openai-tools-call - type: javascript value: | var args JSON.parse(output[0].function.arguments) return ( args.problems args.changes.length 0 args.changes.some( change change.hasChange change.new.includes(var contextRmCmd cobra.Command{) ) )三层断言各管一件事is-json输出是合法 JSONis-valid-openai-tools-call输出是合法的 OpenAI 工具调用对应 provider 里的 tools 定义javascript自定义断言解析工具调用参数要求problems非空、changes非空且至少有一个hasChange: true的变更其new中包含期望代码片段var contextRmCmd cobra.Command{——即验证模型确实产出了恢复该命令定义这一关键修复。fixture 组织方式体现了「输入→期望」的对照设计assets/shared/pre_build.go是原始文件assets/removal/removal下的changes.md、problems.txt、post_build.go分别提供拟议变更、问题描述和期望的最终状态。verify评测的 assets/valid 与 assets/removal 目录还额外附带了diff.txt可用于人工核对模型给出的 diff 是否与预期一致。四、评测分类与指标体系README 的 Metrics 一节目前标注为「COMING SOON」但同目录下的 evals.md 给出了项目规划的完整评测与指标框架值得作为该文档的延伸来读。4.1 指标分类evals.md 按任务性质把指标分为两类Classification分类型MCC马修斯相关系数、Specificity特异度、Sensitivity敏感度、Accuracy准确率——适用于「判断对/错」二分类式校验比如 verify 提示词判断更新是否有效Regression回归型RMSE、R²、MSE——适用于数值型输出质量的量化对比。4.2 四类提示词的评测维度evals.md 按 Plandex 提示词的角色划分了四组评测维度每组七项与仓库中 server 端实际存在的提示词文件如 build 提示、planning 提示、missing file 提示 等的角色分工相互呼应Build Prompts构建语法检查、完整性检查头部/主体/尾部等必要组件是否齐全、清晰度与精确性、上下文适配性、错误处理指引、依赖项完整性、输出校验标准。Verify Prompts校验准确性、校验标准、术语与步骤的一致性、逻辑流、边界情况处理、用户反馈集成、性能指标。Fix Prompts修复错误识别、修复正确性、影响面分析、回归测试不引入新问题、文档更新、修复后代码质量、性能影响——这与fix评测中「穷尽列出 problems、变更不得重叠、不得引入新错误」的提示词要求一一对应。Function Call Schemas函数调用 schemaschema 有效性、参数一致性、返回类型校验、错误处理机制、跨环境兼容性、文档完整性、安全性考量——对应本文第三节的fix.parameters.json provider 工具定义 is-valid-openai-tools-call断言这一整套实践。五、从 PoC 看这套工作流的可复用要点综合 README、evals.md 与fix/verify两个样例这套测试驱动提示词开发流程的核心做法可以归纳为五点迁移到其他 prompt 密集的 AI 项目时同样适用提示词文件化prompt 存为.txt/.md通过 promptfoo 的file://引用参与组合测试天然支持多版本 A/B参数外置生成 provider用config.properties 模板templates/provider.template.yml 独立 JSON Schema 文件避免手工维护 YAML 中的大段内联 schemagen-eval → gen-provider的顺序约束保证产物完整三层输出保证低温采样temperature/top_p 各 0.1response_format: json_objecttool_choice强制唯一函数调用把「输出格式不稳定」这一变量从评测中剥离让断言只检验语义正确性fixture 驱动的回归用例pre_build / changes / problems / post_build (diff)四件套构成可复跑的输入-期望对断言从「合法 JSON → 合法工具调用 → 业务语义检查javascript 自定义」逐层收紧指标先行在写断言之前先按 Classification / Regression 两套指标定义「好提示词」的量化标准MCC、MSE 等迭代以达标为准而非以观感为准。需要说明的适用边界该目录名为promptfoo-pocREADME 中 Metrics 仍标注 COMING SOONprovider 模板也留有 TODO且当前仓库快照中未包含 README 所引用的 evals Makefile全仓库仅见 test/pong/Makefile。因此本文描述的make eval/make gen-*命令以各时期检出的构建文件为准但配置结构、提示词契约、断言分层这些内容在当前仓库中是可直接查阅和复用的。【免费下载链接】plandexOpen source AI coding agent. Designed for large projects and real world tasks.项目地址: https://gitcode.com/GitHub_Trending/pl/plandex创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Android启动初始化与依赖注入优化实践

Android启动初始化与依赖注入优化实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/14 8:58:25 阅读更多 →
coturn Prometheus 指标导出实战:配置、原理与 UDP 401 限流可观测性

coturn Prometheus 指标导出实战:配置、原理与 UDP 401 限流可观测性

coturn Prometheus 指标导出实战:配置、原理与 UDP 401 限流可观测性 【免费下载链接】coturn coturn TURN server project 项目地址: https://gitcode.com/GitHub_Trending/co/coturn coturn 内置了一个 Prometheus 指标导出器:给 turnserver 加…

2026/9/14 8:58:25 阅读更多 →
RRT与PRM串联运动规划算法在机器人导航中的应用

RRT与PRM串联运动规划算法在机器人导航中的应用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/15 11:56:31 阅读更多 →

最新新闻

如何用 Prefect Managed 基础设施运行 flow 而不自建 worker

如何用 Prefect Managed 基础设施运行 flow 而不自建 worker

如何用 Prefect Managed 基础设施运行 flow 而不自建 worker 【免费下载链接】prefect Prefect is a workflow orchestration framework for building resilient data pipelines in Python. 项目地址: https://gitcode.com/GitHub_Trending/pr/prefect 如果你的 flow 需…

2026/9/15 11:55:52 阅读更多 →
Zettlr 引文工作台实战:从 CSL 参考文献库加载到自动引用、侧边栏文献表与导出

Zettlr 引文工作台实战:从 CSL 参考文献库加载到自动引用、侧边栏文献表与导出

Zettlr 引文工作台实战:从 CSL 参考文献库加载到自动引用、侧边栏文献表与导出 【免费下载链接】Zettlr Your One-Stop Publication Workbench 项目地址: https://gitcode.com/GitHub_Trending/ze/Zettlr 本篇技术指南以 Zettlr 官方交互式教程的 Citing wit…

2026/9/15 11:55:52 阅读更多 →
Kimi K2 本地部署实操指南:16 张卡一条命令跑起万亿参数智能体模型

Kimi K2 本地部署实操指南:16 张卡一条命令跑起万亿参数智能体模型

Kimi K2 本地部署实操指南:16 张卡一条命令跑起万亿参数智能体模型 【免费下载链接】Kimi-K2 Kimi K2 is the large language model series developed by Moonshot AI team 项目地址: https://gitcode.com/GitHub_Trending/ki/Kimi-K2 把 Kimi K2 智能体模型…

2026/9/15 11:55:52 阅读更多 →
InternVL批量推理指南:用batch_chat让多模态推理效率翻倍

InternVL批量推理指南:用batch_chat让多模态推理效率翻倍

InternVL批量推理指南:用batch_chat让多模态推理效率翻倍 【免费下载链接】InternVL [CVPR 2024 Oral] InternVL Family: A Pioneering Open-Source Alternative to GPT-4o. 接近GPT-4o表现的开源多模态对话模型 项目地址: https://gitcode.com/GitHub_Trending/i…

2026/9/15 11:55:52 阅读更多 →
Apple Silicon 上的本地 LoRA 微调:在提交 HF Jobs 前的 macOS 冒烟测试指南

Apple Silicon 上的本地 LoRA 微调:在提交 HF Jobs 前的 macOS 冒烟测试指南

Apple Silicon 上的本地 LoRA 微调:在提交 HF Jobs 前的 macOS 冒烟测试指南 【免费下载链接】skills Give your agents the power of the Hugging Face ecosystem 项目地址: https://gitcode.com/GitHub_Trending/skills7/skills 本指南以 local_training_m…

2026/9/15 11:55:52 阅读更多 →
Hydra 1.1 到 1.2 迁移指南:`hydra.job.chdir` 与作业运行时工作目录行为变更

Hydra 1.1 到 1.2 迁移指南:`hydra.job.chdir` 与作业运行时工作目录行为变更

Hydra 1.1 到 1.2 迁移指南:hydra.job.chdir 与作业运行时工作目录行为变更 【免费下载链接】hydra Hydra is a framework for elegantly configuring complex applications 项目地址: https://gitcode.com/GitHub_Trending/hyd/hydra 本指南面向从 Hydra 1.…

2026/9/15 11:54:51 阅读更多 →

日新闻

Java高级技术:从语言特性到性能优化全解析

Java高级技术:从语言特性到性能优化全解析

1. Java高级技术概述Java作为一门成熟的编程语言,经过二十多年的发展已经形成了完整的生态系统。在企业级应用开发、大数据处理、移动开发等领域,Java都占据着重要地位。掌握Java高级技术不仅意味着能够编写更高效的代码,更代表着开发者能够解…

2026/9/15 0:00:23 阅读更多 →
C#与Halcon结合的工业视觉处理实战指南

C#与Halcon结合的工业视觉处理实战指南

1. 项目概述:C#与Halcon强强联合的视觉处理利器这个基于C#和Halcon的视觉处理Demo项目,是我在工业质检领域摸爬滚打多年后提炼出的实战精华。它完美融合了C#的界面开发优势与Halcon强大的图像处理能力,就像给视觉工程师配上了一把瑞士军刀。项…

2026/9/15 0:00:23 阅读更多 →
32路工业串口服务器的硬核选型指南:确定性、鲁棒性与协议下沉

32路工业串口服务器的硬核选型指南:确定性、鲁棒性与协议下沉

1. 为什么“32路复合型”不是营销话术,而是工业现场真实痛点的硬解你有没有遇到过这样的场景:在某大型能源站的PLC机柜里,十几台不同年代、不同品牌的温控仪、电表、气体分析仪、阀门控制器,全靠RS-485总线挂在一根线上&#xff0…

2026/9/15 0:00:23 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/14 5:45:49 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/15 1:32:25 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/15 1:32:21 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/14 17:35:10 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/14 16:59:29 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/14 5:45:14 阅读更多 →