Chat
anyy chat 通过正在运行的 Anyy 网关发送单条提示并打印回复。它是
交互式应用的非交互版本:没有 TUI,也没有提示循环——输入一条提示,
返回一条回答。因此它是脚本、定时任务、CI 步骤,以及任何需要在没有终端会话的情况下
获取 Anyy 回答的场景的基础构件。
由于实际工作由常驻守护进程处理,网关必须已经在运行(参见
网关)。chat 是一个轻量的 RPC 客户端:它创建或复用一个会话,
发送你的文本,并渲染助手的最终消息。完整的命令列表请参见
CLI 概览。
anyy chat [--home PATH] [--socket PATH] [--role ROLE] [--session ID] [--json] [--yes] PROMPT
提示是所有标志之后的全部内容;多个参数会用空格连接,因此引号可选,但建议使用:
anyy chat "summarize my unread mail and list anything that needs a reply"
一次性 Prompt
一次性提示会创建一个全新会话,运行单个回合,并将助手的文本打印到标准输出。除此之外
不会向 stdout 写入任何内容,因此输出可以安全捕获:
reply=$(anyy chat "what's on my calendar tomorrow?")
echo "$reply"
每次不带 --session 的调用都会启动一个新会话,标题取自提示的前 60 个字符。若要继续
已有的对话,请参见 Session 选择。
诊断信息(错误、警告、续接通知)始终写入 stderr,助手回复写入 stdout。这种分离
让你可以分别重定向:
anyy chat "draft a reply to the latest support email" \
>reply.txt 2>chat.log
Role 选择
--role ROLE 选择在创建新会话时使用的 Role。Role 打包了系统提示、默认模型与
工具策略(关于 Role 与会话的关系参见 会话):
anyy chat --role researcher "find three recent papers on local-first sync"
全局写法 anyy --role ROLE chat "..." 与之等价;当两者同时出现时,命令级的
--role 优先。
--role 仅在创建会话时生效,因此不能与 --session(指向已创建的会话)一起使用。
同时传入两者属于用法错误,退出码为 2:
✗ Cannot combine --role and --session
Reason:
--role only applies when creating a new session
Next:
omit --role, or start a new chat without --session
Session 选择
--session ID 将提示发送到已有会话,而不是创建新会话,因此该回合可以看到该会话此前的
历史、记忆和 Role:
# 第一回合创建一个会话;从 JSON 输出中捕获它的 id。
sid=$(anyy chat --json "start a trip plan for Kyoto" | jq -r .session_id)
# 继续同一个对话。
anyy chat --session "$sid" "add a day for day trips to Nara"
会话 id 是稳定的。可从 anyy chat --json 输出中捕获(session_id 字段),
或在交互式应用中恢复某个会话;关于会话如何持久化,参见
会话。指向某个会话能让多步骤脚本保持在同一条连贯的线程中。
审批
当某个回合想要执行会改变状态或具备 root 能力的操作时,Anyy 会发起一个
审批(approval),而不是静默执行。交互式应用会向你询问;anyy chat 是
非交互的,因此它采用一套确定性策略:
-
默认(不带
--yes):拒绝。 所有待处理的审批都会被拒绝,回复(如果有)仍会被 打印,命令以3退出:✗ Approval requiredReason:Anyy opened 1 pending approval(s), and noninteractive chat denies approvals by defaultNext:rerun with --yes to approve supported pending approvals -
--yes:批准受支持的审批。 每个待处理审批都会以原因approved by anyy chat --yes被批准,随后chat最多等待 10 秒以让该回合 继续,并打印最终回复:anyy chat --yes "move yesterday's screenshots into ~/Archive/2026-06"
这使 --yes 成为无人值守自动化的显式选项。仅在你信任该提示与该 Role 的工具策略时
使用它,因为它会自动批准本应由人工确认的操作。无论决策如何作出,网关仍会写入
ChangePlan、审批与审计记录。
如果 --yes 批准了全部审批,但在续接窗口内没有新的助手文本到达,chat 会向
stderr 打印超时通知,并返回它已有的文本:
⚠ Continuation wait timed out
Reason:
no new assistant text arrived within 10s
Next:
open Anyy to inspect the session, or rerun anyy chat
流式输出
anyy chat 不是流式客户端:它会等待回合结束,然后将助手的最终消息一次性
打印出来。没有逐 token 输出,也没有 --stream 标志。如需实时、增量的输出,请使用
交互式应用。
在默认(人类可读)模式下,只会写入助手文本,并以一个换行符结尾。如果该回合没有产生
助手文本(例如它只是拒绝了一个审批),则不会向 stdout 打印任何内容,结果由退出码
表示。
JSON 模式
--json 会用一个经过美化的 JSON 对象替换人类可读回复,用于描述该回合——非常适合
脚本处理,以及检查审批或停止原因。该对象是 stdout 上唯一的内容:
anyy chat --json "what timezone am I in?"
{
"session_id": "ses_01J9Z8...",
"turn_id": "trn_01J9Z8...",
"stop_reason": "completed",
"assistant_text": "You're in Asia/Shanghai (UTC+8).",
"approvals": []
}
字段结构:
| 字段 | 类型 | 含义 |
|---|---|---|
session_id | string | 该回合运行所在的会话(新建的,或来自 --session 的)。 |
turn_id | string | 本回合的标识符;若回合从未开始则为空。 |
stop_reason | string | 回合结束的原因,例如 completed、max_iterations、output_limit。 |
assistant_text | string | 助手的最终文本(若未产生则为空)。 |
approvals | array | 策略执行后仍未处理的审批;没有时为空。 |
approvals 中的每一项结构如下:
| 字段 | 类型 | 含义 |
|---|---|---|
id | string | 审批 id。 |
kind | string | 审批类别(操作类型)。 |
title | string | 简短的人类可读标题。 |
risk | string | 为该操作报告的风险级别。 |
summary | string | 对所请求内容的较长描述。 |
在 --json 与默认拒绝策略下,被拒绝的审批仍会出现在所发出的对象中,然后命令以 3
退出,因此脚本可以准确记录被拒绝的内容:
anyy chat --json "delete every file in /tmp" \
| jq '.approvals[] | {id, kind, risk}'
将 --json 与 --session 结合,可一次捕获 id 并反复使用:
out=$(anyy chat --json "begin a standup summary")
sid=$(echo "$out" | jq -r .session_id)
anyy chat --json --session "$sid" "now add yesterday's blockers" \
| jq -r .assistant_text
退出码
anyy chat 使用退出码,使脚本无需解析文本即可分支:
| 退出码 | 含义 | 常见原因 |
|---|---|---|
0 | 成功 | 回合完成(且所有审批均已批准)。 |
1 | 运行时错误 | 网关未运行 / socket 无法连接,或某次 RPC 调用失败。 |
2 | 用法错误 | 缺少提示、标志无法解析,或 --role 与 --session 同时使用。 |
3 | 审批被拒绝 | 待处理审批被默认的非交互策略拒绝。 |
带 --json 时,3 退出仍会附带 JSON 对象(包含被拒绝的 approvals);退出码 1
和 2 仅在 stderr 上打印错误块。
当网关未运行时,运行时失败如下所示:
✗ Could not create chat session
Reason:
dial unix ~/.anyy/anyy.sock: connect: no such file or directory
Next:
start Anyy gateway, then run anyy chat again
先启动守护进程(anyy gateway start,参见 网关)再重试。
区分“需要审批”与硬性失败的脚本模式:
if anyy chat --yes "tidy my downloads folder"; then
echo "done"
else
case $? in
3) echo "blocked: an action needed approval the policy would not grant" ;;
2) echo "usage error — check the command" ;;
*) echo "gateway/runtime error — is the gateway up?" ;;
esac
fi
选择网关
默认情况下,chat 会根据当前 profile 与 home 目录查找网关 socket。当你运行多个
Anyy,或脚本需要指向特定实例时,可覆盖其中之一:
--home PATH——使用指定的 Anyy home(也可通过ANYY_HOME设置); socket 由它推导得出。--socket PATH——连接到显式的网关 Unix socket,跳过 profile/home 解析。
anyy chat --socket ~/.anyy/anyy.sock "ping"