格子小说app
64.33MB · 2025-09-13
“幻觉”(Hallucination)指的是生成模型在缺乏足够依据时,生成看似合理但客观不正确或捏造的内容。典型表现:
一句话:“语言像人,但不保证像真。”
小图标氛围组:✨???
从“语言建模”的基本机制说起:
生成式模型的核心是“预测下一个词的分布”,本质是高维概率场上的采样过程。它擅长“统计上的相似”,而非“事实上的正确”。
类比:你问一个读遍古籍的文人“USB-C 2.1的最大功率是多少”,他会优雅地胡诌,因为书里没写过,但他要凑一段像样的答复。
提示:温度越高、Top-p越宽,探索度越大,幻觉概率上升;温度极低虽减少幻觉,但也会增加“模式坍缩”,出现机械复读。
识别小贴士:
下面给出自下而上的实战方案栈,每一层都有价值,堆叠效果更好。
强化策略:
减少“自由发挥”,让生成受控:
目标:RAG + 工具调用 + 结构化校验 + 回退策略。
说明:
// 基础工具:检索、校验、回退
const search = {
async query(q, k = 5) {
// 同时使用关键词检索与向量检索(伪)
const keywordHits = await kwSearch(q, k);
const vectorHits = await vecSearch(q, k);
return rerank([...keywordHits, ...vectorHits]).slice(0, k);
}
};
function buildContext(docs) {
// 将检索片段拼装,并附上可引用的来源标注
return docs.map((d, i) => `【S${i+1}】${d.snippet}n(来源: ${d.source})`).join("nn");
}
function validateJsonSchema(obj, schema) {
// 极简校验器:只校验字段存在与类型
for (const [k, t] of Object.entries(schema)) {
if (!(k in obj)) return { ok: false, reason: `缺少字段 ${k}` };
if (typeof obj[k] !== t) return { ok: false, reason: `字段 ${k} 类型应为 ${t}` };
}
return { ok: true };
}
async function hallucinationGuard(answer, sources) {
// 简单启发式:检查是否含有强断言但无引用
const strongClaims = [/始终|确定|绝对|官方已确认|唯一/i];
const hasStrong = strongClaims.some(r => r.test(answer));
const hasCite = /[Sd+]/.test(answer) || /【Sd+】/.test(answer);
if (hasStrong && !hasCite) {
return { ok: false, reason: "强断言缺少引用" };
}
// 可扩展:实体对齐、日期数值一致性检查等
return { ok: true };
}
// 主流程
async function answerQuestion(userQuestion) {
// 1) 检索
const docs = await search.query(userQuestion, 6);
const context = buildContext(docs);
// 2) 生成草稿(提示模型:引用来源、标注片段)
const draft = await model.generate({
system: "你是严谨的助手,若不确定请说明并请求澄清。",
prompt: [
"请基于给定资料回答问题,并用【S#】标注引用来源(尽量覆盖关键结论)。",
"若资料不足,请直说不足并提出需要的信息类型。",
"",
`用户问题:${userQuestion}`,
"",
`可用资料:n${context}`
].join("n")
});
// 3) 幻觉守门与回退
const guard = await hallucinationGuard(draft.text, docs);
if (!guard.ok) {
// 回退策略:降低温度 + 强制要求引用
const retry = await model.generate({
temperature: 0.2,
system: "你是严谨的助手,必须在关键结论处添加【S#】引用;若资料不足则拒答并说明不足。",
prompt: [
`重新回答,并在关键句后标注来源,问题:${userQuestion}`,
`资料:n${context}`
].join("n")
});
return retry.text;
}
// 4) 结构化摘要输出(便于前端或下游系统)
const schema = { finalAnswer: "string", citations: "object" };
const structured = await model.generate({
system: "请将答案压缩为结构化对象",
prompt: [
"生成 JSON:{ finalAnswer: string, citations: { [S#]: sourceUrl } }",
"确保所有引用的S#都在对象里映射到来源链接",
`原答案:n${draft.text}`,
`资料来源列表(编号->链接):n${docs.map((d,i)=>`S${i+1}: ${d.source}`).join("n")}`
].join("n"),
format: "json"
});
const obj = JSON.parse(structured.text);
const check = validateJsonSchema(obj, schema);
if (!check.ok) {
// 回退为纯文本安全版
return draft.text + "nn(提示:结构化失败,已回退为文本版本)";
}
return obj; // 下游可直接渲染
}
要点复盘:
可直接纳入你的系统提示或用户提示中:
建议构建三个维度的指标:
线上监控手段:
小图标收尾:????️?
下面是一个超简的输入输出组件逻辑,展示如何在前端提示引用和不确定性。无外部依赖,便于移植。
// 假设后端返回 { finalAnswer, citations } 或纯文本
function renderAnswer(payload) {
const root = document.getElementById("answer");
root.innerHTML = "";
if (typeof payload === "string") {
root.textContent = payload; // 回退文本
return;
}
const para = document.createElement("p");
para.textContent = payload.finalAnswer;
root.appendChild(para);
const citeTitle = document.createElement("div");
citeTitle.textContent = "来源:";
citeTitle.style.marginTop = "12px";
root.appendChild(citeTitle);
const ul = document.createElement("ul");
for (const [k, url] of Object.entries(payload.citations || {})) {
const li = document.createElement("li");
li.textContent = `${k} -> ${url}`;
ul.appendChild(li);
}
root.appendChild(ul);
}
愿你与模型的对话,不再是“你演我猜”,而是“你证我信”。
64.33MB · 2025-09-13
6G · 2025-09-13
174.31MB · 2025-09-13