信息项
概述
- 信息项类似编程语言中的 “变量”,用于在对话过程中采集和存储用户提供的信息内容(也可以存储和用户输入无关的内容、或者用来和系统交换信息),并在后续的对话节点中进行引用和使用
- 信息项从产生的方式上可以分为如下类别:
- 用户输入信息项:指在 “#单次交互#” 或 “#多次交互#” 节点中定义的信息项,这些信息项都可以由用户输入(AI 提问然后用户肯定或否定也算用户输入 / 但不能是 AI 独立表达的内容),如果用户拒绝回答则信息项会被赋值 None(仅 “#单次交互#” 中定义的信息项可以被系统识别为拒绝回答),同时用户输入信息项也可以:
- 在相关节点的 “Python 脚本/函数” 中通过
ctx中被赋值或被引用 - 通过 “#开始#” 节点的 “启动信息项” 传入而被赋予初始值(参见 “节点 - #开始#” 中的 “启动信息项” 属性)
- 通过 “#动作#调用HTTP” 节点的返回内容而被赋值(参见 “节点 - #动作#调用HTTP”) 这类信息项的名称会进入 LLM 提示词,所以其命名需要符合后面的规范要求
- 在相关节点的 “Python 脚本/函数” 中通过
- 代码定义信息项:指没有在 “#单次交互#” 或 “#多次交互#” 节点中定义过的、而是通过上述 “用户输入信息项” 中的 3 种方式被初始赋值的信息项。这类信息项的名称不会进入 LLM 提示词,所以其命名不用符合后面规范要求;这些信息项一般用来辅助信息存储以及进行计算或逻辑判断,可以看成是作用域在整个对话 session 中的辅助 “变量”
- 系统信息项:指系统预设的信息项,系统会根据执行情况自动对其赋值和使用其值,对话树中的代码或脚本可以对其进行访问;系统信息项的名称两端都有下划线且最外边也被大括号括起来,在 “Python 脚本/函数” 中也可以通过
ctx进行引用。目前有:- {_电话号码_}:str 类型,包括呼入号码和呼出号码,实时语音交互应用在启动对话树时传入
- {_用户性别_}:str 类型,“男” 或 “女”,实时语音交互应用调用 intentchat_set_user_gender_age 进行设置
- {_用户年龄段_}:str 类型,“儿童” 或 “中青年” 或 “老年”,实时语音交互应用调用 intentchat_set_user_gender_age 进行设置
- {_当前节点正在执行的次数_}:num 类型,系统自动设置,
- {_当前用户输入_}:str 类型,系统自动设置
- {_多轮交互退出原因_}:str 类型,“#多轮交互#” 节点的交互循环中,系统自动设置或节点的 “执行脚本” 属性中的脚本或函数设置
- {_多轮交互动态提示词_}:str 类型,“#多轮交互#” 节点的交互循环中,节点的 “执行脚本” 属性中的脚本或函数设置
- {_参考信息命中内容_}:str类型,包括命中的静态和动态的参考信息,系统自动设置
- {_时区_}:num 类型,即 GMT 时区,对话树启动时传入
- 用户输入信息项:指在 “#单次交互#” 或 “#多次交互#” 节点中定义的信息项,这些信息项都可以由用户输入(AI 提问然后用户肯定或否定也算用户输入 / 但不能是 AI 独立表达的内容),如果用户拒绝回答则信息项会被赋值 None(仅 “#单次交互#” 中定义的信息项可以被系统识别为拒绝回答),同时用户输入信息项也可以:
- 关于信息项的值和使用方法,更多可参见 “Python 脚本/函数” 中关于
ctx["{...}"]的说明
用户输入信息项的命名规范要求及约束
- 2 种表达形式(适用于不同场景,如果一种效果不太好可以尝试另一种)
- 不带问号和语气词的疑问句:
- 如:“谁......”、“......什么时间......”、“......什么类型......”、“为什么......”、“......是否......”、“......是......、......还是......”
- 用 “你” 或 “#开始#” 节点的 “系统角色” 来指代对话中的 AI 机器人,用 “用户” 或 “#开始#” 节点的 “用户角色” 来指代对话中的另一方(即用户);慎用其它容易引起混淆的代词
- 名词词组:
- 如:“...的时间”、“...的原因”、“...的地点”、“...的金额”、“...的申请人” 等
- 不带问号和语气词的疑问句:
- 文字要求:
- 只能是 “汉字、数字、大小写字母、全角单引号、顿号、下划线、减号、斜杠和小数点”,且这些符号都用一对大括号括起来,如 “{......}”
- 不能有空格(类似英文单词之间的空格用下划线 “_” 代替),否则空格将会被忽略
- 准确、完整表达信息项相关的上下文信息,可以是信息项名称本身的优化,也可以使用信息项约束:
- 信息项名称中加入修饰词或场景信息进行限定:
- {年龄} 可优化为 {孩子年龄},甚至进一步优化为 {离婚案件中的孩子年龄}
- {预约时间} 可优化为 {体验课预约时间}
- {是否准备告诉双方父母关于离婚的事情} 可优化为 {之前没有说过的话是否准备告诉双方父母关于离婚的事情}
- {具体的地点} 可优化为 {来电者目前所在的具体地点}
- {接电话时间} 可优化为 {期望接听电话的时间}
- {是否已就离婚进行协商} 可优化为 {双方是否已就离婚进行过协商}
- 特别是类似 {案情}、{原因}、{理由}、{结果} 这类描述性信息项,更需要通过修饰词、场景信息等优化信息项名称,以避免抽取的内容过于宽泛而导致准确率低下
- 信息项约束(见 “节点 - #单次交互#” 和 “节点 - #多轮交互#”)进行语义或格式要求(约束描述本身中不能包含“()(){}[]|”等字符),通过约束避免信息抽取的歧义性:
- {刑事案件案情} 可加上约束 “非交通事故”
- {投保人姓名} 可加上约束 “必须是完整的姓名,仅仅某先生某女士则不算”
- {为谁寻求法律服务} 可加上约束 “必须是一个特定的人,不能是否定形式”
- {航班日期} 可加上约束 “必须转换为 YYYY-MM-DD 格式,不能转换则不算”(注意这里的约束不能是 “必须是YYYY-MM-DD格式”,这样可能会导致信息项内容抽取的失败,下同)
- {家务开始时间} 可加上约束 “必须转换为 HH:MM:SS 格式,24小时制,不能转换则不算”
- {家务时长} 可加上约束 “必须转换为 HH:MM:SS 格式,如 03:03:22 表示 3 小时 3 分 22 秒的时长,不能转换则不算”
- {周几做家务} 可加上约束 “必须转换为 1 到 7 的数字形式,分别表示周一到周日,有多个则用逗号分隔开,不能转换则不算”
- {家务是每周执行还是每隔若干周执行} 可加上约束 “如果只是‘按周计算’则两种可能性都有,此时没有答案”
- {你最后的报价} 可加上约束 “必须是你即律师方明确提出或明确同意的金额,必须是数值的最终结果”
- {车主电话号码} 可加上约束 “只有你询问‘车主电话号码’后用户提供的号码、或者用户明确是‘车主电话号码’这两种情况才算” 注意,有些约束是经过测试后发现信息抽取的效果不好再加上的
- 完备性也要兼顾:
- 120 场景中的 {伤情或病情} 可优化为 {伤情或病情或身体状况} 并加上约束 “无症状也算”
- 不能有歧义(表达方式和用词上)
- 慎用否定或排他的表达方式,如 {非...}、{其它...}
- 信息项名称中加入修饰词或场景信息进行限定:
- 信息项名称不是越长越好,有时无用信息太多也会反过来影响 LLM 的信息抽取准确率
- 不同信息项的命名要尽量明显区分开来
- 一个对话树中(包括可能调用的子树),在不同的 “#单次交互#” 和 “#多轮交互#” 节点,不能有名称相同、或名称有包含关系、或意思相近的信息项,比如:
- {地址} 和 {具有标志物或门牌号的地址}
- {发货站} 和 {车辆发货站}
- {是否愿意参加体验课} 和 {再次引导后是否愿意参加体验课}
- {是否参加体验课} 和 {能否参加体验课}
- {是否愿意让销售报价} 和 {能否接受车险报价} 等等,都应该避免,否则会造成混淆、产生错误的对话逻辑
- 如果两个 “#单次交互#” 节点的信息项确实需要是一个意思,则:
- 或者这两个节点应该能合并
- 或者让两个的名称略微不同且不要相互包含(如 {货物查询的发货站} 和 {运费查询的发货站}),然后这两个信息项要么 (1) 某一个或两个都加上 “固定” 信息项修饰、要么 (2) 两个分别在带 “主题” 属性的 “#单次交互#” 节点后的不同 “#用户意图#” 分支上
- 一个对话树中(包括可能调用的子树),在不同的 “#单次交互#” 和 “#多轮交互#” 节点,不能有名称相同、或名称有包含关系、或意思相近的信息项,比如:
- 在信息项名称中绝对不能有要求 LLM “做” 或 “说” 任何事情的表达,比如 {告诉我...}、{帮我...}、{给我...}、{说...}、{回答...} 等等
用户输入信息项的预设可选值
- 仅 Python 对话树支持,Xmind 对话树不支持
- 可以给信息项的值设置 “信息项选项”(一个元素为 str 的 list / 见 “节点 - #单次交互#” 和 “节点 - #多轮交互#”),指信息项的值仅能是(或应尽量匹配)该选项所列出的(一个或多个)值,同时还可使用 “信息项选项修饰”(也是一个元素为 str 的 list)来进行精确控制:
- 如果 “信息项选项修饰” 含有 “多选”,则表示该信息项的值可以是选项中的一个或多个(抽取后多个值会以 “|” 分隔开来);如果没有,则表示该信息项的值最多只能是选项中的一个(即匹配度最高的一个,如果能匹配的话)
- 如果 “信息项选项修饰” 含有 “开放”,则表示该信息项的值可以在选项中也可以不在;如果没有,则表示该信息项的值必须在选项中
- “多选” 和 “开放” 可以同时存在,也可以各自单独存在,也可以都不存在
- “对话树例子” 中的 “商旅平台_预订机票” 和 “医院挂号” 对话树例子中有 “信息项选项” 和 “信息项选项修饰” 这两个属性
- 比如 “信息项选项” 为
["普外科","耳鼻喉科","内科"],如果用户输入 “普通外科” 则会被抽取为 “普外科”;如果用户输入 “烧伤科” ,则不会被抽取出任何值(如果 “信息项选项修饰” 未含 “开放”)或被抽取为 “烧伤科”(如果 “信息项选项修饰” 含有 “开放”) - “信息项选项修饰” 中既不含 “多选” 也不含 “开放” 时,这种情况和 “单次交互” 节点后面有若干 “用户意图” 节点的情况其实一样,这时若干 “用户意图” 节点中的 “意图” 就相当于信息项选项了
- “信息项选项” 的值中,有时需要有一个 “不限” 意思的值(表示当使用 InfoItem 的值作为条件时所有情况都是可以接受的),比如信息项 “{航空公司}”,其 “信息项选项” 一般是
["国际航空", "东方航空", "南方航空", ...],如果要增加一个这样的值,不能仅仅是 “不限”,而要是 “不限航空公司”,即["不限航空公司", "国际航空", "东方航空", "南方航空", ...](上面提到的 “单次交互” 节点后面有若干 “用户意图” 节点的情况也类似,即需要增加一个 “不限航空公司” 的 “用户意图” 节点)
“配套”的用户输入信息项
有些作为 “#单次交互#” 节点的信息项需要有相应的 “配套” 信息项,比如:
- {交通事故对方的伤情},需要有一个 {交通事故对方是否受伤} 的 “配套” 信息项,这样就先提问 “对方是否受伤?” 再询问 “伤到哪里了?严重吗?”,否则如果用户直接回复 “没受伤” 时会有问题
- {离婚案件中需告知的其它内容},需要一个 {离婚案件中是否还需告知其它内容} 的 “配套” 信息项,先提问 “您是否还有其它什么想告诉我们的吗?” 再询问 “那您还要告诉我们什么?”,否则如果用户直接回复 “没有了” 时会有问题
一个用户输入可能会涉及多个用户输入信息项
- 用户输入 “我是去年发现他呢,一直在各种藏匿和转移财产”,可能会信息抽取:{离婚的原因}=“去年发现对方一直在各种藏匿和转移财产”,{离婚的争议点}=“财产转移”,{离婚的财产状况}=“对方一直在各种藏匿和转移财产”
信息项的赋值和使用
- 可产生、修改、引用和清除信息项的地方:
- “#单次交互#” 节点、“#多轮交互#” 节点,基于用户的输入
- 所有 Python 脚本或函数(基于脚本或函数中的
ctx对象进行信息项的访问或赋值),具体参见 “Python 脚本/函数” - “#开始#” 节点,启动方传入(包括执行 “#重启#” 节点重启整个对话后)
- “#动作#调用HTTP” 节点,基于返回结果
- “#动作#重新提问” 节点、“#动作#跳过提问” 节点、“#动作#清除信息” 节点
- 可对信息项的出现进行宏替换的地方(可以用方括号或单引号将信息项括起来,比如在 “#条件#描述” 中,这样能确保在最终的 LLM 提示词中替换后信息项的值的独立性):
- “#单次交互#” 节点的 “系统问题” 属性
- “#单次交互#” 节点的 “提问前提示用户” 属性
- “#单次交互#” 节点的 “提问前结构化输出” 属性
- “#开始#” 节点的 “应对话术” 属性中的 “话术” 部分
- “#提示用户#” 节点的 “提示内容” 属性
- “#结构化输出#” 节点的 “输出内容” 属性
- “#条件#描述” 节点的 “描述” 属性
- “#动作#调用HTTP” 节点的 “链接” 属性