介绍如何用 Node.js 和向量数据库验证 LLM 输出的可靠性,防止模型幻觉问题。对需要保证 LLM 应用质量的开发者有参考价值。
你花费数周打磨提示词。你已经建立了一个强大的检索系统。你验证进入上下文窗口的每一条数据。
尽管如此,你的 RAG(检索增强生成)机器人仍然自信地告诉用户完全错误的信息。
这不经常发生,但当它发生时,会摧毁用户的信任。生产环境中 LLM 的问题不仅仅是让它们回答问题;而是知道它们何时在撒谎(幻觉)。
标准的软件工程实践,如基于正则表达式的单元测试,不适用于非确定性的自然语言输出。我们需要在技术栈中添加一个新层。
以下是我使用 TypeScript、Node.js 和带有 pgvector 的 PostgreSQL 构建"胡言检测器"中间件的方式。
典型的 RAG 流程如下所示:
问题在于这个流程。我们隐性地信任了模型。
要捕捉幻觉,我们需要在生成之后但用户看到之前引入一个对抗步骤。我们需要一个充当不懈事实检查者的中间件。
由于我们已经有了"源真理"(我们在第 2 步检索的文档)和生成的"声明"(LLM 的答案),我们可以数学上衡量它们的对齐程度。
如果 LLM 的答案在语义上远离它应该使用的源文档,那么它可能在胡言乱语。
我为这个中间件选择的技术栈:
运行时:Node.js(轻量级、I/O 快速)。
语言:TypeScript(用于数据结构的类型安全)。
向量数据库:带有 pgvector 扩展的 PostgreSQL。
我选择 pgvector 是因为将操作数据和向量保留在同一数据库中,相比管理单独的 Pinecone 或 Weaviate 实例来进行这个验证步骤,大大简化了架构。
目标不是重新运行整个 RAG 流程。目标是获取最终输出并验证其"基础"。
下面是评估逻辑的简化 TypeScript 视图。我们使用嵌入模型将生成的答案和源文本都转换为向量,然后计算余弦相似度。
import { embedText, cosineSimilarity } from './vectorUtils';
interface AuditRequest {
llmAnswer: string;
retrievedContext: string[]; // The raw text chunks passed to the LLM
threshold: number; // e.g., 0.75
}
export async function validateResponse(req: AuditRequest) {
// 1. Vectorize the "Claim" (the LLM's answer)
const answerVector = await embedText(req.llmAnswer);
let totalSimilarityScore = 0;
// 2. Compare the claim against every piece of context used
for (const sourceText of req.retrievedContext) {
// Vectorize the source truth
const sourceVector = await embedText(sourceText);
// Calculate semantic overlap (1.0 = identical meaning, 0.0 = unrelated)
const similarity = cosineSimilarity(answerVector, sourceVector);
totalSimilarityScore += similarity;
}
// 3. Calculate an average "Trust Score"
// (In production, we use weighted averages based on relevance)
const averageTrustScore = totalSimilarityScore / req.retrievedContext.length;
// 4. Make a Pass/Fail decision
if (averageTrustScore < req.threshold) {
return {
action: "REJECT",
score: averageTrustScore,
reason: "The generated response does not align semantically with the provided source context."
};
}
return {
action: "PASS",
score: averageTrustScore
};
}
要使其在实际应用中有用,中间件不能只返回 true/false。前端需要知道为什么某些内容被标记了。
如果系统检测到幻觉,它会生成一个详细的 JSON 对象,可以记录给工程师或用于在 UI 中显示警告。
{
"id": "audit_123xyz",
"timestamp": "2023-10-27T10:00:00Z",
"trust_score": 0.42,
"action": "REJECT",
"audit_details": {
"reason": "Critical hallucination detected. Answer claims X, but source documents contain Y.",
"contradictions": [
{
"claim": "Product supports XML export",
"source_truth": "Export formats supported: JSON, CSV only."
}
]
}
}
输入验证至关重要,但对于生产级 AI Agent,输出验证是强制性的。你不能仅依靠提示词工程来防止幻觉。
通过将 LLM 视为不受信任的组件,并使用 Node.js 和 pgvector 等工具包装语义验证层,我们可以构建真正有效的防护栏。
我将这套逻辑打包成一个独立的中间件工具,称为 AgentAudit。它旨在集成到现有的 Node/TS 后端中,立即开始捕捉谎言。
我很想听听你如何处理这个问题。你是手动审查日志,还是有自动检查到位?
你可以在这里查看交互式演示:https://agentaudit-dashboard.vercel.app/
如需进一步采取行动,你可以考虑阻止此人和/或报告滥用。