8.5.4 项目:智能问答助手
- 理解一个智能问答助手和普通问答函数的差别
- 学会把检索、状态、工具调用放进同一条流程
- 学会定义这个项目最关键的评估维度
- 学会把它做成一个更像产品的作品集项目
一个智能问答助手到底比普通问答多了什么?
Section titled “一个智能问答助手到底比普通问答多了什么?”不只是“你问一句,我答一句”
Section titled “不只是“你问一句,我答一句””真正的助手感通常来自:
- 它记得上一轮
- 它会在需要时追问
- 它知道什么时候该查知识库,什么时候该查工具
一个清楚的练手题目
Section titled “一个清楚的练手题目”例如:
做一个课程平台助手,能回答退款、证书和学习进度类问题。
这个题目非常适合,因为它天然包含:
- 知识库
- 用户状态
- 多轮上下文
作品级项目的最小闭环长什么样?
Section titled “作品级项目的最小闭环长什么样?”- 维护会话历史
- 识别当前主题
- 检索相关知识
- 必要时调工具查用户状态
- 输出带上下文意识的回答
只要这 5 步做清楚,项目就已经很有产品感。
一张更像真实产品的闭环图
Section titled “一张更像真实产品的闭环图”flowchart LR A["用户消息"] --> B["主题判断"] B --> C["检索知识"] C --> D["是否需要调工具"] D --> E["生成回答"] E --> F["更新会话状态"] F --> A这张图很重要,因为它会提醒你:
- 助手不是只回答一次
- 而是在一轮轮对话里不断更新状态和行动

