#同一个问题每次都有不同的答案:温度、系统提示、搜索稳定性调整
简介
“我问同样的问题,但每次都得到不同的答案”——这是在企业环境中运行 Dify 的团队最常见的抱怨之一。从用户的角度来看,这个问题似乎是一个“不稳定的系统”,但实际上并不意味着系统坏了,而是表明LLM的输出控制设计不当。
在本文中,我们分析了导致答案差异的三个层面(LLM 参数、提示结构和搜索稳定性),并解释了实现稳定、企业质量输出的具体技术。
症状
| 症状 | 示例 |
|---|---|
| 事实是一样的,但每次的表述却不同 | “带薪休假每年20天”和“每年授予的带薪休假天数为20天” |
| 答案的结构和顺序发生变化 | 项目符号的顺序发生变化 |
| 同一个问题引用了不同的信息 | 因为每次搜索结果都会改变,所以引用了不同的chunk |
| 答案长度差异很大 | 同样的问题返回 3 行答案和 15 行答案 |
| 很少会返回矛盾的答案 | “可能”与“不可能”混杂 |
原因分析
答案的差异不是单一原因造成的,而是三层因素共同作用的结果。
flowchart TD
A[回答の不一致] --> B[レイヤー1: LLMパラメータ]
A --> C[レイヤー2: プロンプト構造]
A --> D[レイヤー3: 検索の安定性]
B --> B1[Temperature が高い]
B --> B2[Top-P が高い]
B --> B3[Presence/Frequency Penalty]
C --> C1[役割定義が曖昧]
C --> C2[出力形式が未指定]
C --> C3[判断基準が不明確]
D --> D1[検索結果が毎回異なる]
D --> D2[Top-K が大きすぎる]
D --> D3[Rerank スコアの揺れ]
第 1 层:LLM 参数的影响
温度(最重要)
温度是控制 LLM 输出中概率分布“平坦度”的参数。
| 温度值 | 行为 | 适用场景 |
|---|---|---|
| 0.0 | 0.0近确定性输出(始终选择最可能的标记) | 分类、数据提取、代码生成 |
| 0.1~0.3 | 轻微变化,同时保持高稳定性 | 常见问题解答、手册参考、合同检查 |
| 0.4~0.7 | 适度变化 | 一般写作、电子邮件起草 |
| 0.8~1.0 | 高创造力 | 头脑风暴、文案写作 |
| 超过1.0 | 非常不同(不可预测) | 通常不使用 |
重要:设置温度 = 0.0 并不能保证输出完全相同。由于LLM提供商的基础设施中浮点运算和批处理的差异,可能会出现轻微的波动。
Top-P(核采样)
Top-P 只考虑累积概率达到指定值的 token 候选者。当与温度结合使用时,这两个参数都会影响输出多样性。
# 安定性を最大化する設定例
llm_settings:
temperature: 0.1
top_p: 0.9 # 1.0に近いほど制約が少ない
max_tokens: 2048
presence_penalty: 0.0
frequency_penalty: 0.0
配置 Dify LLM 节点
Dify 的 LLM 节点允许为每个节点单独配置这些参数。
# Workflow LLM ノードの設定
llm_node:
model: gpt-4o
temperature: 0.1 # 安定性重視
top_p: 0.95
max_tokens: 1024
system_prompt: |
あなたは社内規定に基づいて回答するアシスタントです。
...
第 2 层:提示结构的影响
仅降低温度并不能保证稳定性。如果提示的结构不明确,模型在决定如何回答时具有很高的自由度,并且每次都会使用不同的方法进行响应。
不稳定提示示例:
あなたは社内のヘルプデスクです。
ユーザーの質問に丁寧に答えてください。
在此提示符下,以下内容未定义:
- 答案的格式(项目符号或段落)
- 信息来源的优先级(知识库信息或一般知识)
- 大约答案长度
- 未找到信息时的行为
- 是否允许猜测或完成。
稳定提示示例:
あなたは株式会社ABCの社内ITヘルプデスクアシスタントです。
## 回答ルール
1. 回答は必ず「結論」「詳細」「参考情報」の3セクションで構成すること
2. 回答の根拠は、提供されたコンテキスト情報のみに基づくこと
3. コンテキストに該当する情報がない場合は「この質問についての情報は
現在のナレッジベースに含まれていません。IT部門(内線: 1234)に
お問い合わせください」と回答すること
4. 推測や一般的な知識に基づく補完は行わないこと
5. 回答は200文字以内に収めること
## 出力フォーマット
### 結論
[1〜2文で端的に回答]
### 詳細
[必要に応じて箇条書きで補足]
### 参考情報
[参照したドキュメント名を記載]
第 3 层:搜索稳定性
使用知识库时,如果每次为同一问题搜索不同的块,则传递给 LLM 的上下文会发生变化,结果答案也会有所不同。
搜索结果不稳定的原因:
| 原因 | 机制 |
|---|---|
| 向量搜索的近似 | ANN(近似最近邻)算法并不能保证完美的再现性 |
| Top-K 太大 | 边界附近的块可能会被替换 |
| 有许多具有相似分数的块 | 分数差异较小导致排名变化 |
| 搜索多个知识库 | 不同知识库结果的合并顺序不稳定 |
解决方案
步骤 1:适当设置温度
每种场景的推荐设置:
| 应用 | 温度 | 顶P | 原因 |
|---|---|---|---|
| 内部常见问题 | 0.0~0.1 | 0.9 | 0.9事实准确传达是重中之重 |
| 合同审查 | 0.0 | 0.0 0.9 | 0.9法律风险要求的一致性 |
| 技术文档解答 | 0.1~0.2 | 0.95 | 0.95准确性与自然性之间的平衡 |
| 电子邮件起草 | 0.3-0.5 | 0.95 | 0.95表达方式的适当变化 |
| 创意产生 | 0.7~0.9 | 0.95 | 0.95需要多样化的想法 |
第 2 步:将结构约束纳入提示中
强制结构化输出:
## System Prompt
以下のフォーマットに従って回答してください。
フォーマットから逸脱しないでください。
回答フォーマット:
---
【判定】: [該当 / 非該当 / 判定不能]
【根拠】: [コンテキストから引用した該当箇所]
【補足】: [必要な場合のみ、1〜2文で補足]
---
强制 JSON 输出(在工作流节点之间传递数据):
以下のJSON形式で出力してください。JSON以外のテキストは出力しないでください。
{
"category": "技術質問 | 手続き質問 | クレーム | その他",
"confidence": 0.0〜1.0,
"answer": "回答テキスト",
"source": "参照したドキュメント名"
}
步骤 3:确保搜索稳定性
# 安定性重視のナレッジベース検索設定
knowledge_retrieval:
retrieval_mode: hybrid
top_k: 3 # 小さめに設定して境界の揺れを抑制
score_threshold: 0.6 # 高めに設定して低スコアの不安定チャンクを除外
reranking:
enabled: true
model: rerank-multilingual-v3.0
提高搜索稳定性的要点:
- 减少Top-K:如果Top-K=3,前三名的结果会比较稳定。如果设置Top-K=10,底部的替换会更加激烈。
- 将分数阈值设置得较高:分数较低的区块更容易因分数波动而导致排名波动。
- 启用Rerank:Rerank模型在一致的基础上重新评分,提高结果的稳定性。
- 在单个知识库中搜索:合并多个知识库会增加结果的稳定性
步骤 4:通过输出后处理增强稳定性
在 LLM 输出中添加后处理可以吸收表面波动。
flowchart LR
A[ユーザー質問] --> B[ナレッジ検索]
B --> C[LLM生成]
C --> D[フォーマット検証ノード]
D -->|OK| E[回答返却]
D -->|NG| F[フォーマット修正ノード]
F --> E
使用代码节点进行格式验证的示例:
import json
def main(text: str) -> dict:
"""LLM出力が指定フォーマットに準拠しているか検証する"""
try:
result = json.loads(text)
required_keys = ["category", "confidence", "answer", "source"]
for key in required_keys:
if key not in result:
return {
"valid": False,
"error": f"必須キー '{key}' が欠落しています",
"original": text
}
if result["confidence"] < 0 or result["confidence"] > 1:
return {
"valid": False,
"error": "confidence の値が範囲外です",
"original": text
}
return {"valid": True, "data": result}
except json.JSONDecodeError:
return {
"valid": False,
"error": "JSON パース失敗",
"original": text
}
步骤 5:利用种子值(适用于支持的模型)
一些 LLM 提供商支持 seed 参数,该参数允许您指定相同的种子以提高输出的可重复性。
# OpenAI API の seed パラメータ(対応モデルの場合)
llm_settings:
model: gpt-4o
temperature: 0.0
seed: 42 # 固定シード値
注意:种子参数“增加”输出的再现性,但不“保证”完整的同一性。此外,如果无法直接从 Dify 节点设置屏幕设置种子,则需要通过 API 进行自定义设置。
注意事项
1.应用设计的参数设计文档
构建新的 Dify 应用程序时,请提前决定以下事项:
| 项目 | 决定 | 示例 |
|---|---|---|
| 温度 | 价值取决于用途 | 常见问题解答:0.1,草稿:0.5 |
| 输出格式 | 固定模板 | JSON/3 节结构 |
| 答案长度 | 上限和下限 | 100-300 个字符 |
| 缺乏信息时的行为 | 固定短语 | “暂无信息” |
| 猜测的可能性 | 允许/禁止 | 不允许 |
2. 执行回归测试
定期询问同一组问题并检查答案的一致性。
import hashlib
def test_consistency(api_client, query: str, runs: int = 5):
"""同じ質問を複数回実行し、回答の一貫性を確認する"""
answers = [api_client.chat(query=query)["answer"] for _ in range(runs)]
hashes = [hashlib.md5(a.encode()).hexdigest() for a in answers]
unique = len(set(hashes))
rate = 1 - (unique - 1) / runs
return {"query": query, "unique_answers": unique, "consistency_rate": rate}
for q in ["有給休暇の申請方法は", "経費精算の締め日はいつ", "VPN接続できない場合の対処法"]:
r = test_consistency(client, q)
print(f"[{'OK' if r['consistency_rate']>=0.8 else 'WARN'}] {q}: {r['consistency_rate']:.0%}")
3.稳定性检查表
- 温度设置是否符合目的?
- 是否在系统提示符下指定输出格式?
- 行为是否定义为“如果没有信息”?
- 提示中是否明确说明是否可以猜测或补全?
- 知识库搜索中的Top-K 是否是最低限度的必要条件?
- 分数阈值设置得足够高吗?
- 是否启用重新排名?
- 是否有定期回归测试的机制?
总结
当出现差异时,仅关注温度是不够的。要实现真正的企业品质、稳定输出,必须统筹设计以下三层:
- LLM参数层:根据目的设置Temperature,抑制不必要的发散
- 提示结构层:显式定义输出格式、判断标准、拒绝条件,限制模型自由度。
- 搜索稳定层:关注Top-K,设置更高的分数阈值,并通过Rerank持续重新评分。
在这三层中,改进提示结构往往是最有效的。如果降低温度不能解决问题,我们建议首先检查提示的结构。
参考资料
-LLM ノード | Dify Docs(日本語) -Dify x Claude でつくる2分週報 AI -現場で使える!Dify x Python ハイブリッド開発実践