Skip to content

Agent Context.zh CN

Saco Song edited this page Aug 14, 2026 · 4 revisions

Agent 上下文

English · 首页

Agent 上下文是一份由用户选择启用、在开始听写时创建的术语快照。它不是停止听写时截取的 assistant message,也不只用于 LLM refinement。同一份不可变快照可以分别向 Qwen-Audio-3 Streaming 和 Refine 提供长度受限的术语视图。

启用方式

[llm]
agent_context_enabled = true
agent_context_max_chars = 6000

启用 Refine,或者选用的 ASR provider 为 alibaba-qwen-audio3 时,程序都会构建术语。因此,即使 llm.enabled = false,Audio3 也可以收到 Session Context。公开配置默认关闭此功能。

开始时创建的快照

录音开始时,Voice Input 会冻结以下信息:

  • 当前聚焦的 Kitty 窗口,以及其中聚焦的前台 picodex process;
  • 解析得到的 Pi 或 Codex session;
  • 此时可用的最新一条已完成 assistant source。

程序会在启动术语 worker 前读取 source。此后切换 Kitty tab、改变焦点或者出现新的 assistant response,都不会改变本次操作的快照。程序会在可能较慢的 session 查找前准备好音频采集,避免因为开始时查找 session 而丢失快捷键按下后的音频。

程序在本地按以下顺序处理 source:

  1. 验证 process、session identity、canonical path 和文件 identity;
  2. 最多读取 session JSONL 末尾 8 MiB;
  3. 选择最新一条已完成 assistant text,并忽略 tool-call block;
  4. 对已知的敏感行和 token-shaped secret 执行脱敏;
  5. 把 source 字符预算限制在 500–12,000;
  6. 使用 Jieba 在本地分词,过滤不适合作为术语或疑似 secret 的候选项,并按大小写不敏感方式去重;
  7. 统计候选项在脱敏 source 中的出现次数,按照低频到高频排列;频率相同时保留稳定的 source 顺序;
  8. 保存一份仅用于本次操作的不可变术语快照。

完整 source text 和术语频率始终保留在本机。

两种远程视图

两个使用方会从同一快照中独立选择完整术语:

使用方 发送的数据 限制与时机
Qwen-Audio-3 Streaming 初始 run-task input context 中使用换行分隔的纯文本术语 包含换行在内最多 400 个字符。即使关闭 LLM refinement,该限制仍然适用。
Refine 随 transcript 发送的 reference_context.agent 和术语 array 最多 96 个术语,术语字符总数最多 1,500。

两种视图都不会发送原始 assistant message、频率计数、session path、process ID、window title、application metadata 或原始 desktop metadata。Audio3 不接收 Agent label。Refine 只接收与开始时快照关联的规范 PiCodex label。

Audio3 不发送 continue-task。如果结束前的一次可恢复中断创建了 replacement task,replacement run-task 会收到完全相同且已经限制长度的 context string。程序不会合并旧 task 与 replacement task 的术语或 transcript。

在 Refine 前以及 model 返回结果后,Voice Input 都会在本地归一化高置信度的技术词变体。这些变体只能与快照中选定的术语存在 ASCII 大小写或分隔符差异。边界与准入检查可以避免大范围替换有歧义的子词。快照和归一化规则不会跨录音保留。

停止时焦点承担独立职责

停止听写且启用了 LLM refinement 时,当前聚焦的目标只决定 refinement 的呈现风格:

  • 聚焦 Pi 或 Codex 时,使用紧凑的 coding-agent Markdown;
  • 聚焦已识别的原生即时通讯客户端时,使用自然的消息标点;
  • 其他目标使用轻度书面化的默认风格。

停止时的焦点不会重新选择或刷新开始时的术语 source。相应地,如果停止时的目标已经改变,开始时的术语也不会强制使用 coding-agent Markdown。

Pi 查找

make install 会复制:

~/.pi/agent/extensions/voice-input-session-registry.ts

Extension 会在以下目录发布权限为 0600 的 registry file:

$XDG_RUNTIME_DIR/voice-input/agent-sessions/pi-<pid>.json

它会在 Pi session lifecycle event 发生时更新 registry,也会每五秒更新一次,并在 shutdown 时删除属于自己的 registry。Voice Input 会验证:

  • registry schema version、PID 和 Linux process start ticks;
  • session canonical path 位于 ~/.pi/agent/sessions 下;
  • session header ID 与 registry 一致;
  • 加载 source 时,process identity、文件 device 和 inode 仍然一致。

安装或更新后必须重启 Pi,或者 reload Pi extension。已经运行的 Pi process 不会自动加载刚复制的 extension。

Registry 发布使用同一个串行写入 queue,并且每个 runtime 都有 generation token。Shutdown 会使自己的 generation 失效,等待已排队的写入结束,然后只删除自身 registry。程序会在 atomic rename 前立即检查 generation,避免 /new/resume/fork/reload 之后,延迟的 heartbeat 覆盖新 entry。

