Skip to content

结构化数据 Agent:从自然语言到查询语义 ​

对应 CS224V · 2026-10-07 · Agents for Structured and Hybrid Data。日期为校方课表日期,可能调整。核对官方课表。

资料状态

核对日期:2026-09-19。对应课程尚未开课;本文是基于公开课纲与文中原始资料的原创预习技术解读,不是课堂实录、讲义翻译或官方作业答案。本文于 2026-09-20 深度修订。示例为原创教学设计;离线实验与真实模型实验的边界分别说明,不以推演冒充模型实测。

课程助手现在要从 C1–C6 中筛选秋季、无冲突、先修满足的课程。把表格转成一段自然语言再让模型挑选,很容易遗漏一个条件。结构化数据的优势,在于可以把自然语言理解与确定性执行分开。

本讲完成从请求到查询的转换,并重点解释:SQL 能执行,为何仍然可能回答错问题。

模式不仅是列名,也是语义约定 ​

数据库需要明确学期枚举、学分单位、课程与开课实例的关系。课程介绍可能长期不变,上课时段却属于具体学期的 offering;若把二者混成一行,更新一个学期可能覆盖另一个学期。

一个教学模式可以包含 courses、offerings、meetings 和 prerequisites。查询时先选开课实例,再关联课程介绍,避免把上一年的时间表拼到今年的课程上。

模型要知道 credits=3 是 3 学分,term='autumn' 是枚举值。用户说 fall 可以映射为 autumn,但映射应由模式说明与合法值约束,而不是遇到空结果后随意改写。

时间冲突是区间关系 ​

将上课时段统一成同一时区、同一天内的分钟数,使用半开区间 [start,end)。两个区间冲突的条件是:

text
同一天,且 start1 < end2,且 start2 < end1

周三 14–16 与 15–17 冲突;14–16 与 16–18 在这个约定下不冲突。若需要跨教室通勤时间,应把缓冲加入业务规则,而不是偷偷改比较符。

有多个上课时段时,任意一个时段冲突就排除该开课实例。SQL 可用 NOT EXISTS 表达不存在冲突时段。只比较星期几会错误排除同一天但不重叠的课。

先修的未知不是不满足,也不是满足 ​

用户完成 A,B 未知。C3 要求 B,数据库中找不到完成记录时,如果记录体系不保证完整,就只能说未确认。不能默认用户没有学过,也不能为了推荐而默认满足。

可以在数据层保存已完成、明确未完成和未知三类状态。只有“已确认满足”进入确定推荐;未知进入待核实集合。后续约束求解篇会进一步说明这种开放事实的处理。

连接会悄悄改变计数 ​

一门课有三条评价,连接 courses JOIN reviews 后出现三行。如果随后 COUNT(*),统计的是评价行,不是课程数。按学分求和还可能把一门课算三遍。

这不是模型算术不行,而是查询粒度错误。对课程计数用正确的课程或开课实例键,或先聚合评价再连接。DISTINCT 可以消除某些重复,却不能代替理解哪些重复具有真实含义。

一次自然语言解析应输出什么 ​

解析器可以先给出结构化意图:目标实体是开课实例,学期过滤,排除冲突,确认先修,单门加入后不超学分。之后由受限查询构建器生成 SQL,或对模型生成的查询执行语法树检查。

仅用字符串判断是否包含 SELECT 不够;多语句、函数和可访问对象都需要控制。执行账号使用只读权限、超时和结果上限,让模型无法通过查询文本扩大数据库能力。

SUQL 官方项目可作为后续混合查询的研究来源;本篇先建立普通结构化查询的语义基础。

把“任何时段都不能冲突”写进查询 ​

以下是简化模式下的相关子查询;busy 保存用户已有时段,meetings 保存每个开课实例的全部时段。其余条件在外层分别检查。

sql
SELECT o.id
FROM offerings AS o
WHERE o.term = 'autumn'
  AND NOT EXISTS (
    SELECT 1
    FROM meetings AS m
    JOIN busy AS b ON m.day = b.day
    WHERE m.offering_id = o.id
      AND m.start_min < b.end_min
      AND b.start_min < m.end_min
  );

外层每次考虑一个开课实例;内层只要找到一对冲突时段,EXISTS 就成立,该实例被排除。反过来,不能写成“存在一个不冲突时段”:一门课有周一讲座和周三实验,周一不冲突并不能抵消周三冲突。

还有一个容易被忽略的前提:课程时间表完整。如果 meetings 缺了全部记录,内层也找不到冲突,查询会把它当作通过。因此生产查询需要额外的 schedule_complete 状态,或在数据接入层保证每个实例的时段已完整录入。数据库忠实执行的只是已给定语义,不会自动知道空表代表“没有课”还是“资料缺失”。

用极小数据暴露错误 ​

在共同数据上,忽略文本条件时,确定满足硬条件的课程是 C1、C5、C6。C2 时间冲突,C3 先修未知,C4 学期不符。把 C2 的开始时间改为 16 点,按半开区间规则它才通过时间条件。

再把用户学分上限改为 6,任何 3 学分课程加入后都超限。若结果不变,说明某个条件没有进入查询。随后为 C1 添加第二条评价,候选数不应增加。

这些变形测试不依赖模型自然语言是否漂亮,直接验证查询是否保持任务语义。

下一讲在这些硬条件之上加入“实践充分”的文本判断,讨论混合查询的成本与正确性。继续阅读SUQL。


本课程逐讲目录 · 两门课程映射与资料边界 · 离线实验与验证边界