跳到主要内容

Python 脚本/函数

可以出现的地方

位置Python 对话树Xmind 对话树
“#动作#执行脚本” 节点“函数” 属性的 函数名lambda 表达式第二行开始的 单行/多行脚本
“#多轮交互#” 节点“执行函数” 属性的 函数名lambda 表达式“执行脚本” 属性的 单行/多行脚本
“#开始#” 节点的 “信息项变化触发” 属性“函数” 字段的 函数名lambda 表达式每行 “-->” 后的 单行脚本
“#条件#脚本” 节点“函数” 属性的 返回 bool 值的函数名返回 bool 值的 lambda 表达式第二行开始的 单行/多行 bool 表达式脚本
“#开始#” 节点的 “动态参考信息” 属性“函数” 字段的 返回 str 值的函数名返回 str 值的 lambda 表达式每行 “-->” 后的 单行 str 表达式脚本
“#开始#” 节点的 “意图触发” 属性“函数” 字段的 函数名lambda 表达式每行 “-->” 后的 单行脚本
“#单次交互#” 节点的 “提问前执行脚本” 属性函数名lambda 表达式(无)
所有节点的 “执行前” 和 “执行后” 属性函数名lambda 表达式(具体参见“IDE调试”(无)

Xmind 对话树:脚本

  • 脚本是一段受限的 Python 代码,不能含有 import、open、globals、locals、exit、quit、input 等关键词
  • 脚本中可以使用 ctx 这个当前对话上下文环境变量,具体参见下面的内容

Python 对话树:函数

  • 函数必须有且只有一个参数 ctx 这个当前对话上下文环境变量,具体参见下面的内容

在脚本/函数中使用信息项

  • 【获取信息项状态】 使用 ctx["{...}"].state() 获取信息项的状态(这里 {...} 是信息项的名称,下同):
    • 返回值为 -1 : 表示信息项还没有值。对于 “用户输入类” 信息项来说,可能是还未执行到对信息项赋值的节点(“#单次交互#”、“#多轮交互#”、“#动作#执行脚本”等),也可能是 “#动作#清除信息”、“#动作#重新提问” 等节点的效果,也可能是使用下面 “删除信息项的值” 的方法
    • 返回值为 0 : 表示信息项值为 None。对于 “用户输入类” 信息项来说,是执行到了 “#单次交互#” 节点但用户拒绝提供(如用户回复“不清楚”、“不方便说”等),也可能是 “#动作#跳过提问” 节点的效果,也可能是在脚本或函数中直接对信息项赋值 None
    • 返回值为 1 : 表示信息项已有值且不为 None。对于 “用户输入类” 信息项来说,是执行到了 “#单次交互#” 或 “#多轮交互#” 节点且用户提供了有效答案,也可能是在脚本或函数中直接对信息项赋值
  • 【获取信息项的值】 使用 ctx["{...}"].as_str()ctx["{...}"].as_bool()ctx["{...}"].as_num()ctx["{...}"].as_json() 来获取信息项的值(仅使用 ctx["{...}"] 作为右值引用时会报错),信息项状态为 0 或 -1 时都会返回 None信息项的值实际存储时都会是 str 类型,之所以这样是因为从用户话语中抽取的信息(用户输入信息项)不管是什么数据类型先都是文本形式(同时代码定义信息项和系统信息项也采用了同样的存储形式,参见 “信息项”),系统会根据 as_str() / as_bool() / as_num() / as_json() 智能地将值转换为相应的数据类型并返回(其中 as_num()as_bool() 是基于规则进行判断的,如果不放心或已出现问题,可以基于 as_str() 提取值后自行判断)
  • 【对信息项赋值】 使用 ctx["{...}"] = ... 来赋值信息项(但注意这里 = 不能是 +=-=),如果所赋的值是 None 则会存储为 None,否则都会被智能地转换为 str 进行存储(原因同上)
  • 【删除信息项的值】 使用 del ctx["{...}"] 来清除信息项的值,即信息项状态变为 -1
  • 【json 信息项的值】 对于 dict / list 数据类型的信息项,实际使用 json 格式字符串存储(见 “节点 - #单次交互#”“节点 - #多轮交互#” 中的 “json” 信息项修饰),但有如下特殊处理:
    • 使用 ctx["{...}"] = ... 赋值时,如果是 dict 值,则系统会自动在外面将值包成仅有一个成员的 list 值再赋值(因为该类信息项主要用来存储表格信息)
    • 使用 ctx["{...}"].as_json() 引用其值时,最外层也肯定是 list(即使只有一个 list 成员)
    • 从用户输入中抽取该信息项时,如果用户未提供某些字段的内容,则可能是下面的情况之一:
      • 该字段的 key 不存在
      • 该字段的 key 存在,但 value 是空串或表示空的意思的字符串(如 “无”、“没有” 等)
  • 【系统信息项】 上述信息项({...})也可以是系统信息项(即 {_..._}),但不要随意对系统信息项进行赋值或清除,否则可能导致系统错误

其它可用的 ctx 方法和属性

  • 脚本中可以使用 ctx.get_chat_records() 获得作为 list 变量的当前对话记录(第一条是系统输出,最后一条是当前的用户输入),返回值的格式如下:
    [\{"role":"assistant", "content":"..."\}, \{"role":"user", "content":"..."\}, \{"role":"assistant", "content":"..."\}, ..., \{"role":"user", "content":"..."\}]
  • 脚本中可以使用 ctx.get_infoitems()ctx.get_infoitems_before_ask_again() 分别获得当前已赋值的信息项的 dict 变量及被 “#动作#重新提问” 前的信息项的 dict 变量,其中 dict 的 key 是信息项名称
  • 脚本中可以使用 get_offset_date(year_offset, month_offset, day_offset) 来获取当前日期加上偏移后的日期,返回值格式为 “YYYY-MM-DD”,其中 year_offset、month_offset、day_offset 可以为正整数、零和负整数,分别是年、月、日的偏移量
  • 脚本中可以通过 ctx.script_debug_info(s) 来输出调试信息,相关调试信息可以通过在对话测试页面的系统执行轨迹信息中查看(参见 “对话测试”),或通过 “获取执行踪迹” API 接口获取(参见 “API”

其它

  • Xmind 对话树中,脚本中要调用 “#开始#” 节点的 “代码文件” 属性指向的 Python 代码文件中的函数时,须将 ctx 变量作为参数传入,以便代码文件也能像上面一样进行相关处理(Python 对话树中定义相关函数时也必须将 ctx 作为唯一参数)
  • Xmind 对话树中,如果要中途退出 Python 脚本的执行,执行 ctx.exit_script() 即可(该函数在 Python 对话树中不能使用,Python 对话树中直接 return 即可)
  • Xmind 对话树中,所有 Python 脚本(不含代码文件)都已预先 import os, sys, json, datetime, time, math, random, copy, re, requests, urllib 等常用 Python 包,使用包名再带上包内函数名进行调用即可(Python 对话树中自行 import 即可)