模型与上下文
ZettCode 能对接任何 OpenAI 兼容的接入点:云上的 API、把多家 provider 聚在一起的网关,或者跑在 你自己机器上的模型。它需要知道的东西都在配置参考里。
切换
/model 会在对话之上弹出选择面板。Enter 选定的是之后的请求 —— 正在跑的那一次不受影响 —— 头部会立刻显示新名字。/model DeepSeek Pro 也可以,它会同时匹配显示名和模型 id,适合你很清楚 想要哪个的时候。
每个模型有各自的 token、接入点和窗口,所以在本地服务和云服务之间切换只要按一个键,而不是改 配置再重启。
例如,按双模型配置添加 DeepSeek Pro 和 DeepSeek Flash, 然后依次尝试:
/model DeepSeek Pro
先解释这个模块的设计取舍,不要急着修改。
/model DeepSeek Flash
看看这张截图,说明错误信息是什么意思。截图请求需要实际附加图片,并且对应模型配置了 multimodal = true。切换模型不会自动附加 图片,也不会清空对话。想从没有历史的状态开始,应使用 /new。
推理强度
/effort 决定模型在回答前愿意想多久:
| 档位 | 适合什么 |
|---|---|
off | 请求不做刻意思考,实际取决于接入点支持。 |
minimal | 一点点思考,最快。 |
low | 小改动时的快速回答。 |
medium | 默认的平衡点。 |
high | 难题多想一些。 |
xhigh | 难题上长时间思考。 |
max | provider 能接受的最高预算。 |
ultra | 请求最高档位,是否可用取决于接入点。 |
档位影响本次程序运行中的后续请求,头部会显示当前选择,不是写入 config.toml 的永久设置。 例如:
/effort low
解释这个正则表达式匹配什么。
/effort high
检查这段加锁代码是否可能死锁或发生竞争,先不要修改。实际思考预算由接入点决定,不是所有接口都支持所有档位。网关可能映射不支持的值,也可能 直接拒绝。DeepSeek 当前的映射规则见 Thinking Mode。 当前客户端在 Chat Completions 下使用 /effort off 时,只会省略 reasoning_effort, 不会发送 DeepSeek 单独的 thinking 开关。因此不能保证关闭默认已开启的供应商思考模式。
上下文窗口
每个模型都有上限。ZettCode 会跟踪用量 —— 状态行里的 ctx 34.0%,以及 /context 里的完整 明细 —— 并按模型配置里的 compact_percent 在溢出之前压缩。
Context 103,241 / 128,000 tokens
Source Share Count
System prompt 1.9% (1)
Environment notes 4.8% (2)
Tool schemas 10.9% (9)
User messages 0.1% (3)
Assistant messages 22.2% (12)
Tool output 60.1% (17)
~4 chars/token · esc back标题拿总量和模型的窗口比;百分比是当前上下文内部的占比,所以加起来是 100%。如果某一行 大得意外,那就是该看的地方:一个你从不使用的工具 schema,或者一次读文件返回的长内容。页脚会 说明这些数字是谁算出来的 —— 能加载编码时是 tiktoken,否则是按每四个字符一个 token 估算。
两种百分比要分开理解:
| 显示位置 | 计算方式 | 例子 |
|---|---|---|
状态行的 ctx | 当前上下文 token ÷ 配置的窗口大小 | 1,000,000 的窗口用了 100,000,显示 ctx 10.0%。 |
/context 的分类行 | 这一类的 token ÷ 当前上下文总 token | 总共 100,000,其中工具输出 60,000,工具输出占 60.0%。 |
分类占比在显示舍入前加起来是 100%。Count 表示对应分类的消息、工具定义或指令条目个数, 不是对话轮数。恢复的会话也可以查看;当前进程尚未组装工具和环境说明时,页脚可能显示 notes and tools pending,说明这还是一份不完整的快照。
压缩
当最新一次请求将要越过触发线时,对话会先被总结:较早的部分变成一条摘要消息,触发线的最后四分之一 原样保留,所以模型保住了眼前的上下文,只丢掉已经说过的内容。/compact 可以立刻做这件事。
摘要是作为一种独立的记录存下来的,而不是删除。这就是为什么对话里会以 Conversation checkpoint 收尾,为什么会话列表仍然准确,以及为什么昨天压缩过的会话今天还能 正确恢复。手动触发时只有最后一轮会原样保留,而自动压缩会留下触发线的四分之一。
压缩的代价
总结本身是一次模型调用,所以要花几秒钟 —— 期间对话里会显示 Compacting。早做比晚做好:不然 你就得在自己正忙着的时候面对接入点报错。如果摘要并不比原文更短,ZettCode 会直接说明并保留 原文。
对话进行了几轮,或者读过很大的文件之后,可以依次尝试:
/context
/compact
/context每次用 Esc 关闭上下文面板,再输入下一条命令。/compact 立即开始生成摘要,期间显示带动画的 Compacting。对比前后报告:较早的内容由摘要替代,近期工作上下文仍然保留。 它不是 /clear:压缩会改变后续发给模型的内容,清屏只改变可见的对话。
如果最新的 checkpoint 已经覆盖当前对话,再手动压缩会被拒绝并提示。先继续对话,再考虑压缩。 摘要可能省略细节;需要准确原文时,让模型重新读取对应文件。
读懂那些数字
↑18.4k ↓900 · 71.2% cached · 74 tok/s · ctx 12.3% —— 依次是:发出的 token 数、生成的 token 数、输入中命中 provider 缓存的比例、按模型耗时平均的生成速度,以及最新一次请求的窗口 占用。输入和输出总量在会话内累加;上下文占用是快照,不是不断累加的百分比。
| 字段 | 应该怎么理解 |
|---|---|
↑ / ↓ | 供应商上报的累计输入和输出 token。历史上下文重复发送时,每次都会算输入。 |
cached | 累计缓存命中输入 token ÷ 累计输入 token。100,000 输入里命中 60,000,就是 60.0%。 |
tok/s | 输出 token 除以测得的模型耗时,不是含工具、审批和阅读时间的整轮墙钟耗时。 |
ctx | 最近的上下文占用相对于所选模型配置窗口的比例。 |
接入点没有上报缓存命中数量时,这里无法得到有意义的命中率。这些统计不是账单,实际收费 应查看供应商控制台。
缓存这一项值得理解,因为时间和钱都花在这里。provider 缓存的是请求的前缀:如果一次请求的 开头和上一次逐字节相同,这一部分就更便宜、更快。这就是系统提示只写日期不写时间、项目指令按 固定顺序读取、以及可以在两轮之间随手打开 /context 的原因 —— 稳定的前缀有利于复用缓存。 不存在通用的“好命中率”:切换模型、压缩、工具定义变化和供应商缓存有效期都可能让比例下降。 新生成的输出,只有在之后的请求中作为输入发回去,才可能成为命中的输入缓存。