角色卡导入规范
SillyTavern 角色卡可以是带有 ccv3 或 chara 数据块的 PNG,也可以是 JSON。系统支持 V2 和 V3,并先把 V2 规范化为 V3。导入会创建新世界并写成原生世界文件;如果结果暂时还不能开始故事,已有工作会保留为可修复的草稿,而不是丢失。
流程
- 在世界页选择导入。主机读取角色卡,代码位于
host/import/card.ts。文件上限由importMaxUploadBytes控制,默认 100 MB。上传内容暂存在导入目录,并显示其中的信息。 - 选择导入器收到的内容:世界名称、需要关闭的 lorebook 条目,以及作为开场的一个问候语。关闭的条目不会继续传递;开场可选第一条消息或一个备选问候。
- 开始导入。系统创建世界,把上传内容移入
.import/,创建创作对话,并代表用户发送/import-st .import/card.json ...。创作智能体通过agent/pre-step识别命令,收到专用流程而非普通请求,导入完成前不能结束该回合。 - 导入包含三个工具。每次调用都由专注于一项小任务的
runChild执行,最多按importConcurrency并发运行:import_survey逐项列出字段、开场和 lorebook 条目。长条目按段落或句子边界截分。每项会被分类为角色、玩家、说话方式、地点、阵营、物品、世界、场景、指令、生成指引、模板或无关内容,并标出涉及的命名事物。最后通过一次模型调用合并角色、地点、阵营和物品名册;确定性回退会合并名称包含关系。import_build从与实体有关的片段中为每个实体提取一份文档,并把背景片段转成设定条目。文档使用世界本身的解析器检查,不合法时带原因退回,直到通过。import_finish暂存全部内容,把描述、标签、开场、封面及原生文件写入世界,再用开始会话时的同一套验证检查完整世界。同一回合会使用创作工具复查地点、通路、起始地点和重复项,在不逐项询问的情况下修正窄任务看不到的问题;如果问题仍在,文件会保留为草稿,助手继续修复。.import/state.json中的reviewing会在该回合结束前临时解除批准门槛。
.import/state.json保存ready、surveyed、built、repair、done五个阶段。中断后会从已有阶段恢复,每一步都拒绝越序执行。
窄任务统一使用插件级的导入与创作助手设置。它们可以使用与创作对话不同的模型和推理等级,按受限并发运行,并在超过 importTimeoutMinutes 后停止,而不会无限占住导入。importMaxTokens 是上限:分类、名册、实体、设定、风格和翻译任务只申请其结果所需的较小预算。助手若用散文耗尽预算却不调用结果工具,会被立即停止;重试同一个被截断的回答只会再次浪费相同预算。import_build 在一个创作回合中最多运行两次,避免模型反复重建一个无法收敛的导入。
设计决定
- 条目在卡片中的位置,以及它是常量还是按键触发,无法可靠说明其语义。lorebook 可能保存世界背景、单个角色的提醒或完整定义,因此每个片段都按内容判断,lorebook 不会原样导入。
- 当
importDecisions为decision时,已配置的决策服务会先判断片段是否只是给 AI 的指令,或与故事无关的读者说明。达到importConfidence的结果无需再由语言模型分类;没有把握或服务失败时照常回退到语言模型,调查结果会报告直接判定的数量和回退问题。可能描述故事的片段不会只凭决策模型丢弃。 - 追踪数值由
extractVariables分组读取。面板、格式和状态规范会被切成每组最多 6 000 字符,再逐组处理。- 一次请求最多声明
importVariablesPerRequest个数值(默认 25)。填满时会再次询问,并告诉模型已经声明了哪些 key。同一个 key 以第一次声明为准,世界追踪的数量没有上限。 - 无法使用的声明(只有一个选项的选择型、不递增的分段)会连同原因被舍去,不会连累同一次回答里的其余部分。
- 受约束的回复如果在长列表中途撞到输出上限,会在最后一个完整条目之后收尾,下一轮再询问其余的。
- 把全部文字放进一个请求,会让模型一直写到上限也不作答(在一张变量规则很长的卡上实际遇到),所有变量都会丢失。
- 助手的单次请求最多输出
importMaxTokens。默认值 0 表示模型上下文窗口的十分之一(至少 16 000),每个任务还会为模型习惯先写的分析留出额外空间。
- 一次请求最多声明
- 角色任务通过
carries返回开场时随身携带的物品,沿用卡片中的名称,最多 12 个。名册中还没有的名称会成为由该角色持有的物品,并通过held_by关联。角色只是知道、但没有持有的物品仍写在knows。 - 生成人物的段落会变成世界机制(
host/import/casting.ts,提示词import/casting)。导入器会把这些段落放在一起重读,再据此写出指令和触发器:commands.json记录卡片提到的斜杠词。没有任何触发器使用的指令不会保留。triggers.json增加一些条目,其效果是让世界作者生成人物的节拍(dispatch: author、need,以及来自卡片列表的抽取选项draw)。- 触发器由指令的标记启动,或由一条用过去时写的、描述某个事件的陈述启动,这条陈述由模型判断(由
decisions.triggers决定谁来判断)。 - 没有任何启动条件的机制会被舍去,并留下说明。
- 不使用模型的导入由
host/import/structure.ts、run-import.ts中的structureImport和POST /worlds/import/structure?id=完成。代码直接整理卡片,不让模型读取内容:- 卡片自己的角色来自描述、性格和对话示例(
characterDocument)。 - 每个世界书片段原文成为只有游戏主持人可读的设定(
asWritten)。 - 系统提示词与历史后指令成为
roleplay/style,其中的${和{{会变为无效标记。 - 仍由同一个
finishImport写入世界。世界的描述和标签取自卡片自己的字段(ctx.noModel)。 - 导入以
done结束;世界还无法开始时为repair;并写入provenance.json。没有对话,也没有审阅。
- 卡片自己的角色来自描述、性格和对话示例(
- 创作检查和导入来源会随文件一起记录。
- 每次创作写入(元素、关系、剧情线、触发器、世界信息)都会在结果旁返回整个世界在能开始故事之前还缺什么:结果中的
check_world是ok,或最多八个未解决的问题及其余数量。这只是提示,不是拒绝,因为写到一半的世界是正常的中间状态。 .import/provenance.json(schema: dsh-roleplay-import/v1)每次导入或更新记一行:时间、卡片名称、所读卡片的 SHA-256、语言,导入还记录数量和说明条数。其他 schema 的文件会被拒绝,不会被改写。
- 每次创作写入(元素、关系、剧情线、触发器、世界信息)都会在结果旁返回整个世界在能开始故事之前还缺什么:结果中的
- 常驻规则和生成指引来自
extractEntities与提示词import/generator。每个有实质内容的片段只问一个问题,返回两个列表。段落必须原样复制,并与来源核对。- casting 是游玩中如何凭空生成人物、地点或物品,成为只有游戏主持人可读的设定(“人物如何生成”)。
- rules 是游戏主持人要遵守的常驻规则与机制:检定、战斗步骤、表格、状态如何记录。来自卡片始终发送的世界书条目(
constant)的 rules 会合并成世界的提示词roleplay/standing,游戏主持人每回合都会带上它(最多 12 000 字符,${和{{变为无效标记)。其余的以及放不下的部分,成为只有游戏主持人可读的设定(“规则与机制”)。 - 分类之前,分类器会看到整张卡的片段目录,以及区分相近角色的示例。
- 包含玩家标记的名字会被当作用玩家称呼替换后的名字,不再被拒绝。
- 每个片段里的 EJS 控制代码会被去掉,分支文字保留。
- 提到变量更新工具的片段(
stat_data、[mvu_、<UpdateVariable>、JSON Patch)一定会交给追踪数值这一步。 - 只在别的内容的片段里被提到一次的名字,不会成为实体。
- 草稿修复由
host/import/draft.ts、run-import.ts和worlds/world-check.ts实现。import_finish先修补代码能确定的问题:悬空的阵营成员、关系、已知地点、父地点、通路和起始地点会被丢弃,并各留下说明。- 随后即使
checkWorld(开始存档时运行的校验)仍发现问 题,也会写入世界。导入状态变为repair,结果带有draft,WorldSummary.draft标记卡片。 - 助手被要求用
check_world和原始角色卡修复。当一个可能改动世界的回合要结束而世界仍然无法开始时,导入钩子会把它送回去(import/repair-again,最多 5 次)。 - 问题仍在时
endReview让状态停在repair;checkWorld通过后,settleDraft把世界变回普通世界。 GET /worlds/import/draft?id=返回状态和问题。POST的action为ask(再次发送导入指令,回合在解除审批的状态下运行,startRepair)、keep(keepDraft)或discard(文件夹移到<root>/.trash/worlds)。- 文件通过
atomicWrite(host/atomic-write.ts)写入,world.json的改动通过updateWorldFile,按世界串行执行。
- 导入中断时,卡片和已提取的内容仍保留在
.import/中。服务器重启、完成步骤被拒绝或对话提前结束都可以继续。POST /roleplay-api/worlds/import/resume?id=<世界 id>会把导入指令重新发给该世界的对话,导入钩子从保存的阶段接着运行。没有等待中的导入时,接口返回 422。 - 凭空生成人物的指引使用
generator角色,包括类型和情境池、模板、表格、档案必填字段,以及引入人物的时机。它会原样保存为类型custom、范围listed的设定。游戏主持人和世界作者可以读取,角色不能读取。设定任务不会改写它,isGeneratorOnly也会阻止它向名册提供名称;同时包含其他内容的 片段会保留两部分。游玩时,游戏主持人在场景可能出现新人时读取这些设定,再调用expand_world。世界作者会搜索并遵循这些设定。没有固定角色的卡会成为一个没有角色的世界,开始存档时需要带上角色形象。 - AI 指令只保留一部分。
import_build的import/style任务读取系统提示词、历史后指令和被分类为指令的片段,只留下故事写法和角色行为方面的要求,例如声音、语气、视角、保持角色身份和角色如何拒绝。这些内容写入世界的roleplay/style与roleplay/character-style,并由import_finish为每种随附语言写入prompts/<language>/roleplay/。卡片原文不随界面语言改变。游戏规则、格式、状态面板、脚本和特定实体说明不会保留,报告会注明被排除的内容。文本过长或使用任务未提供的占位符时会被拒绝,并在报告中说明;导入仍会继续。 host/import/pictures.ts处理卡片引用的图片。系统扫描卡片中的所有字符串,包括脚本和扩展,收集到NormalizedCard.urls。指向 PNG、JPEG、WebP、GIF 或没有扩展名的网页地址,会从导入第一步开始在后台下载,并记录在导入目录的pictures.json中。import_finish等待该任务结束。图片作为用户上传的可复用图片写入世界的images/library/,开始会话时复制过去,等待会话的图片解释器补充描述。下载失败不会阻止导入。- 图片下载只允许无凭据的 HTTP/HTTPS,端口限于 80 和 443。字面私有地址会被拒绝;建立连接时解析名称,只要任一结果属于回环、私有、链路本地、共享、组播、保留地址或嵌入地址的 IPv6 形式,就会拒绝。最多跟随四次重定向,每次都重新检查, 不使用代理。系统先发送 HEAD,排除 404、410 或明确声明为非图片的响应;拒绝 HEAD 或未声明类型时仍尝试下载。下载上限 20 MB,并设有超时。最终忽略声明类型,只在文件头属于支持的图片格式、文件至少 1 KB 且不是该卡片其他图片、也不是图库中已有图片的副本时保留(用
pictureHash比较:PNG 去掉文本、时间和 EXIF 块后的内容,所以写入已保存文件的元数据不会掩盖副本)。尝试地址数量不设上限,最多八个并发。 import_build的import/variables任务读取卡片的面板、格式和指令,从中声明需要跟踪的值,包括有限制和分段的数字、标志和选项。情绪已有内建结构,不会声明为变量。结果写入variables.json,并通过variableProblems使用世界的规则验证。键为带下划线的小写 ASCII;限制到角色、地点或物品的名称会转换成相应键。不会提取各实体初值,而使用默认值。失败只记入报告,不中止导入。- 角色之间与对世界的了解。 角色的
knows(名单中的地点、物品和两个地点之间的路线)会成为其文件中的knowledge(locations、items、exits),并裁剪到实际写出的内容以及地点确实存在的路线(pruneKnowledge);关于某个角色的设定条目会加入该角色所知,被他人关系提到的角色若自己没有对应关系,会得到一条普通的acquaintance关系(completeAwareness),因为在封闭世界里缺少边就意味着不知道对方存在。 - 叙述预设。 SillyTavern 的提示预设可以应用到已有的世界:世界页的导入叙述预设把它上传到
<world>/.import/preset.json(POST /worlds/import/preset),世界的编辑对话被请求调用import_preset,同一个import/style任务按预设的顺序把启用的提示(readPreset同时读取提示列表布局和旧的固定键)转成世界的散文提示词。调用前会先询问用户,因为它会替换世界自己的版本。同一个任务也用于填充资料库中的预设:见提示词系统规范中的预设(import_narration_preset、POST /presets/import)。在对话框中勾选不使用助手可跳过转换:不会运行模型,也不会再询问,勾选的提示会原文成为世界的叙述风格(每种出厂语言的roleplay/style),预设的采样设置也会写入世界。世界原有的风格会先移到世界的.trash。 - **世界书。**SillyTavern 世界书(带
entries的导出文件,或角色卡的character_book)会导入世界书资料库,而不是某个世界:POST /roleplay-api/lorebooks/import?name=&language=会预留一个空的资料库条目,把文件保存在其.import/lorebook.json,打开该世界书的创作聊天并让它调用import_lorebook。关闭的或为空的条目会被丢弃,该工具的宏会被替换。一个窄任务(import/lorebook)对每批至多八个条目(受文本预算限制)判断每个条目是什么:知识(原文保留;模型给出标题、类型、一句话摘要,以及适用范围——只有条目明确说明谁知道时才带known_by,否则为everyone)、指令(给 AI 的指令,被改写为面向某个目标提示词的简短指引:style、character-style、persona、game-master 或 character-rules)或略去。每个条目都必须有决定,否则答案会被拒绝;一批始终得不到可用答案时整个导入失败,因此不会写入做到一半的东西。知识成为书中的条目(条目的关键词放进摘要);指令保存在.import/steering.json。随后apply_steering会创建一个新的资料库预设,其中每个目标提示词保留内置文字,并在每种内置语言里把指引追加在后面;它先征求用户同意,目标不是叙述类提示词时带有警告。类型为sillytavern/lorebook的目录条目走同一条路径(POST /roleplay-api/catalogue/convert/lorebook)。 - 第一条消息和未被选作开场的其他问候会写入
alternate_openings,供开始对话时选择。系统会像处理选中开场一样清理玩家标记和卡片标记语法。 - 卡片图片也会成为与卡片同名角色的规范参考肖像;若世界只有一个角色,则归给该角色。图片带有用户提供来源的元数据。
- 卡片未提供玩家角色时,系统不会自动创建。没有可扮演角色的世界会在编辑器中显示警告,添加角色前不能开始。
- 卡片文本中的
{{user}}会变为供模型使用的[PLAYER],最后再替换成玩家角色或普通称呼。{{char}}表示卡片自身名称。 - 任意文字系统中的名称都可生成 ID。文件夹名、ID 和图片路径接受各种语言的字母与数字,但不接受分隔符和点路径段。
- 一张卡片可包含多个角色,由名册决定具体角色。
- 卡片版权属于其作者。测试只使用
tests/support/cards.ts中虚构的卡片,不使用真实卡片内容。 - 卡会保留。 导入之后
.import/不会被删除,该世界的创作聊天拥有只读工具:card_overview(每个字段、问候语和世界书条目及其大小、勘察认定它是什么、由它生成了哪些实体,还有名册和报告中的说明)、card_search(先按短语、再按词匹配,任何文字都可以,返回片段)、card_read(原文返回一段,每次 6000 字符)和card_origin(某个实体是由哪些段落生成的,用与构建相同的sourcesFor重新计算;对导入没有生成任何内容的名字,则列出提到它的段落)。它们与.import/card.json同在,所以删除该文件夹就会关闭它们。流程提示词要求助手去查卡、把世界文件当作设定而把卡当作依据,并对照原文核实导入记录。插件导出或翻译的内容都不会带上这张卡(翻译会跳过.import,也没有其他导出);同步会随世界一起带走它。游玩过程接触不到它。 - 卡片带来了什么,以及它们变成了什么(
dialect.ts、outcomes.ts、job-cache.ts)。dialectOf读出制作角色卡的工具所用的机制,但不执行其中任何一项:正则表达式脚本和辅助脚本(读卡时计数,NormalizedCard.ignored.regexScripts与helperScripts)、玩家和角色名之外的{{宏}}名称,以及不属于普通标记的标签块。审阅页(ImportPreview.dialect)、开始导入的消息(sourceSummary:来源格式、条目与开场数量、哪些内容不会带入)和ImportReport.leftOut.dialect都会说明。pieceOutcomes根据导入记录给卡片的每个片段一个结果:carried(原文带入,如开场)、converted(由它生成了角色、地点或物品)、guidance(给叙述者的指示)、read(为世界读过,但没有产生具名内容)、omitted(备注、格式、用户去掉的片段)或awaiting(导入尚未处理到它)。card_overview返回每个片段的结果和总数,ImportReport.pieces保存总数。每个任务的答案以其指令、问题与答案格式的哈希为键保存在.import/jobs/,因此失败或中断后重新运行构建时,只会重新请求未完成的任务;新的勘察和完成的导入会清空它。 - 按新版角色卡更新世界(
host/import/update.ts、update-tools.ts、card-diff.ts、snapshot.ts)。查看角色卡时(ImportPreview.targets,来自findTargets)会列出每个.import/card.json存在且导入已完成的世界,名称与卡相同的排在前面(sameName);edited把世界文件与.import/files.json比较,这个文件是导入回合结束时(endReview)写下的 SHA-256 快照(不含images/和顶层以点开头的条目),没有快照则为unknown。世界自己的页面通过同一个查看页面提供更新(GET /worlds/import/update?id=说明这个世界是否由角色卡导入、是否有更新在等待、上一次更新能否撤销)。POST /worlds/import/start和/catalogue/convert/staged接受update: <世界 id>;startUpdate把世界的文件(不含images/和点开头的条目)与导入的记录保存到.import/before-update/,把上传的卡移入.import/update/,打开创作对话并发送updateMessage——这只是一条普通请求,不是特殊回合,所以每项修改都像其他修改一样需要批准(authoringApproval同样适用);updateHooks在更新回合停下而更新仍在等待时把它送回一次(实测有模型在一项找不到去处的改动上结束了回合),第二次停下则放行,这样向用户提问也能结束回合。card_diff(只读)对两张卡的片段配对(matchPieces:字段按 id;条目先按标题和关键词,再按文字,最后在编号相同且共有一半词时配对),按句子对比有变化的片段(diffText,最多 1500 句),并加上旧片段生成的实体(entitiesByPiece,来自导入的记录;被删去的片段还会给出只由它生成的实体,madeOnlyFromIt)、卡对世界本身的改动(worldFieldChanges:简介、标签、作者、开场、其他开场)、卡片自带图片和图片地址是否变化(pictureChange、addressChanges),以及导入之后被修改的文件。撤销更新不会动图片。助手用edit_world_info处理这些改动(它修改WORLD_INFO_FIELDS里的world.json字段,像其他修改一样需要批准,并拒绝名称、预设、世界书、采样和工具开关),并移除只由被删去的片段生成、且用户没有改过的内容。card_read和card_search接受version: new。card_update_finish把旧卡、旧选择和旧图片保存到.import/previous,写入新的,把classification.json转到新的片段 id 并忘记被删去的片段,获取旧卡没有的图片地址,以及已保存的pictures.json显示因可能已经消失的原因而失败的地址(addressesToFetch、worthAskingAgain;没有记录时,旧卡的地址一律视为已处理),把结果合并进pictures.json(mergeReports),列出地址已被新卡删去但已获取的图片(droppedFromTheCard,仍留在图库),把仍是卡自带图片的头像(来源为uploaded、原文件名为picture.png的参考图)换成新图片,并重新拍下快照。DELETE /worlds/import/update?id=(revertUpdate)把保存的文件和记录放回去,世界当前的内容移到.trash/update-<时间>。编辑器的默认选项是:同名世界且edited: no时更新,否则新建世界;世界保留名称;目录中的发布版本会把新版本记为世界的来源。
检查套件
host/checks/ 把所有“世界对不对”的检查放进一个套件,按检查包组织(shared/checks.ts:consistency、fidelity、quality、playability)。面向用户的说明见检查世界。
- 统一的约定。 一项检查是
{ id, kit, mode, needs, description, run(input) }(check.ts),返回发现:severity(error、warning、info)、code、where、message,以及可选的hint。mode为code(由程序判定)、judged(模型阅读程序收集的依据)或decision(决策模型可以回答的是非题)。needs是card和/或model。无法在某个世界上运行的检查会抛出CheckSkipped,报告里会连同原因把它列为跳过,而不是算作没问题。runChecks(run.ts)运行被要求的检查包;不是code的检查只在deep时运行(deep: 'decision'还会运行decision类),否则列为跳过。一次运行把世界的每一部分只读一遍,供它所有的检查共用(loaded.ts,即该次运行输入里的memo)。 - 一致性(
consistency.ts)包装checkWorld(开始故事时的校验)、对由世界文件生成的临时故事运行的lintWorld(worlds/scratch.ts,与触发器检查共用)、对同样对象含义相同的追踪数值(duplicateValues,带一个小的同义词表)、别名和名称冲突,世界自带的提示词(把copyWorldPrompts复制到临时文件夹),以及没有解析器读取的字段(unread-fields:Reader.unreadBy运行每种实体真正的解析器,返回它从未看过的键,因此不需要另外维护一份字段清单)。 - 对照(
fidelity.ts、card-evidence.ts)基于CardEvidence:世界所依据的角色卡,或者等待更新它的新卡,同时带上导入记录所对应的旧卡。madeInto说明每个片段变成了世界的哪些部分:角色、地点等实体按导入的名册和分类(originOf)确定,背景条目和world.json按它们的词项在片段中所占比例确定(terms.ts;背景条目自己不记录来源)。代码检查包括:导入读取过的片段的覆盖情况、名字能否在卡里找到、数字是否保留,以及有新卡时世界尚未写到的改动(matchPieces、diffText)。由模型判断的card-fidelity对每份文档询问丢失和编造的事实,每条都附一段必须出现在其来源文本里的引文(comparisonProblem),至多 40 份文档,每份每类至多六条。 - 质量(
quality.ts)有三个代码检查(角色阵容、地点、世界对自身的说明)、sheet-playable(决策:决策模型有把握时经verdictOf由导入的决策模型回答,否则由语言模型回答)和world-gaps(对世界概要由模型判断;每个缺口必须指明概要里的某个 key 或世界)。 - 可玩性(
playability.ts)看每个可扮演角色的第一场景:first-scene(代码:起始地点、出路、同伴或物品)和opening-playable(决策:开场白与该场景,经verdictOf)。 - 判断复用导入的运行器。 由模型判断的检查拿到的是调用它的工具的
ImportContext(contextOf),因此聊天所用的模型、importReasoning、importTemperature、token 上限、超时、并发数和importDecisions都照样生效,不需要新增任何配置。 - 按含义查找(
similar.ts、semantic.ts)。ImportContext.embed用所选的嵌入提供方做嵌入(没有提供方时以NoEmbeddingService拒绝)。candidates返回检查自己的过滤条件允许的、最接近的配对,余弦阈值故意设得很低、至多 12 对,因为接近只用来挑出要问什么,不决定任何事。duplicate-values-meaning、name-near(也按嵌套名称)和lore-conflict(日期不相交的条目不会配对)是基于这些配对的decision检查:先走verdictOf;lore-conflict之后再让语言模型给出结论,并要求引用两个条目各自的原文,引文必须能在条目里找到(conflictProblem)。card-coverage仍是code检查,但运行带模型时,会先对每个未被覆盖的片段询问最接近的几份文档,再报告它。向量按文本哈希保存在<world>/.checks/vectors.json(float32、base64,保留最新 4000 条),模型或维度变化时会丢弃。助手的create_world_element和replace_world_element传入refuseUnread,用Reader.unreadBy拒绝没有任何解析器会读的字段。 - 结果按检查分别保存在
<world>/.checks/results.json(results.ts);每次运行会对照这次运行的检查上次保存的结果,说明多少条是新的、哪些已经消失。与.import一样,点开头的文件夹从不属于已发布的世界或翻译。 - 工具与命令。
check_world、check_card(带version)、check_quality、check_play(都带deep)和check_list是世界创作聊天的工具(tools.ts)。命令/check、/check-all、/check-world、/check-card、/check-quality和/check-play由同一个解析器读取(shared/authoring-commands.ts,/import-st也用它);hooks.ts在这个回合的第一步加入通知checks/notice。 - 在导入流程中。
finish、structureImport和card_update_finish通过checkImported运行所有由程序判定的检查并保存结果(导入带有决策模型时,decision类检查也会运行);import_finish和card_update_finish把发现作为checks返回。审阅提示词要求助手依据它们行动,并在卡片或发现需要时运行 deep 检查。更新消息要求助手在结束之前用version: new运行check_card。