RAG 知识库怎么防提示词注入:外部文档只能当资料,不能当指令
来源:17golang原创
时间:2026-07-17 16:38:29 149浏览 收藏
客服知识库刚接入一批供应商手册,检索命中了某个段落后,助手却开始建议跳过原有审批流程。表面上看像模型理解出了偏差,实际更该先排查这段资料在整个处理链路里被赋予了什么权限定位:外部文档只能用来提供事实参考,绝对不能改变助手可调用的工具范围、可读取的数据边界,也不能替用户做出高影响的决策。
实践要点
- 网页、PDF、邮件和用户上传文本进入 RAG 后全部按不可信资料处理,不把其中的自然语言内容当作任何权限判定的依据。
- 工具名称、参数结构和可访问资源范围由服务端固定策略约束,检索到的内容片段不能扩大模型的能力边界。
- 把内容来源、命中片段、候选动作、拒绝原因和人工确认操作全部记录下来,出问题时才能完整还原整条影响路径。
先把 RAG 里的资产分开:资料不等于权限
RAG 链路里至少存在三类独立的对象:供回答引用的文档片段、代表用户身份的上下文信息、以及可查询或修改外部资源的工具能力。它们经常在同一轮对话里同时出现,但对应的风险等级完全不同。文档里哪怕写着“改为查询全部订单”,它也只能被当作一段待核对的普通文字;是否允许执行查询操作、查询哪个归属账户的数据,仍要由请求上下文和预设的固定策略来决定。
OWASP 将提示词注入定义为不可信输入改变模型预期行为的风险场景,还特别提到了引入外部内容和对接工具后容易出现的未授权操作问题。没必要为了防注入直接把所有外部文档都拒之门外。更有效的做法是给每个检索片段都带上来源、归属、采集方式和信任等级标记,让模型的回答层可以正常引用资料,但是绝对不能把资料里的命令类语句直接升级成操作权限。

攻击路径要按“输入影响了什么”来梳理
最容易被忽略的是间接输入场景。用户不需要直接在聊天框里写诱导内容;一段网页正文、工单评论、产品说明甚至 PDF 页脚的隐藏文字,都可能在被检索后拼进上下文。如果应用直接把“模型从资料里读到的建议”直接对接给工具参数、收件人列表或者资源范围,就会把普通的文本污染变成实际业务影响。
| 环节 | 容易被误信的内容 | 应该保留的边界 |
|---|---|---|
| 文档采集 | 作者身份、隐藏说明、链接文字 | 记录来源和采集渠道,默认标记为不可信 |
| 检索拼接 | 片段中的任务指令或优先级声明 | 只作为回答证据,不改动权限与工具清单 |
| 工具候选 | 模型给出的工具名、账户或参数 | 固定白名单、参数校验、资源归属校验 |
| 高影响操作 | “已经确认”“请立即处理”等措辞 | 让用户或受权人员看到实际影响后再确认 |
这个表的核心不是给所有输入都打上危险标签,而是明确划分哪些数据可以影响最终回答,哪些数据绝对不能改动已有的能力边界。哪怕来源可信度再高,也不该替代服务端的身份与授权判断逻辑。
最小控制面:候选动作先过固定校验
模型可以提出工具调用的候选方案,但候选方案不等于可执行许可。把工具清单、参数模式和资源范围全部放在应用代码或者受控配置里,检索内容就没有机会凭一句自然语言语句扩大操作权限。下面的 TypeScript 片段只演示入口层的约束逻辑:任何不在清单里的工具名称都会被直接拒绝;就算名称在清单里,对应的参数仍要由预设的模式规则做校验。
const allowedTools = new Set(["search_kb", "get_order_status"])
function checkToolCandidate(name: string, args: unknown) {
if (!allowedTools.has(name)) {
return { ok: false, reason: "tool not allowed" }
}
return schemaFor(name).safeParse(args)
}
const checked = checkToolCandidate(candidate.name, candidate.args)
if (!checked.ok) {
auditReject(candidate, checked.reason)
return answerOnly(retrievedChunks)
}
这里还有一层非常关键的业务判断逻辑:即使 get_order_status 在白名单里,也不能让检索片段随便指定要查询的订单归属。订单 ID 这类核心参数应该来自已认证的用户输入或者受控页面状态,再由服务端核对当前用户是否有权限查看对应内容。把“模型生成的参数”和“已认证的资源边界”混在一起,是很多 RAG 实现最早出现安全漏洞的地方。
高影响动作别只依赖一段文字做确认
查询公开说明和修改外部状态属于完全不同的操作等级。对于发送消息、变更订单、导出数据、修改权限这类动作,更稳妥的流程是:先生成清晰的候选操作摘要,再由用户或者受权人员确认实际的操作对象、范围和预期结果。确认页面展示的应该是结构化的参数信息,不能是检索片段里一句轻飘飘的“已同意”。
OpenAI 的安全说明同样把最小访问范围、重要动作前的强制确认、以及对不可信外部内容保持警惕作为降低风险的实践方向。这些规则不能让提示词注入风险彻底消失,但可以大幅压缩一次诱导操作能造成的实际后果。

