Python 现代开发学习笔记

18-02 建立缺少证据的问题集

本章题解 · 全部练习

题目

加入三个笔记中没有答案的问题,记录检索结果、得分和最终回复。分别修改阈值与提示,检查哪些变化解决了误答、哪些丢掉了应命中的材料。

推导与做法

评估集包含一个应有答案的问题和三个语料外问题,先人工标出 expected_evidence。把阈值从 0.12、0.25 提到 0.4,分别记录命中、漏检与无关命中。

阈值提高可能减少误取,也可能丢掉真正需要的材料。当前回放模型只复现证据文本,不会因提示修改而获得语义判断能力;接真实模型时,再用同一问题集比较“材料不足就说明缺失”的提示。保留检索与最终回答两层记录,不能只检查输出是否符合 JSON。

过程图

%% 每个节点保留输入、执行位置或执行后的实际状态。 flowchart TD S0["先标注一个应答与三个无证据问题"] S1["阈值0.12、0.25、0.4分别检索"] S0 --> S1 S2["记录材料、得分与最终回复"] S1 --> S2 S3["比较误取与漏检,再评估提示改变"] S2 --> S3 classDef default fill:#EEF0FB,stroke:#4657B5,color:#24324A linkStyle default stroke:#4657B5

实现与运行

查看带注释实现。本题与相关处理函数放在同一章节代码文件中;启动工具负责定位相邻项目和选择题号。

在配套目录的 LangChain与AgentRuntime/study_agent 中运行。先按项目 README 执行 uv sync --locked。本章先执行 uv sync --locked --all-extras。18-06 还需执行 uv pip install -e "../../FastAPI/api_project",接入前面 API 声明的依赖;之后使用 --no-sync 保留这份组合环境。

# 使用项目解释器运行本题,题号决定执行哪一组演示。
uv run --no-sync python "../../学习索引/参考实现/代码/ch18.py" 18-02

程序按题号输出处理后的值、查询结果或状态。先和前面的手算比较,再修改一项输入重跑。

查看本题运行结果
# 与上面的手算状态和题目数值逐项比较。
[
  {
    "threshold": 0.12,
    "cases": [
      {
        "question": "NumPy 切片怎样避免改动原数组?",
        "expected_evidence": true,
        "retrieved": true,
        "top_score": 0.4545454545454546,
        "answer": "NumPy 切片与拷贝\n\nNumPy 的基本切片通常得到视图,视图和原数组共享数据。修改切片中的元素可能改变原数组。希望保留原数组时,先调用 copy(),再修改新数组。"
      },
      {
        "question": "东京明天的天气如何?",
        "expected_evidence": false,
        "retrieved": false,
        "top_score": 0.06666666666666668,
        "answer": "笔记中没有找到能支持这个问题的内容。"
      },
      {
        "question": "蓝鲸的平均寿命是多少?",
        "expected_evidence": false,
        "retrieved": false,
        "top_score": 0.0,
        "answer": "笔记中没有找到能支持这个问题的内容。"
      },
      {
        "question": "当前黄金价格是多少?",
        "expected_evidence": false,
        "retrieved": true,
        "top_score": 0.13018891098082386,
        "answer": "恢复会重新进入暂停节点,从节点开头执行。因此实际写入放在确认后的独立节点,并用业务操作编号避免重复保存。"
      }
    ]
  },
  {
    "threshold": 0.25,
    "cases": [
      {
        "question": "NumPy 切片怎样避免改动原数组?",
        "expected_evidence": true,
        "retrieved": true,
        "top_score": 0.4545454545454546,
        "answer": "NumPy 切片与拷贝\n\nNumPy 的基本切片通常得到视图,视图和原数组共享数据。修改切片中的元素可能改变原数组。希望保留原数组时,先调用 copy(),再修改新数组。"
      },
      {
        "question": "东京明天的天气如何?",
        "expected_evidence": false,
        "retrieved": false,
        "top_score": 0.06666666666666668,
        "answer": "笔记中没有找到能支持这个问题的内容。"
      },
      {
        "question": "蓝鲸的平均寿命是多少?",
        "expected_evidence": false,
        "retrieved": false,
        "top_score": 0.0,
        "answer": "笔记中没有找到能支持这个问题的内容。"
      },
      {
        "question": "当前黄金价格是多少?",
        "expected_evidence": false,
        "retrieved": false,
        "top_score": 0.13018891098082386,
        "answer": "笔记中没有找到能支持这个问题的内容。"
      }
    ]
  },
  {
    "threshold": 0.4,
    "cases": [
      {
        "question": "NumPy 切片怎样避免改动原数组?",
        "expected_evidence": true,
        "retrieved": true,
        "top_score": 0.4545454545454546,
        "answer": "NumPy 切片与拷贝\n\nNumPy 的基本切片通常得到视图,视图和原数组共享数据。修改切片中的元素可能改变原数组。希望保留原数组时,先调用 copy(),再修改新数组。"
      },
      {
        "question": "东京明天的天气如何?",
        "expected_evidence": false,
        "retrieved": false,
        "top_score": 0.06666666666666668,
        "answer": "笔记中没有找到能支持这个问题的内容。"
      },
      {
        "question": "蓝鲸的平均寿命是多少?",
        "expected_evidence": false,
        "retrieved": false,
        "top_score": 0.0,
        "answer": "笔记中没有找到能支持这个问题的内容。"
      },
      {
        "question": "当前黄金价格是多少?",
        "expected_evidence": false,
        "retrieved": false,
        "top_score": 0.13018891098082386,
        "answer": "笔记中没有找到能支持这个问题的内容。"
      }
    ]
  }
]

笔记正文与全部题解 · Ctrl / ⌘ K