前言
当前这个项目的目标:
做一个能基于课程资料,稳定回答课程相关问题的 RAG Copilot。
在上一篇中,已经把 RAG 的最小闭环跑通了:
-
能读取 PDF
-
能返回模型结果
但在继续往下推进时,意识到一个问题:
这个输出,我其实不太敢信。
一、遇到的问题:不是"不准",而是"不稳"
真正卡住我的,并不是模型能力本身,而是输出形态的问题:
-
同一份 PDF,多次运行输出结构不一致
-
有时候像课程大纲,有时候又像项目说明
-
内容看起来都"说得通",但无法稳定复现
从项目工程视角,就会变成一个核心风险:
结果不可预测,就无法被真正使用。
二、想解决的问题是什么
这一阶段,并不是想让模型"生成得更聪明",
而是想解决一个更基础、也更工程的问题:
模型能不能按照"规定的结果形态"来生成内容。
具体来说就是:
-
只回答课程相关内容
-
回答必须基于已有文档
-
输出结构本身是可预期的
这不再是简单的 prompt 调整,而是一个输出契约(Output Contract)的问题。
三、做了什么
围绕"输出是否可控"这个问题,做了这些调整:
-
将「课程大纲」和「项目说明」拆成两种独立的输出模式
-
同一份 PDF,通过不同 prompt 明确约束输出形态
-
对「项目说明」模式,强制固定为三页结构,用于说明背景、方案与测试视角
没有引入新的模型能力,也没有提前做复杂优化,只是先把"结果长什么样"这件事控住。
prompt_course_outline.py 文件要点记录:
SYSTEM_PROMPT = (
"你是一个 helpful assistant,会根据需要调用工具来获取信息。"
"当需要获取 PDF 内容时,你必须调用 read_local_pdf 工具读取文件内容。"
"后续输出必须基于工具返回内容,不得虚构。"
)
FIRST_PROMPT_TEMPLATE = (
"请读取以下 PDF 文件内容,然后基于内容生成一个详细的课程大纲(使用 Markdown)。\n"
"要求:每条大纲要点末尾请注明来源,格式为:(来源:文件名 摘录:...)。\n\n"
"PDF 文件路径:{pdf_path}"
)
SECOND_PROMPT = (
"请仅基于上面 tool 返回的【文件名 + p1/p2/p3 摘录】生成课程大纲(Markdown)。\n"
"要求:3~8章,每章3~7要点;每条要点末尾必须带(来源:文件名 pX 摘录:...)。\n"
"不要再次要求读取PDF,也不要再次调用任何工具。"
)
这个文件的定位:"课程大纲版"输出契约
它解决的问题
-
把 PDF 内容重组为"课程结构"
-
强制章节数/要点数
-
每条都要带来源(可追溯)
具体就是:
-
输出必须是 课程大纲
-
必须 3~8 章 ,每章 3~7 要点
-
每条要点末尾必须携带 (来源:文件名 pX 摘录:...)
-
第二轮不再调用工具(只基于 tool 返回的 p1/p2/p3)
适用场景:
-
需要"讲解式"材料:培训、对外讲解、内容二次加工
-
PDF 内容本身像教材/方案文档,适合课程化拆解
怎么验证:
-
同一 PDF 多次跑:章节结构稳定(不会变成三页说明)
-
每条要点都有来源,且 pX 正确
prompt_project_brief.py 要点记录:
# -*- coding: utf-8 -*-
SYSTEM_PROMPT = (
"你是一个工程型 AI 助手。"
"当需要获取 PDF 内容时,你必须调用 read_local_pdf 工具读取文件内容。"
"后续输出必须严格基于工具返回内容,不得虚构或扩写。"
"输出结构必须遵循用户明确��求的格式。"
)
FIRST_PROMPT_TEMPLATE = (
"请读取以下 PDF 文件内容。\n"
"注意:这是【项目说明文档(说明版)】,不是课程教材。\n"
"本轮只需要读取 PDF 并返回工具调用,不要做总结。\n\n"
"PDF 文件路径:{pdf_path}"
)
SECOND_PROMPT = (
"请仅基于上面 tool 返回的【文件名 + p1/p2/p3 摘录】生成《3页项目说明(说明版)》Markdown。\n"
"严格要求:\n"
"1) 必须按 p1 / p2 / p3 三页结构输出,标题格式为:\n"
" # 第1页:...\n"
" # 第2页:...\n"
" # 第3页:...\n"
"2) 每页输出 4~6 条要点(不要超过 6 条)。优先保留:目标/边界/流程/验收/测试。\n"
"3) 不要生成课程大纲或第X章目录式结构。\n"
"4) 不得新增 PDF 中不存在的观点。\n"
"5) 不要再次调用任何工具。\n"
"6) 允许轻度整理语句,但不要改变原意。\n"
"7) 每条要点末尾必须带来源:(来源:文件名 pX 摘录:...)。\n"
"8) 【重要】每条来源摘录控制在 20~40 个汉字,必要时用...省略,但保留关键词。\n"
)
文件定位:"项目说明版(说明版)"输出契约(更工程、可复述)
它解决的问题:
-
解决你说的核心痛点:"能跑但不可信"
-
让输出形态稳定(固定三页)
-
把"日志式输出"变成"可交付说明"
具体说明:
-
输出必须按 三页结构:
-
# 第1页:... -
# 第2页:... -
# 第3页:...
-
-
每页 4~6 条要点(不超过 6)
-
不允许输出"课程大纲/第X章/目录式结构"
-
不允许新增 PDF 中不存在的观点
-
每条要点必须带来源,且 摘录长度受控(20~40 字,可省略号)
-
第一轮只触发读 PDF(不总结),第二轮才输出
适用场景:
- 写 README、对外解释项目
怎么验证它(最小回归点):
-
输出一定是三段标题(第1/2/3页)
-
每页条数 ≤ 6
-
引用摘录明显变短(不再一大坨)
-
不会漂移成"课程大纲"
四、这一步对后续 RAG 有什么意义
这一步是 RAG 从"能跑"走向"可信" 的分水岭。
原因:
-
只有当输出是稳定、可控、可复现的
-
后面的检索效果评估、回归测试、质量对比才有意义
否则,即使检索做得再好,也很难判断问题到底出在检索、生成,还是输出组织本身。
五、这一篇暂不展开的内容
本文只记录这一阶段的判断与实践结果,暂不展开以下内容:
-
RAG 检索策略
-
chunk / embedding 设计
-
离线评测与回归验证
这些内容后面看情况再补充。
附:代码记录(GitHub)
本阶段的代码放在 GitHub,
主要用于记录这一阶段「输出形态控制」的实现与验证,方便后续回看与迭代。
GitHub(私有仓库,用于阶段性存档):
https://github.com/test202005/project2_mvp