推荐推进顺序
Section titled “推荐推进顺序”对新人来说,更稳的顺序通常是:
- 先做单轮知识问答
- 再补会话状态
- 再补工具调用
- 最后再做多轮评估和失败案例展示
这样你才能明确知道“助手感”到底是从哪一层加出来的。
一个更适合新人的总类比
Section titled “一个更适合新人的总类比”你可以把智能问答助手理解成:
- 一个会查资料、会追问、也会查系统状态的客服
它和 FAQ 页最大的不同不在于:
- 回答更长
而在于:
- 会根据上下文继续协作
先跑一个更完整的最小助手
Section titled “先跑一个更完整的最小助手”下面这个示例会做:
- 维护 session
- 检索知识库
- 在退款问题里调用用户进度工具
- 根据上下文生成最终回答
kb = [ {"key": "退款", "text": "退款政策:购买后 7 天内且学习进度低于 20% 可退款。"}, {"key": "证书", "text": "证书政策:完成所有项目并通过测试后可获得证书。"},]
def retrieve(query): if "退款" in query: return kb[0], 0.92 if "证书" in query: return kb[1], 0.88 return None, 0.0
def get_user_progress(user_id): progress_db = { 1: 0.15, 2: 0.30, } return progress_db.get(user_id, None)
def new_session(): return { "history": [], "topic": None, "user_id": None, "last_retrieved_doc": None, "last_tool_call": None, }
def assistant_reply(session, user_message, user_id=None): if user_id is not None: session["user_id"] = user_id
session["history"].append({"role": "user", "content": user_message})
if "还能退" in user_message and session["topic"] == "退款" and session["user_id"] is not None: session["last_tool_call"] = {"name": "get_user_progress", "user_id": session["user_id"]} progress = get_user_progress(session["user_id"]) if progress is None: answer = "当前查不到你的学习进度信息,请确认账号状态。" else: answer = ( f"系统查到你的学习进度约为 {int(progress * 100)}%。" + (" 当前仍可退款。" if progress < 0.2 else " 当前不满足退款条件。") )
elif "退款" in user_message: session["topic"] = "退款" doc, score = retrieve("退款") session["last_retrieved_doc"] = doc session["last_tool_call"] = None answer = f"{doc['text']} 如果你告诉我学习进度,我可以继续帮你判断是否符合资格。"
elif "证书" in user_message: session["topic"] = "证书" doc, score = retrieve("证书") session["last_retrieved_doc"] = doc session["last_tool_call"] = None answer = doc["text"]
else: session["last_tool_call"] = None answer = "我目前可以帮助你处理退款、证书和学习进度类问题。"
session["history"].append({"role": "assistant", "content": answer}) return answer
session = new_session()print(assistant_reply(session, "退款政策是什么?", user_id=2))print(assistant_reply(session, "那我还能退吗?"))print("last_tool_call:", session["last_tool_call"])print("topic:", session["topic"])预期输出:
退款政策:购买后 7 天内且学习进度低于 20% 可退款。 如果你告诉我学习进度,我可以继续帮你判断是否符合资格。系统查到你的学习进度约为 30%。 当前不满足退款条件。last_tool_call: {'name': 'get_user_progress', 'user_id': 2}topic: 退款
这个例子最关键的价值是什么?
Section titled “这个例子最关键的价值是什么?”它不是只在做“问答”,而是在体现:
- 会话状态
- 检索与工具的分工
- 多轮上下文如何推动回答
这已经比单轮 FAQ 匹配更像真正的助手产品。
为什么 session 比答案本身更值得看?
Section titled “为什么 session 比答案本身更值得看?”因为 session 才是让系统持续协作的关键。
没有状态,你几乎做不出助手感。
再看一个最小“状态快照”示例
Section titled “再看一个最小“状态快照”示例”snapshot = { "topic": session["topic"], "user_id": session["user_id"], "last_retrieved_doc": session["last_retrieved_doc"], "last_tool_call": session["last_tool_call"],}
print(snapshot)预期输出:
{'topic': '退款', 'user_id': 2, 'last_retrieved_doc': {'key': '退款', 'text': '退款政策:购买后 7 天内且学习进度低于 20% 可退款。'}, 'last_tool_call': {'name': 'get_user_progress', 'user_id': 2}}这个示例很适合初学者,因为它会帮助你先看到:
- 助手系统真正需要维护的不是“原话全部文本”
- 而是几项关键状态
这个项目最该怎么评估?
Section titled “这个项目最该怎么评估?”单轮正确率不够
Section titled “单轮正确率不够”你至少还要看:
- 多轮上下文是否保持一致
- 工具调用是否合理
- 系统会不会在缺信息时瞎猜
一个最小评估用例表
Section titled “一个最小评估用例表”eval_cases = [ { "turns": ["退款政策是什么?", "那我还能退吗?"], "user_id": 1, "expected_keywords": ["15%", "可退款"], }, { "turns": ["证书怎么拿?"], "user_id": None, "expected_keywords": ["通过测试", "证书"], },]
for case in eval_cases: session = new_session() last_answer = "" for turn in case["turns"]: last_answer = assistant_reply(session, turn, case["user_id"]) print({ "turns": case["turns"], "last_answer": last_answer, "expected_hit": all(keyword in last_answer for keyword in case["expected_keywords"]), })预期输出:
{'turns': ['退款政策是什么?', '那我还能退吗?'], 'last_answer': '系统查到你的学习进度约为 15%。 当前仍可退款。', 'expected_hit': True}{'turns': ['证书怎么拿?'], 'last_answer': '证书政策:完成所有项目并通过测试后可获得证书。', 'expected_hit': True}为什么多轮评估特别重要?
Section titled “为什么多轮评估特别重要?”因为这类项目的亮点根本就不在单轮。 它最容易出错的地方恰恰是:
- 第二轮开始忘记上下文
一个很适合初学者先记的评估表
Section titled “一个很适合初学者先记的评估表”| 维度 | 更像在看什么 |
|---|---|
| 单轮回答对不对 | 知识回答能力 |
| 多轮上下文有没有接住 | 状态管理能力 |
| 工具调用合不合理 | 系统决策能力 |
| 缺信息时会不会追问 | 助手协作能力 |
这个表很适合新人,因为它会帮助你把“助手感”拆成几个具体可检查的部分。
怎么把这个项目做成作品级页面?
Section titled “怎么把这个项目做成作品级页面?”展示一条完整对话 追踪
Section titled “展示一条完整对话 追踪”例如:
- 用户问题
- 检索命中文档
- 是否调用工具
- 最终回答
特别值得展示的失败案例
Section titled “特别值得展示的失败案例”例如:
- 用户没给足信息时,系统是否会乱猜
- 工具查不到状态时,系统是否会诚实停住
一个很加分的点
Section titled “一个很加分的点”把:
- 知识回答
- 用户状态回答
这两条链画成流程图展示出来。
最容易踩的坑
Section titled “最容易踩的坑”只做单轮问答
Section titled “只做单轮问答”这样很难体现“助手感”。
没有工具边界
Section titled “没有工具边界”所有问题都靠模型猜,会越来越不稳。
不做上下文一致性检查
Section titled “不做上下文一致性检查”很多项目的问题恰恰出在第二轮和第三轮。
如果把它做成作品集,最值得强调什么
Section titled “如果把它做成作品集,最值得强调什么”最值得强调的通常不是:
- “它能聊天”
而是:
- 一条完整多轮对话 追踪
- 其中哪一轮触发了检索
- 哪一轮触发了工具调用
- session 状态是怎么变化的
- 系统什么时候选择追问或停住
这样别人会更容易感觉到:
- 你做的是一个持续协作系统
- 不只是多轮聊天演示
项目交付时最好补上的内容
Section titled “项目交付时最好补上的内容”- 一张系统流程图
- 一段完整多轮对话 追踪
- 一组工具调用成功 / 失败案例
- 一组“系统知道该追问 / 该停住”的例子
- 一段你对后续扩展路径的说明
学完这一页,至少保留这张证据卡:
- 项目目标
- 用户任务和业务边界
- 基线
- 最简单的提示/RAG/应用版本优先
- 评估
- 固定案例、检索证据、答案质量和引用检查
- 失败日志
- 至少一个失败案例及其可能原因
- 交付物
- README、运行命令、截图/日志、下一步
这节最重要的是建立一个产品级判断:
智能问答助手真正像项目的地方,不是答得像人,而是能否把检索、状态和工具调用组织成一条持续协作的多轮流程。
只要这条流程讲清楚,它就会非常像一款可继续扩展的真实 AI 产品。
版本路线建议
Section titled “版本路线建议”| 版本 | 目标 | 交付重点 |
|---|---|---|
| 基础版 | 跑通最小闭环 | 能输入、能处理、能输出,并保留一组示例 |
| 标准版 | 形成可展示项目 | 增加配置、日志、错误处理、README 和截图 |
| 挑战版 | 接近作品集质量 | 增加评估、对比实验、失败样本分析和下一步路线 |
建议先完成基础版,不要一开始就追求大而全。每提升一个版本,都要把“新增了什么能力、怎么验证、还有什么问题”写进 README。
- 给示例再加一个
学习顺序主题,让助手能处理三类问题。 - 想一想:为什么智能助手比 FAQ 更需要状态管理?
- 如果工具查不到用户状态,系统最稳妥的回应应该是什么?
- 如果你把这个项目做成作品集,最值得展示哪一段对话?
项目交付参考与讲解
学习顺序主题应增加 intent 识别、必填 slot、工具/上下文来源和回答模板。- 智能助手要跟踪用户目标、缺失信息、前面回答、工具结果和下一步动作;FAQ 多数只是无状态查询。
- 最稳妥的回应是说明暂时查不到状态,请用户补充必要信息或提供安全下一步,不能编造状态。
- 最值得展示的是包含多轮澄清、状态更新、工具/RAG 证据,以及失败或权限边界处理的对话。