你花了好几周时间打磨你的提示。你建立了一个强大的检索系统。你验证了进入上下文窗口的每一条数据。
然而,你的RAG(检索增强生成)机器人仍然自信地告诉用户完全错误的信息。
这种情况不常发生,但一旦发生,就会破坏用户信任。生产环境中的大型语言模型问题不仅是让他们回答;而是知道他们什么时候在撒谎(产生幻觉)。
标准的软件工程实践,比如基于正则表达式的单元测试,无法处理非确定性自然语言输出。我们需要在技术栈中增加一层新内容。
以下是我如何利用TypeScript、Node.js和PostgreSQL构建一个“废话检测器”中间件的方法。pgvector
架构问题
典型的RAG流程如下:
- 用户提问。
- 应用检索相关的上下文文档。
- LLM会根据上下文生成答案。
- 用户能看到答案(即使答案是错误的)。
问题在于第四步。我们完全信任模型。
要捕捉幻觉,我们需要在用户看到之前,在世代之后引入对抗性的步骤。我们需要一个中间件,充当无情的事实核查者。
解决方案:语义接近性检查
由于我们已经有了“来源真理”(我们在第二步检索到的文件)和生成的“主张”(LLM的答案),我们可以用数学方式衡量它们的高度匹配程度。
如果LLM的回答语义上与它本应使用的源文档相去甚远,那很可能是在胡扯。
我为这个中间件准备的堆栈:
- 运行时间:Node.js(轻量化,I/O快速)。
- 语言: TypeScript(用于数据结构的类型安全)。
- 向量数据库:带有扩展的PostgreSQL。
pgvector
我选择是因为将作数据和向量放在同一个数据库中,相比仅管理一个独立的Pinecone或Weaviate实例来验证,架构简化了极大。pgvector
核心逻辑
目标不是重新运行整个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对象,供工程师记录或在界面中显示警告。
{
"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代理来说,输出验证是强制性的。你不能仅依赖迅速工程来预防幻觉。
通过将LLM视为不可信组件,并用Node.js和pgvector等工具包裹语义验证层,我们可以构建真正有效的护栏。
我把这个逻辑打包到一个叫AgentAudit的独立中间件工具里。它的设计目的是直接插入现有的Node/TS后端,立即开始识别谎言。
我很想听听你们是怎么处理这个问题的。你是手动审核日志,还是有自动检查?


文章评论