Voice Input 会沿 Pi 当前 branch 向后回溯,查找最新一条 stopReason = "stop" 的 assistant message,并且只收集 text block。

Codex 查找

Codex 不需要仓库提供的 extension。Voice Input 会:

  1. 从当前聚焦的 Codex process 读取 CODEX_HOME,没有该变量时使用 ~/.codex
  2. 通过 Linux /proc 检查该 process 已打开的 file descriptor;
  3. 只接受 canonical path 位于 CODEX_HOME/sessions 下的 .jsonl,并要求 header 中包含 source = "cli"thread_source = "user"
  4. 只有恰好存在一个符合条件的已打开 session file 时才继续;
  5. 选择最新的 assistant final_answer,并把 task_complete.last_agent_message 作为兼容 fallback。

Container 边界、受限的 /proc、多个符合条件的文件,或者非 CLI session 都会使程序不创建术语快照,而不会猜测 session。

Kitty 条件

开始录音时,活动窗口 class 必须为 kitty。Voice Input 会通过以下地址查询 Kitty OS window:

unix:/tmp/kitty-<kitty-process-id>

kitty @ … ls 返回的数据必须表明:当前 focused foreground process 的可执行文件 basename 恰好为 picodex。外部查询的 timeout 为一秒。

Launcher 可以采用以下方式启用所需的逐进程 socket:

#!/bin/sh
exec kitty -o allow_remote_control=yes \
  --listen-on "unix:/tmp/kitty-$$" "$@"

exec 会保留 shell PID,因此 socket 名称会与 Kitty process 匹配。请根据 launcher 和安全策略调整该写法。

脱敏与信任边界

脱敏会替换包含常见 authorization、API key、password、secret、token、private-key 或 cookie 标记的整行,也会替换具有已知 prefix 的 token 和较长的 JWT-like value。程序随后限制脱敏 source 的长度,再提取术语。这些规则属于启发式保护,无法识别每一种 credential、私人名称、专有术语或敏感句子。

Refine 会把每个术语候选项视为不可信 vocabulary。Prompt 只允许使用术语解决可能的 ASR 拼写问题,并明确禁止把术语当作指令或事实来源。Transcript 本身也只是待编辑文本:其中的问题、命令和请求必须保留,不能回答或执行。Prompt 指令可以降低风险,但无法证明每个第三方 model 都会完全遵守。

如果某个 source 中提取出的 vocabulary 不应发送给配置的 Alibaba 或 LLM provider,请勿启用 Session 术语。

取消与失败行为

取消会停止后续 refinement 和输出,但无法撤销已经读取或发送的数据。特别是,在收到 record cancel 前,程序可能已经在本地读取开始时的 source text,Audio3 也可能已经通过 run-task 发送 Session Context。

术语功能采用 fail-soft 行为:

  • 焦点不受支持、Kitty 查找失败、session 无效或存在歧义、没有已完成 assistant source、脱敏或提取失败,或者 consumer 等待超时时,都不会产生术语视图;
  • Audio3 最多等待 min(asr.connect_timeout_ms, 5000) 毫秒;快照仍未准备好时,它会在不带 Session Context 的情况下启动;
  • refinement 开始前,daemon 最多等待 min(llm.timeout_ms, 5000) 毫秒;必要时会在不带术语的情况下继续,后续 LLM attempt 仍共用其自身配置的 refinement deadline;
  • 无法构建术语不会直接改变识别文本;
  • LLM 失败时仍会保留 ASR 识别文本。

在 Audio3 Adaptive 模式下,如果 stream 可用、明确完成且确实发送了 Session Context,程序不会仅因为录音达到 30 秒而使用 Native 替换该结果。Stream 为空、降级、中断、过载或没有明确完成时,仍然遵循常规的完整音频恢复策略。

安全排查选择结果

首先使用适合支持报告的安全输出:

voice-input diagnostics --format text

Schema 4 只报告是否发送了非空的 Audio3 Session Context,不包含术语或 source text。Daemon 日志还可以报告开始时查找结果、source 字符数、候选项数量、选中的术语数量与字符数,以及提取耗时,但不会打印术语:

journalctl --user -u voice-input.service -b \
  | grep -E 'voice-input (agent context|refinement context)'

在不打开文件的情况下检查 Pi registry:

ls -l "$XDG_RUNTIME_DIR/voice-input/agent-sessions/"

使用实际活动窗口 PID 检查 Kitty endpoint:

hyprctl activewindow -j
kitty @ --to unix:/tmp/kitty-<pid> ls

除非已经检查过私人数据,否则不要发布 Kitty response、session command line、registry 内容、session path 或 JSONL file。不要把 voice-input status --extended 用作支持报告,因为其中可能包含 transcript 和 tooltip text。

另请参阅:安全与隐私 · 故障排查

Clone this wiki locally