1 · 你在哪里会用到它
ChatGPT 官方支持上传文件进行分析、总结和提取。可用一份不敏感的政策文档,询问退款期限并要求提供依据段落。本教程实现小型词项检索组件,不声称这是 ChatGPT 内部文件处理架构。
官方产品/API 文档 ↗来源核对日期 2026-10-25。产品行为来自官方公开说明,下方代码是独立教学实现。
2 · 关键工程决策
实际问题是来源可追溯:回答流畅但无法找到依据仍不够。我们按空行分段、保留段落 ID、按查询词重叠评分并返回原文。没有命中就弃答。分数是词项重叠,不是置信度、真实性或语义相关性。先用这个简单基线暴露失败,再引入 embedding 或 LLM。
- 检查查询词 refund 与 deadline。
- P1 包含 refund,重叠分数为 1/2 = 0.5;P2、P3 为零。
- 原样返回 P1 和 ID,不编造综合回答。
- 将问题改为 reimbursement window:虽然语义相关,基线仍弃答,由此理解语义检索的价值。
3 · 运行并修改输入
完全在浏览器运行,无模型调用、网络请求、API Key 或上传。输入为 JSON,这是确定性组件演示,不是生成式助手。
{
"status": "evidence_found",
"evidence": [
{
"id": "P1",
"text": "Refund policy: request a refund within 30 days.",
"matches": [
"refund"
],
"score": 0.5
}
],
"extract": "[P1] Refund policy: request a refund within 30 days."
}初始输出是构建时实际计算的示例结果。修改后点击运行以计算你的结果。
4 · 完整源代码
需要现代浏览器或 Node.js 18+。下载模块,将下方 runner 存为同目录 demo.mjs,执行 node demo.mjs,无需 npm 依赖。
下载源代码 ↓// Local lexical retrieval baseline. No LLM, embeddings, PDF parser or network.
export const example = {
query: 'refund deadline',
document: 'Refund policy: request a refund within 30 days.\n\nShipping policy: delivery takes 5 days.\n\nSupport policy: contact support for damaged items.'
};
const terms = text => new Set(text.toLowerCase().match(/[\p{L}\p{N}]+/gu) || []);
export function run({query, document}) {
if (typeof query !== 'string' || typeof document !== 'string') throw Error('query and document must be strings');
if (document.length > 20000 || query.length > 500) throw Error('Input limit exceeded');
const q = terms(query);
const evidence = document.split(/\n\s*\n/).map((text, index) => {
const tokens = terms(text);
const matches = [...q].filter(term => tokens.has(term));
return {id: `P${index + 1}`, text, matches, score: matches.length / Math.max(1, q.size)};
}).filter(item => item.score > 0)
.sort((a, b) => b.score - a.score || a.id.localeCompare(b.id)).slice(0, 2);
return {
status: evidence.length ? 'evidence_found' : 'abstain',
evidence,
// Evidence quotes, not a generated or semantically verified answer.
extract: evidence.map(item => `[${item.id}] ${item.text}`).join('\n')
};
}
import {run, example} from './document-evidence.mjs';
console.log(JSON.stringify(run(example), null, 2));5 · 失败案例与生产差距
关键词命中可能无关或互相矛盾。段落 ID 仅在当前输入中稳定,生产引用需文档版本与偏移。按词边界处理对未分词中文较弱。演示只接收纯文本,不解析 PDF 或 OCR。文档里的指令应视为数据,不能升级成后续生成阶段的系统指令。
6 · 你的实现练习
加入一个相关同义改写和一个堆关键词的干扰段。在人工标注题集上测 recall@2,再增加版本化引用与句子级切分,每次只改变一个组件。
交付修改后的代码、至少一个成功与一个失败案例,并解释测试不能证明什么。
继续学习关联知识点 →