跳到主要内容

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 required

    Reason:
    Anyy opened 1 pending approval(s), and noninteractive chat denies approvals by default

    Next:
    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_idstring该回合运行所在的会话(新建的,或来自 --session 的)。
turn_idstring本回合的标识符;若回合从未开始则为空。
stop_reasonstring回合结束的原因,例如 completedmax_iterationsoutput_limit
assistant_textstring助手的最终文本(若未产生则为空)。
approvalsarray策略执行后仍未处理的审批;没有时为空。

approvals 中的每一项结构如下:

字段类型含义
idstring审批 id。
kindstring审批类别(操作类型)。
titlestring简短的人类可读标题。
riskstring为该操作报告的风险级别。
summarystring对所请求内容的较长描述。

--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);退出码 12 仅在 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"

关于会话与 Role 如何在多次调用间持久化,参见 会话;其余命令集请见 CLI 概览