ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

LLM Zoomcamp RAG 提示词构建指南:从检索结果到可落地的 Instructions 与 User Prompt

LLM Zoomcamp RAG 提示词构建指南:从检索结果到可落地的 Instructions 与 User Prompt LLM Zoomcamp RAG 提示词构建指南从检索结果到可落地的 Instructions 与 User Prompt【免费下载链接】llm-zoomcampLLM Zoomcamp - a free online course about real-life applications of LLMs. In 10 weeks you will learn how to build an AI system that answers questions about your knowledge base. Register here 项目地址: https://gitcode.com/GitHub_Trending/ll/llm-zoomcamp导读本文是 LLM Zoomcamp2026 届模块 1「Agentic RAG」第 6 课《Building the Prompt》的技术详解。检索Search负责把知识库中最相关的文档找出来但 LLM 并不会自动看见这些文档——只有当检索结果与用户问题被正确地组装进提示词Prompt后LLM 才能生成基于事实的答案。读完本文你将掌握为什么要把提示词拆成固定不变的 Instructions 与每次变化的 User Prompt 两部分、如何用build_context把检索结果格式化成 LLM 易读的文本块、如何用模板把问题与上下文组合成最终请求以及这些代码在仓库 rag_helper.py 中如何被封装为可复用的类方法。为什么必须构建提示词LLM 看不到你的文档在前一课 Search 中我们用 minsearch 建立了索引并检索出了 5 条最相关的 FAQ 条目得到了形如[{section: ..., question: ..., answer: ...}]的字典列表。但这里有一个关键事实LLM 是一个无状态的黑盒——它不知道你检索到了什么除非你把内容写进发给它的文本里。正如课程 What is RAG 中所演示的直接把学生问题I just discovered the course. Can I join now?丢给模型它只会给出你可以通常加入、请查看课程官网这类泛泛而谈的回答因为它不了解 Zoomcamp 具体的报名与证书政策。RAG 的整个思路就是在提问时把相关知识库文档检索出来与问题一起放进提示词交给 LLM。提示词就是检索Search与生成Generation之间的桥梁。因此构建提示词需要解决两件事把用户的问题放进去把检索回来的文档放进去并格式化成 LLM 容易理解的结构。Prompt 的两段式结构Instructions 与 User Prompt当我们构建 AI 系统时通常把提示词拆成两部分组成部分别名内容变化频率Instructions系统提示system prompt告诉 LLM 扮演什么角色、如何作答固定不变每个请求都一样User prompt用户提示承载实际问题与检索到的上下文每次请求都不同拆分的理由很朴素Instructions 是固定的User prompt 是变化的。分开存放让固定部分易于复用写一次、处处生效而变化部分则可以在每次请求时重新构建。这样既避免了重复维护也让调试时能一眼看出规则与数据的边界。这个设计在后续课程中进一步落地为两个独立的文件ingest.py 负责数据加载与索引构建rag_helper.py 负责 RAG 逻辑搜索、提示词、LLM 调用详见 RAG Helper。Instructions告诉 LLM 它的角色与边界课程给出了如下 Instructions 模板INSTRUCTIONS Your task is to answer questions from the course participants based on the provided context. Use the context to find relevant information and provide accurate answers. If the answer is not found in the context, respond with I dont know. 这段提示做了三件事定义角色你是回答课程学员问题的助手而不是一个万能的百科定义信息源答案必须基于提供的 context 得出定义失败行为如果 context 中没有答案就如实回复 I dont know.而不是编造。最后一条至关重要——它正是把答案锚定在我们的数据上、降低幻觉hallucination的关键约束。这也是对 What is RAG 中朴素 RAG示例的正式化当时我们手工把 FAQ 内容粘贴进 prompt现在 Instructions 把这一行为规范成了可复用的固定规则。仓库 rag_helper.py 中的INSTRUCTIONS与课程模板完全一致并作为RAGBase构造函数的默认参数使用。User Prompt 模板为问题与上下文留出占位符User prompt 部分使用模板字符串用占位符接收每次请求都会变化的内容USER_PROMPT_TEMPLATE Question: {question} Context: {context} 模板本身只是一个空壳{question}和{context}两个占位符会在运行时被填充。注意观察它与 Instructions 的差异这里没有任何行为规则只有数据布局——问题在上、上下文在下。值得一提的是仓库 rag_helper.py 中最终使用的PROMPT_TEMPLATE在措辞上略有演进大写QUESTION:与CONTEXT:标签并用.strip()去掉首尾空白但结构完全一致。这恰好说明提示词模板本身就是一个可以随意实验、按需调整的参数课程把它的默认值固化在代码里同时允许通过构造函数覆盖。构建 Context把检索结果格式化成文本检索返回的是字典列表而 LLM 只接受字符串。build_context就是二者之间的序列化器def build_context(search_results): lines [] for doc in search_results: lines.append(doc[section]) lines.append(Q: doc[question]) lines.append(A: doc[answer]) lines.append() return \n.join(lines).strip()对每一条 FAQ 文档它输出一个由三行组成的块第一行所属 section如 General Course-Related Questions起到分组标题的作用Q:前缀的问题A:前缀的答案末尾追加一个空行作为块与块之间的视觉分隔。最后用\n.join(lines)把所有行拼成一个字符串再.strip()去掉首尾多余空白。这一步虽然简单却是 RAG 管线中不可省略的预处理它把结构化的列表数据转换成了 LLM 最易读的分块 标签线性文本。上下文格式的好坏直接影响 LLM 能否快速定位到答案。课程配套截图见文首展示了build_context的典型输出每个 FAQ 块以 section 开头接着是Q:/A:成对的问题与答案多块之间以空行分隔排版清晰。在 rag_helper.py 中同样的逻辑被封装为RAGBase.build_context方法逐行实现与这里完全一致。构建完整 Prompt问题与上下文的组装有了模板和上下文build_prompt只需把两者填进占位符def build_prompt(question, search_results): context build_context(search_results) prompt USER_PROMPT_TEMPLATE.format( questionquestion, contextcontext ) return prompt.strip()流程是先调用build_context得到格式化后的上下文字符串再用str.format分别填充模板中的{question}与{context}最后.strip()去掉可能的前后空白。返回的就是将直接发送给 LLM 的完整 User prompt。在 rag_helper.py 中RAGBase.build_prompt(query, search_results)的封装如出一辙唯一区别是它使用实例属性self.prompt_template从而允许为不同场景替换模板。运行验证打印出来的 Prompt 长什么样在 notebook 中调用prompt build_prompt(question, search_results) print(prompt)你应该看到问题在最上方、若干条 FAQ 条目紧随其后的完整提示词大致如下Question: I just discovered the course. Can I join now? Context: General Course-Related Questions Q: I just discovered the course. Can I still join? A: Yes, but if you want to receive a certificate, you need to submit your project while were still accepting submissions. General Course-Related Questions Q: Course: I have registered for the LLM Zoomcamp. When can I expect to receive the confirmation email? A: You dont need it. Youre accepted. You can also just start learning and submitting homework... ...这就是我们最终发送给 LLM 的内容。注意两个细节问题来自用户每次请求都不同上下文来自上一课的搜索步骤默认num_results5并带boost_dict{question: 2.0, section: 0.5}与filter_dict{course: llm-zoomcamp}的检索配置参见 05-search.md而 FAQ 条目的question/answer/section字段结构来自 04-dataset.md 中抓取的 DataTalks.Club FAQ 数据。这里省略了结尾的Answer:提示。正如 03-rag.md 中提到的早期 GPT-3 这类模型需要这种补全提示来引导输出而现代模型已经不需要这个提示拐杖。消息历史Instructions 与 User prompt 的正式分离build_prompt组装出的是 User prompt 部分。但在真正调用 LLM 时课程 The LLM 展示了更规范的做法把整个请求组织成消息列表message history让固定指令与变化内容在角色层面就分开message_history [ {role: developer, content: INSTRUCTIONS}, {role: user, content: prompt} ] response openai_client.responses.create( modelgpt-5.4-mini, inputmessage_history )developer角色承载固定的 Instructions系统级行为规则user角色承载每次变化的 User prompt问题 上下文。OpenAI 同时接受developer与system作为指令角色课程统一使用developer。这样设计的好处是即使提示词文本在物理上被拆成两块它们在同一个请求中始终一起被发送LLM 依然能看到完整的指令 数据。从函数到类仓库源码中的最终形态课程中的独立函数build_context、build_prompt在 rag_helper.py 中被整合进RAGBase类。类方法与独立函数一一对应并且把index、llm_client、instructions、prompt_template、course、model全部变成构造参数——这样任何 indexminsearch、sqlitesearch和任何兼容 OpenAI 接口的客户端都可以即插即用class RAGBase: def __init__( self, index, llm_client, instructionsINSTRUCTIONS, prompt_templatePROMPT_TEMPLATE, coursellm-zoomcamp, modelgpt-5.4-mini ): ...其中llm方法把本课的提示词构建与角色分离整合成一次完整调用rag_helper.pydef llm(self, prompt): input_messages [ {role: developer, content: self.instructions}, {role: user, content: prompt} ] response self.llm_client.responses.create( modelself.model, inputinput_messages ) return response.output_text而rag方法则把search→build_prompt→llm三步串成完整管线rag_helper.py。从本课的手工组装提示词到这里的类方法封装演进脉络非常清晰先理解每一行代码在做什么再把它们沉淀成可复用组件。自定义 Instructions按需覆盖默认规则由于instructions是构造参数覆盖它就能改变模型行为而不必改动任何管线代码。课程 RAG Helper 给出了一例custom_instructions Youre a course teaching assistant. Answer the QUESTION based on the CONTEXT from the FAQ database. Use only the facts from the CONTEXT when answering the QUESTION. .strip() assistant RAGBase( indexindex, llm_clientopenai_client, instructionscustom_instructions, )你可以自由实验更强的约束只能引用 CONTEXT 中的事实、更具体的输出格式先给结论再给依据、或针对不同课程定制角色。提示词工程一半是艺术、一半是科学——你需要不断尝试不同的措辞、结构、字段标签观察输出变化。Prompt 质量与幻觉的关系本课结尾给出了一个值得记住的论断The prompt is the bridge between search and the LLM. A bad prompt lets the LLM ignore the context and hallucinate. A good prompt keeps the answer grounded.即坏提示词上下文没有被清晰标记、指令含糊、未定义不知道的行为LLM 就会忽略上下文去编造好提示词用Question:/Context:明确分隔数据、用 Instructions 约束信息源、用 I dont know. 兜底答案就会被牢牢锚定在检索结果上。同时要诚实看待提示词工程的局限性本课的模板是一个良好的起点而不是终点。正如课程后续 Evaluation 模块所强调的判断一个提示词好坏最终要靠评估指标如命中率、MRR、LLM-as-judge来度量而不是靠感觉猜测。到那个阶段你就能量化调整提示词到底带来了多少收益。小结与下一步回顾本课构建的完整提示词组装链路INSTRUCTIONS固定不变的角色与行为约束锚定答案、抑制幻觉USER_PROMPT_TEMPLATE为{question}与{context}预留占位符的固定骨架build_context把检索到的字典列表格式化为sectionQ:/A:分块的易读文本build_prompt把问题与上下文填入模板产出最终 User prompt消息历史在请求层把developer指令与user数据正式分离类封装以上逻辑在 rag_helper.py 中固化为RAGBase可通过参数覆盖指令、模板、模型与索引。至此RAG 三大件中提示词这一环已经就位。下一步是 The LLM把这个提示词真正发送给模型读取response.output_text并把搜索、提示词、LLM 三部分组装成完整的rag()函数——那将是整条 RAG 管线第一次端到端跑通。【免费下载链接】llm-zoomcampLLM Zoomcamp - a free online course about real-life applications of LLMs. In 10 weeks you will learn how to build an AI system that answers questions about your knowledge base. Register here 项目地址: https://gitcode.com/GitHub_Trending/ll/llm-zoomcamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表