设想你收到一份安排得很漂亮的行程:下午三点到站,三点二十参观博物馆。火车时刻和预约时间都查过,博物馆地址也有来源。
你再看一眼路程:从车站过去,至少需要半小时。
资料没有互相说谎,行程却要求你比自己早十分钟抵达。旅行还没开始,第一项活动已经是短距离瞬间移动。
出错的环节在哪里?系统可能分别记住了几个正确事实,却没有在安排时真正执行“到站时间加上交通耗时,不得晚于预约时间”这条比较。
给AI更多资料,是解决问题的一部分。怎样让分散的事实进入同一次可靠的判断,是另一部分。
一堆资料,怎样变成同一件事?
先给这个教学旅行系统整理材料。我们需要区分几种对象:车站、班次、场馆、预约。还要规定各自有哪些属性,比如班次的到达时间、预约的开始时间;对象之间有哪些关系,比如某班次到达哪个车站、某预约属于哪个场馆。
这套类别与关系的约定,可以理解为一份领域本体。名字听起来很哲学,眼前的工作很具体:别把“博物馆”当成一班车,也别把“预约时间”误装进“行驶时长”的格子。
再把具体材料填进去:南站是一个车站,下午三点到达的是某班次,三点二十开始的是某预约。将这些对象和关系连接起来,就得到一份知识图谱。图谱的重点是关系能够被查询和使用,不在于屏幕上画出了多少条漂亮的线。
这里必须分清两层。类别约定说“班次可以有到达时间”;具体记录说“这个班次的到达时间是三点”。前者像表格的栏目,后者像填进栏目里的值。两者混在一起,修改一班车的时间就可能误伤所有班次。
图画完了,谁来做那次加法?
只有图谱仍然不够。我们还要规定一项能够执行的检查:输入班次与预约,找到到站时间,沿关联取得车站和场馆,查询交通耗时,算出最早抵达时间,再与预约比较。
对开头的数据,这次检查得到三点半。它比三点二十晚十分钟,因此原安排不满足条件。程序应该返回具体冲突,而不是只说“综合考虑后,行程可行”。
如果换成两点四十到站的班次,同样加半小时,最早三点十分抵达,便能赶上。这次变化无需重新发明整套旅行哲学:换一个输入,再执行同一项检查即可。
把这种重复操作封装成可调用的函数,就能让Agent使用它。函数是预先写明输入、处理办法和输出的一段程序;Agent则是根据任务和反馈组织行动的系统。它可以选择检查哪两个对象,但检查内部的加法与比较有明确步骤。
于是,一句话里的“帮我看看能不能赶上”,被落实成了几次可追踪的查找与计算。过去只存在于提示词里的要求,开始有了实际执行的位置。
8月的新研究,把什么接到了一起?
8月24日提交的OaK论文,将任务本体、知识图谱与可执行函数组织成一个共同接口。构建时,它根据任务材料拟定类别和关系、抽取具体知识,再组合查询、筛选和汇总等操作,形成任务函数;随后利用执行结果与评价反馈修订。1
与单纯“检索几段相关文字”相比,这里多了一层可重复使用的计算安排。旅行例子中的关键不是找到“半小时”三个字,而是让它进入抵达时间的计算。
论文还有一个容易被“动态”二字遮住的边界:构建阶段可以迭代;测试时冻结类别约定和函数,再根据新问题的资料生成相应图谱。正式运行并非每遇到麻烦都临时改一套规则。1
这项研究在旅行规划等任务中报告了改进,属于知识组织与执行接口的系统方法进展。图谱与本体都有更早历史,新意要落在它怎样为任务构建、组合和修订接口,不能写成8月才发明“把知识连起来”。
验证过的结构,也可能装着错时间
回到车站。假如系统把“南站”与“南城站”误认为同一地点,交通时间就可能查错;若材料里的半小时只适用于某种交通方式,抽取时漏掉条件,计算也会认真使用错误前提。
因此至少要分别检查:类别关系是否自洽,具体事实是否正确,操作是否符合任务。三种问题不能凭同一个“已验证”标记一并放行。
例如,“预约开始时间必须是一个时间”可以防止把地址填进去,却无法证明填进去的三点二十来自正确日期。一个格子里的内容格式无误,并不意味着它说的是真的。
类似地,最早三点十分抵达,只说明在我们规定的固定半小时交通条件下能赶上。如果要考虑出站、排队或路况,就需要相应数据与规则。这不是催促系统再写几句“请合理安排时间”,而是明确指出计算里缺了哪一项。
封装也有代价。把常用判断做成工具,能减少重复组织步骤的负担;但工具没覆盖的新情况,需要修订或额外处理。原本灵活的一段话,被整理成明确接口之后,边界也会更清楚地显露出来。
一份好行程不只是每条信息各有出处,还要让这些信息在同一组条件下相容。知识结构负责说明对象怎样相关,函数负责执行必要判断,真实结果再告诉系统哪里需要修正。
三点到站的人,仍然不能三点二十完成半小时的路程。值得改进的Agent,应该替你换一班车,而不是把不可能的行程排得更好看。