Dify 提示词工程怎么做?如何写出稳定可控的 Prompt?
Dify 提示词工程先抓住什么?
Dify 里的提示词工程,重点不是把 Prompt 写得更玄,而是让应用在不同输入下稳定输出。一个可上线的 Prompt 至少要说清四件事:模型扮演什么角色、要完成什么任务、可以依据哪些上下文、输出必须长什么样。很多应用在测试时看着不错,上线后开始胡编,通常是边界没写清,而不是模型突然变差。
模板、变量和系统提示词怎么分工?
Dify 的 Prompt Template 支持 {{query}}、{{context}} 这类变量,也支持 Jinja2 风格的条件和循环。固定规则放在系统提示词里,动态内容通过变量传入,后续维护会清楚很多。比如知识库问答不要只写“请专业回答”,而要明确“只能根据资料回答,资料没有就说未提到”。
text你是企业知识库助手,只能依据资料回答。 资料:{{context}} 问题:{{query}} 要求:资料未提到时回答“资料中未提到”;不要编造;三句话以内。
取舍点在于,越不能被用户覆盖的规则,越应该放在系统层;越依赖本次请求的内容,越应该放进变量。环境变量适合保存模型网关、接口域名等配置,但密钥不要出现在可能被模型复述的提示词里。变量名也别写成 data1、result,用 user_question、retrieved_docs 这种名字更利于排查。
如何优化 Prompt?
优化时不要一次改一大段。先准备一组典型问题、边界问题和恶意输入,每次只改角色、示例、格式约束中的一项,再看失败类型是否减少。Few-shot 示例适合分类、抽取、格式转换;开放问答放太多示例,反而会让回答僵硬并增加 token 成本。
如果业务要结构化结果,可以约束 JSON 字段,但后端仍要做解析失败兜底。生产环境常见坑是模型偶尔多输出一句解释,导致 JSON 解析失败。更稳的做法是在 Dify 工作流里加代码节点校验,失败时重试一次或走异常分支。
什么时候不该继续堆 Prompt?
当一个提示词同时承担意图判断、知识检索、业务计算和回答生成时,就该拆成工作流节点。模型适合理解和生成,不适合做确定性校验。复杂应用里,Prompt 工程不是把所有规则写进一段话,而是决定哪些交给模型,哪些交给流程、代码和业务系统。
追问
Dify 的 Prompt Template 和普通提示词有什么区别?
普通提示词是一段固定文本,适合临时测试。Prompt Template 可以通过变量注入用户问题、知识库内容和节点输出,更适合应用化。边界是模板只提升组织方式,任务定义含糊时,变量再多也无法保证稳定。踩坑点是把所有上下文都塞进去,成本变高还会稀释重点。
示例越多效果越好吗?
不一定。分类、抽取任务放 2-4 个高质量示例很有帮助,开放问答示例太多会限制表达。示例还要覆盖正例、反例和边界,否则模型只学到表面格式。最常见的坑是示例允许猜测,但正式规则要求不能编造,模型会优先模仿示例。
如何减少 Dify 应用胡编?
先在提示词里明确“只依据资料回答”,再在检索为空时直接走兜底分支。不要把用户问题和知识库资料混在同一段里,要用变量标签区分来源。真正稳定的做法是流程控制加提示词约束,而不是只写一句“不要胡编”。边界是资料本身过旧或召回质量差时,Prompt 也救不了答案。
什么时候要拆成工作流?
当任务有多个步骤,且每步失败原因不同,就应该拆。比如先分类、再检索、再生成、再校验,比一个大 Prompt 更好排查。取舍是节点越多链路越长,延迟和维护成本也会上升。实际项目通常先做最短链路,再根据失败样本逐步拆分。