生成
生成(generation)把「問題 + 檢索到的段落」編成一次 LLM 呼叫。模型的工作是綜合與措辭,不是補充庫裡沒有的事實。
提示裡該有什麼
一個堪用的 RAG 提示通常有三塊:
- 指令:根據上下文回答;上下文沒有就明說不知道;不要編造;引用來源。
- 上下文:檢索到的塊,每塊標上編號或檔名,方便引用。
- 使用者問題。
你是公司內規助理。只根據「上下文」回答。
若上下文不足以回答,說「文件中找不到相關規定」,不要猜測。
在句末用 [1] [2] 標出來源編號。
上下文:
[1] (來源:差旅辦法.md)……
[2] (來源:補助表.md)……
問題:出差可以報計程車嗎?
沒有「不知道」這條指令,模型很容易用訓練知識把缺口補滿,RAG 就失去可核對性。
把塊塞進提示時
- 順序:相關的放前面,或依重排序分數排。有些模型對開頭與結尾較敏感。
- 去重:同一段出現兩次會浪費 token。
- 長度:超出模型視窗就截最不相干的,而不是默默截斷結尾。
- 引用:要求輸出來源標記,再在 UI 做成可點的連結。Microsoft RAGChat 示範了用括號標記再抽成超連結,見 官方影音。
最小可跑的串接
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
prompt = ChatPromptTemplate.from_template(
"""只根據上下文回答。沒有就說找不到。
上下文:
{context}
問題:{question}"""
)
llm = ChatOpenAI(model="gpt-4.1-mini")
docs = retriever.invoke(question)
context = "\n\n".join(d.page_content for d in docs)
answer = llm.invoke(prompt.format(context=context, question=question))
LangChain/LlamaIndex 有現成的 chain 或 query engine;自己組一次,比較知道失敗時該查檢索還是提示。
生成仍會錯的原因
- 檢索對了,提示沒要求引用,模型忽略上下文。
- 檢索錯了,模型仍流暢作答(faithfulness 低)。
- 多塊互相矛盾,沒告訴模型以哪份文件為準。
這些要用 評估 分開看,不要只看「答案好不好讀」。
下一頁:評估。影片:LangChain Part 4 Generation。