8.4 KiB
角色功能如何使用
什么是角色
角色系统是 CapsWriter-Offline 的 LLM (大语言模型) 后处理功能,可以调用 LLM 的 API 对识别结果进行润色,或当作语音助手进行对话。
你可以定义多个「角色」,每个角色有自己的提示词、模型、输出方式。语音识别完成后,通过前缀匹配触发对应角色进行处理。
角色有两种输出方式:
- 打字输出,可用作润色
- Toast 弹窗输出,可用作语音助手
比如你用鼠标选中一段文字,然后说:
翻译这段文字
客户端检测到"翻译"前缀,自动调用对应的 LLM 角色,复制所选文字,调用 LLM API,返回的结果会以 Toast 弹窗显示。
使用角色前,需要编辑角色文件,配置 LLM API,可以用在线服务如 DeepSeek,也可以用本地模型如 LM Studio 或 Ollama。
一、角色文件在哪
角色文件存放在项目根目录的 [LLM/](../LLM/) 文件夹中,每个 .py` 文件定义一个角色。系统启动时会自动加载该目录下所有角色文件,修改后自动热重载(3 秒防抖)。
内置角色
| 文件名 | 触发前缀 | 输出模式 | 用途 |
|---|---|---|---|
| `default.py | (默认) | typing | 默认角色,用于润色,已经关闭 |
| `翻译.py | 翻译 | toast | 翻译选中文字 |
| `小助理.py | 小助理 | toast | 问答助手 |
二、角色文件格式
角色文件是普通的 Python 文件,通过定义顶层变量来配置角色。以下是一个完整示例:
# ===== 基本信息 =====
name = '翻译 | translate' # 角色名称,| 分隔多个触发前缀
match = True # 是否启用前缀匹配
process = True # 匹配到后是否处理
# ===== API 配置 =====
provider = 'lmstudio' # API 提供商:'lmstudio', 'ollama', 'openai', 'deepseek', 'moonshot', 'zhipu', 'claude', 'gemini'
api_url = '' # 留空则自动使用 provider 对应的默认值
api_key = '' # API Key
model = 'local-model' # 模型名称
# ===== 上下文管理 =====
max_context_length = 4096 # 最大上下文长度(token)
# ===== 功能开关 =====
enable_hotwords = True # 是否将热词列表放入上下文
enable_history = True # 是否保留对话历史
enable_read_selection = True # 是否读取选中文字(模拟 Ctrl+C)
selection_max_length = 1024 # 选中文字最大长度
# ===== 输出配置 =====
output_mode = 'toast' # 'typing' 直接打字 | 'toast' 弹窗
# ===== Toast 外观(仅 toast 模式) =====
toast_font_size = 23
toast_font_color = 'white'
toast_bg_color = '#075077'
toast_duration = 3000 # 显示时长(毫秒)
# ===== 生成参数 =====
temperature = 0.7
top_p = 0.9
max_tokens = 4096
# ===== 提示词定制 =====
prompt_prefix_hotwords = '热词列表:'
prompt_prefix_selection = '选中文字:'
prompt_prefix_input = '用户输入:'
# ===== System Prompt(核心!) =====
system_prompt = '''
你是一个翻译助手。将用户输入的内容翻译成中文。
如果输入是中文,就翻译成英文。
只输出翻译结果,不要解释。
'''
三、核心字段说明
name
- 触发前缀,语音识别结果以此开头时触发该角色
- 支持
|分隔多个别名,如'翻译 | translate' - 留空表示默认角色
process
True:走 LLM 处理False:不使用 LLM,直接输出原始文本(如默认角色)
output_mode
'typing':模拟键盘逐字打字输出,用于润色'toast':在 Toast 浮动窗口中显示(支持 Markdown 渲染),适合翻译、问答等
provider
支持的服务商:
| provider | 说明 | 默认 API 地址 |
|---|---|---|
ollama |
本地 Ollama | http://localhost:11434/v1 |
lmstudio |
本地 LM Studio | http://localhost:1234/v1 |
openai |
OpenAI | https://api.openai.com/v1 |
deepseek |
DeepSeek | https://api.deepseek.com |
moonshot |
月之暗面 | https://api.moonshot.cn/v1 |
zhipu |
智谱 AI | https://open.bigmodel.cn/api/paas/v4 |
四、如何创建新角色
- 在
LLM/目录下新建一个.py文件,文件名建议用中文(如代码助手.py) - 按照上面的格式定义变量
- 保存文件,自动加载,无需重启
或者直接从已有角色文件复制一份新的,然后修改即可。
其实无需使用多个角色,作者个人只有两个角色:
- 小助理,是用的本地 LM Studio 加载的 Gemma4-E4B 模型,翻译、问答都能做
- 大助理,是用的 DeepSeek 的 API
五、触发机制详述
检测流程:
语音识别结果 → 角色检测器
↓
遍历所有角色
↓
检查 text 是否以 role.names 之一开头
├─ 匹配成功 → 去掉前缀和分隔符 → 交给该角色处理
└─ 全部不匹配 → 检查 default.process
├─ True → 交给默认角色处理
└─ False → 不调用 LLM,直接输出
分隔符清除:匹配到前缀后,自动去掉紧跟的 :、,。,. 等字符。
六、输出模式说明
Typing 模式('typing')
- 边生成边模拟键盘打字
- 如果
config_client.py中paste = True,则先完整生成再通过剪贴板粘贴 - 按
Esc可中断输出(由llm_stop_key配置)
Toast 模式('toast')
- 在屏幕上的浮动窗口中显示
- 支持 Markdown 渲染(标题、代码块、列表等)
- 可自定义字体、颜色、背景、显示时长
- 鼠标可左键拖拽,右键复制内容,鼠标离开 3 秒后自动关闭
- 键盘 ESC 可手动关闭
七、上下文构成
当角色启用相关功能时,LLM 接收到的消息结构如下:
System: (角色的 system_prompt)
(对话历史,多轮问答记录)
热词列表:[Claude, CapsWriter, ...] ← enable_hotwords
选中文字:被选中的文本内容 ← enable_read_selection
用户输入:用户本次语音输入的内容 ← prompt_prefix_input
八、配置项
在 `config_client.py 中:
paste = False # 是否用粘贴代替打字输出
restore_clip = True # 粘贴后是否恢复剪贴板
paste_apps = ['WeXin.exe', 'Telegram.exe'] # 强制使用粘贴的应用
llm_enabled = True # LLM 总开关
llm_stop_key = 'esc' # 中断输出的快捷键
九、实用技巧
1. 开启润色
如果你希望所有语音都经过 LLM 润色,将 default.py 中的 process = False 改为 process = True。
其实,Qwen3-ASR 已经非常强大,加上热词功能,已经完全不需要 LLM 润色功能。毕竟 LLM 处理会增加延迟,降低体验。
在作者的 RTX5050 独显笔记本上,Qwen3-ASR 的短音频延迟最短只有 110ms,体感上是瞬出,识别率又非常好。如果开启润色,每次输出都加上 0.3s 的延迟,体感上就会慢一拍。
只不过 Typeless 有润色,LLM 又这么火,总会有朋友想试试。作者自己试用了 Typeless,表示延迟太大,体验不合格。
2. 多别名触发
name = '翻译 | translate'
3. 角色特定热词
如果某个角色 enable_hotwords = True,客户端会将 RAG 检索到的潜在热词列表放入 LLM 上下文,帮助 LLM 理解专业术语。
4. 结合选中文字
对于翻译、改写等场景,设置 enable_read_selection = True,先选中文字再语音说出指令,LLM 可以同时拿到选中内容和语音输入。
十、常见问题
Q: 修改角色文件后需要重启吗?
不需要。系统会自动检测 LLM/ 目录变化,3 秒内自动重载。
Q: 为什么说了前缀但没有触发角色?
检查以下几点:
config_client.py中llm_enabled = True- 角色文件中
process = True且match = True - 前缀是否完全匹配(区分中英文)
- 查看日志
logs/client_latest.log中的角色检测信息
Q: 如何暂时禁用一个角色?
将角色文件中的 process = False 或将 match = False,保存后自动生效。
Q: 对话历史会一直累积吗?
不会。当历史消息的估算 token 总数超过 max_context_length 的 80% 时,会自动从最旧的消息开始丢弃。