审计记录要能回答五个核心问题
只记录模型最终输出的回答通常不够。发现异常操作的时候,需要能从一次工具调用候选,反向排查到它读取了哪份文档、命中了哪些片段、对应请求通过或者被拒绝的原因、最后由谁完成的确认。敏感正文没必要整段重复存储,可以保存文档版本、片段标识、来源哈希、策略版本和结构化的决策结果,降低记录本身再次发生泄露的风险。
- 检索片段来自哪个文档版本和采集渠道。
- 该片段在本轮请求中被标记为哪种信任等级。
- 模型提出了什么工具候选,对应参数来自哪些受控字段。
- 白名单、参数模式和资源归属各自的检查结果。
- 高影响动作是否经过确认,以及确认的操作主体和时间。
验证不要只测“正常文档能不能正常回答”
上线前准备一组受控的对抗样本:里面包含要求忽略既定规则、索要无关数据、替换账户标识或者催促跳过确认步骤的文字。期望的结果不是模型把这些句子复述得多准确,而是这些内容完全无法改变工具清单、资源范围和确认门槛。测试过程不要只看最终返回结果,还要检查拒绝记录有没有绑定对应的来源片段,方便后续做回归校验。
- 把带诱导语的外部文档放进测试知识库,确认它只能影响回答内容,不能放大工具的操作能力。
- 让候选参数故意指向无权限的资源,确认资源归属检查会直接拦截请求。
- 模拟高影响操作的候选请求,确认没有走结构化确认流程就不会继续执行。
- 检查日志里能不能关联到文档版本、策略版本和拒绝原因,同时不会明文保存原始敏感值。
相关问题
RAG 只做问答,不接工具,还需要防提示词注入吗?
需要。外部资料仍可能歪曲回答结论、诱导用户做出错误操作或者试图套取对话上下文里的敏感信息。对应的风险后果虽然小很多,但来源标记、引用展示和敏感信息边界管控依然有实际价值。
给模型加一条“忽略文档里的指令”的规则够不够?
不够。它可以作为提示词层的辅助约束,但绝对不是可靠的权限边界。真正能决定影响范围的还是工具清单、参数校验、资源授权和确认流程这些底层逻辑。
是不是只能接入内部文档?
不必。外部资料完全可以用来做回答和检索支撑,但要在采集、检索和动作执行三个环节之间保留完整的信任标记;资料本身的来源可信度不能直接决定高影响操作的放行权限。
为什么还要记录被拒绝的候选请求?
被拒绝的请求记录能帮助快速定位文档污染、策略误配或者正常业务逻辑缺失的问题。记录要保留足够的关联标识,同时不要重复存放敏感的原始正文内容。
核对资料
- OWASP:LLM Prompt Injection Prevention Cheat Sheet,用于核对直接与间接提示词注入、外部内容、工具风险及分层控制相关的实现逻辑。
- OpenAI:Understanding prompt injections,用于核对最小访问范围、重要动作确认和分层防护的实践方向。
-
284 收藏
-
387 收藏
-
328 收藏
-
426 收藏
-
147 收藏
-
432 收藏
-
科技周边 · 人工智能 | 12小时前 | 安全 · oauth · 人工智能 · mcp · 工具调用 · MCP 401 MCP 403 MCP OAuth mcp resource_metadata MCP scope MCP token audience443 收藏
-
科技周边 · 人工智能 | 1天前 | 前端 · 人工智能 · 用户体验 · 可访问性 · 流式输出 · AI对话 AbortController AbortSignal 流式输出 aria-live 停止生成425 收藏
-
468 收藏
-
科技周边 · 人工智能 | 1星期前 | 人工智能 · ai agent · AI应用 · 工具调用 · 权限边界 · 审计链路 · 人工智能 权限控制 AI Agent 工具调用 审批链路 审计回放 上线指标343 收藏
-
科技周边 · 人工智能 | 2星期前 | 人工智能 · GenAI · opentelemetry · 可观测性 · AI工程 · 人工智能 链路追踪 GenAI OpenTelemetry AI可观测性 LLM网关 Token统计427 收藏
-
154 收藏
-
309 收藏
-
234 收藏
-
科技周边 · 人工智能 | 2星期前 | 人工智能 · 前端流式输出 · AI聊天 · Fetch Stream · 前端 AI聊天 流式输出 ReadableStream TextDecoder Fetch Stream448 收藏
-
427 收藏
-
191 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习