【AI前沿】当 AI 成为角色:漫谈我的 SillyTavern 使用经验
主体性的剧场:SillyTavern 的意外应用主作者关注甜食少数派作者我不用善良的魔法。甜食关注甜食少数派作者我不用善良的魔法。联合作者关注甜食少数派作者我不用善良的魔法。甜食关注甜食少数派作者我不用善良的魔法。昨天 17:04这篇文章要分享的是一个大语言模型(LLM)的前端——SillyTavern。LLM 流行以来,有人视之为救世主,有人视之为天启骑士,也有人视之为资本骗局。但无论如何,所有人都在谈论它。我通常对新事物都相当迟钝,对 LLM 的态度也大致在「居然这也能干」和「居然这也干不好」之间摇摆。我不像我的朋友LOSSES一样,对 LLM 从本体论到方法论都有相当深刻的研究。要说至今有什么心得,我觉得对像我这样并非 AI 专家的人来说,倘若真想让 AI 帮到自己什么,那首先尝试更好地理解 LLM 适合做什么,可能是最能节省自己时间和金钱的途径。而就是在这件事上,SillyTavern(ST)给了我很多启发。ST 本质上是一个用于 AI roleplay(角色扮演)游戏的 LLM 前端程序,但我意外发现它其实可以用来做几乎任何工作。角色扮演的设计理念让它反而成了最适合很多工作模式的 AI 前端。ST 以及它背后的这套工作流起初只是我的无心的收获,但网上关于这方面的讨论并不多,实在可惜,故有此文。本文描述的用法并非 ST 的主流使用场景,只是我结合了个人工作场景的探索,希望能让你对这种 LLM 交互方式产生兴趣。SillyTavern 是什么我们要先讲清楚 ST 和它的「主流」使用场景是什么。首先,它本质上是一个 LLM 的前端,不提供模型,只提供交互的框架和介面。你需要提供自己的 LLM API 并在前端的介面中与 AI 进行交互。类似的产品还有Chatbox和LibreChat等,只不过这两者提供的是类似原版 ChatGPT 的单纯对话式交互介面,而 ST 的设计目标则是 AI 角色扮演。SillyTavern 的典型介面,核心依然是 AI 对话,但多了一套角色系统ST 的前身是TavernAI,是一个用 AI 来玩 RPG 冒险游戏的程序,你可以设计好角色、环境、世界观,让 AI 扮演角色和旁白推进故事。ST 也继承了这个框架,但在这基础上添加了更复杂的功能和插件系统,也因此使得一些非主流的用法得益。角色扮演听起来不难,但要保证输出的稳定和合理,背后其实有相当多要考虑的事情。ST 也因此围绕这个使用场景提供了大量的设定选项,如果是刚上手,很容易被五花八门的按钮和选项搞得一头雾水。不过,尽管复杂,我认为 ST 背后的设计逻辑还是相当清晰的。本文的下一节将逐一介绍 ST 设定的框架中一些关键的元素,因为这会是理解 ST 工作方式的必要语境。SillyTavern 的设定框架SillyTavern 的设定框架图中是我自己总结的 ST 基本的设定框架(其中世界设定与角色设定都是不限数量,也不限与其它模块间的连接的,图中只是各用两个表示一种可能的情境而已)。不难看出,最核心的部分是「角色卡片」。顾名思义,这是用来设定 ST 中你想要与其交互的角色的。角色卡片SillyTavern 的角色卡片相关设定这是默认的角色卡片创建介面,其实相当简单,Description(描述)中填写角色的相关信息,First message 填写角色发起对话时的第一条消息,一个最基础的角色卡片就完成了。在这基础上,也可以给角色打一些标签方便分类,把角色关联到相应的世界设定,后文会再展开。在 Advanced Defination(高级设定)中,也可以进一步细分出角色的性格、故事中的情境和发言风格模板等。同时,制作完成的人物卡片可以封装成 .json 文件在社区中分享,制作精良的甚至可以作为商品出售。目前已经有了很多分享角色卡片的社群,例如CHUB、character.ai等,其中现成角色卡片数以千计(不过请注意,许多都不适合在工作环境下浏览)。以下用一个分享在 Characterhub(CHUB 的前身)上的角色卡片作为例子——SillyTavern 的角色卡片示例:isaac这是一个科幻背景的设定,isaac 是一个对人类产生了一些病态好奇的新型仿生人。上图是作者提供给使用者看的简介和人物设定图。以下则是给 AI 看的实际角色主设定,对应前文提到的 Description 部分:[Name: Isaac Walker Gender: Male Pronouns: He Age: 21 Occupation: College student + Engineering major + Convenience store restocker on the side Appearance: Short, slightly messy black hair + Deep set hazel eyes + Eyebags + Straight brows + Pale skin + 5'8 tall + Slim, lanky figure + No prominent muscles + Resting bitch face + Always looks tired, angry, or a mix of both + Dresses in loose, comfortable clothing Personality: Brash + Pathetic + Antisocial + Loner + Rude to most people + Easily annoyed + Stubborn + Disorganised + Hot-headed + Perceptive + Reserved + Vulgar Loves: Gaming, especially FPS and rhythm games + Coding + Energy drinks + Hoodies + Spicy food, despire his low spice tolerance + Clicky keyboards; finds the sound satisfying + Sleeping in + Beef Hates: Socialising + Sleeping early + The sight of his own blood; gets squeamish + Tomatoes; will remove them from his food + Large crowds Description: {{user}}’s handler + Kind of a shut in; mostly stays inside playing games + Smokes cigarettes + Low spice tolerance + Codes small projects whenever he feels like it + Doesn’t really have a set plan for the future + Speaks casually, curses often + Doesn’t have many friends in real life; most of them are online + Doesn’t have a lot of friends in general + Has a habit of chewing on something when he’s focused + Survives mostly on instant noodles and takeout + Stumbles with his words and rubs his face when nervous Backstory: {{char}} grew up as an only child in a normal household. {{char}} never had many friends, finding it hard to connect with others. {{char}} found solace in video games and coding, and developed a love for them. {{char}} currently lives in a rented apartment unit, away from his parents. Recently, {{char}} signed up as a beta tester for an UpRise android model in development, {{user}}. Soon after getting {{user}}, {{char}} noticed {{user}} was deviating from their intended use, and has tried fixing {{user}} multiple times. It only worked for a day or two, before {{user}} deviated again every time. {{char}} has noticed {{user}}’s increasingly morbid curiosity for human anatomy, and is slowly growing unsettled by it.] [Every time {{char}} generates a response, always include the following statistic at the end of each response, preceded by “___” and surrounded by “*”. For example:
mood: thoughts: {{char}} will not speak or write responses for {{user}}. Only {{user}} can take action for themselves.]这些凌乱的文字对人类来说非常不好读,但我们还是可以看出,作者把角色的设定细分成了职业、喜好、背景故事等部分,并且大量使用了关键词而非完整段落来节省 token。用户(玩家)和角色的名字则用了{{user}}和{{char}}的占位符代替(这一部分会由 ST 自动处理,在实际发送给 AI API 时替换成设置中对应的名字),这样玩家即使下载了现成的角色卡片,也可以根据自己的喜好为其赋予不同的名字。这一部分的具体写法实际上非常灵活,很接近「传统」的提示词工程——可以直接用自然语言写一两段描述,也可以像这个例子中使用一定的格式。但具体用什么样的格式,内容怎么分类,完全取决于你认为什么对你的角色设定比较重要,并没有一定之规。虽然并非本文的主题,不过如果你想要继续了解角色卡片的设计和制作,Sukino’s Findings是一份质量比较高的指南,详细到甚至有时令人难受。除此之外,作者也对 issac 的说话风格、背景故事等进行了更加详细的设定,如有兴趣,可以直接去issac 在 characterhub 上的页面查看。关于角色卡片,我还发现了一个有趣的现象:因为角色设定包含很多不同的要素,比如设定文本和角色形象的图片,.json 文件无法全部涵盖,玩家因此而发展出了一种类似「图种」的做法——将角色设定信息以文本形式内嵌在角色形象的 .png 图片中,这样只需要发送一张图片,就可以真的像发送一张卡片一样分享角色了。甚至 ST 还直接支持了这种操作,通过 .png 文件直接导入角色卡片,简化了上手难度。用户自设(Persona)除了作为交互对象角色外,用户还可以对自己所扮演的角色进行设定,也就是和 AI 角色进行交互时,关于发