2.4 户籍档案:本体与知识表示


2.4 户籍档案:本体与知识表示

摘要:智能体的知识表示回答"镇民脑子里的事实用什么结构存";本体(ontology)则是一群镇民共享的概念词汇表——类、关系、公理三件套。本节梳理逻辑、规则、框架三类经典表示,重点拆本体的构造与用途,并用分类树完成一次"任务—能力"的语义匹配。

两个镇民在集市上吵架,一个说"我要雇个搬运工",另一个说"我这就有个能举重的",旁边第三个嘀咕"举重的不就是搬运工吗"。吵了半天才发现,他们说的是同一件事,只是词汇表不同。这一节解决的就是这个问题:镇民脑子里的知识怎么表示,镇民之间的词汇表怎么统一。它是镇民解剖的最后一刀——前几节装的是"怎么想",这节装的是"想的东西放哪"。

知识表示的三件老家具

单个镇民存知识,经典路数有三大件。

逻辑表示:用一阶谓词逻辑写事实与规则,例如"在水井在位置 P"写成命题,"所有可搬运且空手的镇民都能取水"写成蕴含式。优点是语义精确、可推理;缺点是脆弱——一条事实错了,推理链整条污染。

规则表示:产生式规则(条件—动作或条件—结论),上一节行为层的规则栈就是它。优点是与决策天然贴合;缺点是规则间相互作用的可读性差,规模一大就成了"没人敢动的祖传代码"。

框架与语义网:框架是带槽位的记录模板("井"框架有位置、容量、状态槽),语义网把概念画成节点、关系画成边。两者是现代本体与知识图谱的共同祖先。

BDI 镇民的信念库、反应式镇民的规则表、混合式镇民的分层模型,底层不外乎这三大件的组合。选型口诀:要可解释可推理用逻辑,要驱动行为用规则,要挂结构化属性用框架。

本体:镇民的公共词汇表

单个镇民怎么存知识是私事;一群镇民要对话,就必须统一词汇。本体就是某个领域内概念及其关系、约束的形式化规范说明——镇民共同签署的"词典加语法"。三件套:

类(概念):领域里的话题词。运输领域有"车辆""无人机""搬运工",它们构成一棵分类树:无人机是飞行器,飞行器是运载工具。

关系:概念之间的谓词。"能够举起"连接搬运工与货物;"位于"连接车辆与仓库。关系也可以有层次("位于"是"空间关联"的子关系)。

公理:约束与推理规则。"若 X 能举起 Y 且 Y 属于重型货物,则 X 具备重载能力";"无人机不得进入禁飞区"。公理让本体从词典升级为法典。

💡 一句话分清两个易混词:本体管"大家同意这些词是什么意思",知识库管"具体某件事是什么情况"。本体是 schema,事实是数据。

图 2-4 运输领域的本体切片:分类树加关系网

图 2-4 运输领域的本体切片:分类树加关系网

用代码建一座迷你本体

下面用纯 Python 实现一个带分类树与公理的迷你本体,支持"子类传递推理"与"能力查询"。第 3 章合同网里的能力匹配、第 4 章任务分解里的可行性检查,都靠这一套。

class MiniOntology: """迷你本体:类层次 + 关系断言 + 可传递的子类推理。""" def __init__(self): self.parents = {} # 类 -> 父类 self.relations = {} # (关系名, 主体) -> {对象集合} def subclass(self, child, parent): self.parents[child] = parent def assert_rel(self, rel, subj, obj): self.relations.setdefault((rel, subj), set()).add(obj) def is_a(self, x, cls): """x 是否属于 cls:沿分类树向上找。""" while x in self.parents: x = self.parents[x] if x == cls: return True return x == cls def query(self, rel, subj): """查询关系,自动沿子类继承父类断言。""" out = set(self.relations.get((rel, subj), set())) for (r, s), objs in self.relations.items(): if r == rel and self.is_a(subj, s) and subj != s: out |= objs # 父类的断言子类继承 return out onto = MiniOntology() onto.subclass("drone", "vehicle"); onto.subclass("truck", "vehicle") onto.subclass("hauler", "agent"); onto.subclass("operator", "agent") onto.assert_rel("can_carry", "vehicle", "light_cargo") onto.assert_rel("can_carry", "truck", "heavy_cargo") onto.assert_rel("forbidden", "drone", "no_fly_zone") print("drone 能运:", onto.query("can_carry", "drone")) # 继承 vehicle 的轻货 print("truck 能运:", onto.query("can_carry", "truck")) print("drone 是 vehicle 吗:", onto.is_a("drone", "vehicle"))

注意 query 里的继承:给"运载工具"挂上"能运轻货",无人机与卡车自动继承——把断言尽量挂在高层,是本体维护的第一美德

用本体做一次能力匹配

本体真正的产出是"语义匹配"。招标书要"能运重货且不进禁飞区的运力",登记处把条件翻译成图查询,而不是字符串比对:

def match(agent_types, requirement, onto): """requirement: [(关系, 对象, 正负号), ...],正=须满足,负=须不满足。""" hits = [] for t in agent_types: ok = True for rel, obj, polarity in requirement: has = obj in onto.query(rel, t) if has != (polarity == "+"): ok = False; break if ok: hits.append(t) return hits types = ["drone", "truck", "forklift"] onto.subclass("forklift", "vehicle") onto.assert_rel("can_carry", "forklift", "heavy_cargo") onto.assert_rel("zone", "forklift", "warehouse_only") req_light = [("can_carry", "light_cargo", "+")] req_air = [("can_carry", "light_cargo", "+"), ("forbidden", "no_fly_zone", "-")] print("轻货运力:", match(types, req_light, onto)) print("能进禁飞区的轻货运力:", match(types, req_air, onto))

同一个词"运力",需求方写条件、供给方挂标签,本体负责翻译与匹配——无人机被禁飞区条款排除,靠的是关系查询而不是名字里带"飞"字。第 3 章合同网的"招标—投标"要跑得通,底层正是这套词汇基础设施。顺带一提,标准化阵营为这类内容设计了专门的语言:KIF 用一阶逻辑写断言,FIPA-SL 是智能体消息的内容语言,网络时代的 OWL 则给类层次配上了机器可验的公理表达能力。语言可以换,"共享词汇表"这个思想不变。

理论账本

本体的账本两面记。收益面:语义互操作(异构镇民说得上话)、知识复用(断言挂高层、全树继承)、推理增值(公理把隐含事实显式化)、需求清晰(领域共识写进文档而非口口相传)。成本面:本体工程昂贵——建模、评审、版本演化都要人力;过强的本体反而僵化,领域一变,改动成本像还技术债;分布式环境下还各有各的版本,本体对齐(两套词汇表的映射)本身就是个研究课题。

⚠️ 常见坑:为了"先进"给每个概念都建公理,结果镇民每次通信都要跑一遍推理机,延迟翻了数倍。工程惯例是:公理只写会改变决策的那几条,其余留给文档。

沙盘推演小结

回到开头的集市吵架:有了本体,"搬运工"与"能举重的"被分类树归并,"举重物者具备重载能力"的公理自动补全隐含条件,第三个镇民不用再嘀咕。镇民解剖到此完成——脑子(体系结构)与档案(知识表示)都齐了。下一章开邮政局:脑子再好、档案再全的镇民,也得先把话说给对方听懂。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U