DOCAI · 课程 · L3 · 25 分钟 · 交互模式与工具
多行输入
回车一敲就发送,代码刚贴一半就碎成几条消息。几种多行写法各自适合什么场景,以及粘贴失效、内容被截断时按什么顺序排查。
你将学会
- 能用至少三种方式把多行提示词一次性提交
- 能根据终端兼容性和内容长度选择输入方式
- 能排查粘贴被逐行提交、长提示词被截断的问题
一行没写完就发出去了
你想让它改一段函数,先写要求,再粘代码。第一次回车,要求单独成了一条消息;剩下几行又各自成条。对话被切碎,它只能反复问你想干嘛。
这不是它笨,是输入框的默认规则:回车等于发送。想一次给一整段,就得让换行不触发提交。下面几种做法,从最顺手到最稳排列。
先把选择标准说清楚,后面就不用来回试:
| 场景 | 首选写法 | 原因 |
|---|---|---|
| 本地终端,写三五行要求 | Shift 加回车 | 最接近普通编辑器的手感 |
| 终端不认 Shift 加回车 | 反斜杠加回车或 Ctrl+J | 不依赖终端识别组合键 |
| 远程登录、老终端 | 三引号模式 | 只用到普通字符,兼容性最好 |
| 几十行以上的提示词 | 文件输入 | 可编辑、可复用、可进版本库 |
| 脚本或批处理 | heredoc 或管道 | 调用和内容写在一处,复制就能跑 |
| 从别处复制一大段 | 括号粘贴 | 一次送入,保留换行 |
顺手改键:Shift 加回车
按住 Shift 再按回车,光标下移,消息不发出。写完后单独按一次回车提交。
问题出在终端。有的终端原生支持,有的会把组合键当成普通回车。官方列出的原生支持名单是 iTerm2、WezTerm、Ghostty、Kitty、Warp 和 Windows Terminal;VS Code、Cursor、Zed、Alacritty 0.16 以前的版本要跑一次 /terminal-setup;GNOME Terminal 和 JetBrains 系不支持。macOS 上把 Option 设成 Meta 后,Option 加回车也能换行。
一份更细的对照,方便你判断手里这个终端该怎么办:
| 终端 | 是否原生支持 | 备注 |
|---|---|---|
| iTerm2 | 支持 | 到 Profile 的 Keys 里确认没被别的动作占用 |
| Terminal.app | 不在原生支持名单 | 用 Ctrl+J,或把 Option 设为 Meta 后用 Option+Enter |
| Windows Terminal | 较新版本支持 | 老版本升级后再试 |
| GNOME Terminal | 不支持 | 用 Ctrl+J 或三引号 |
| Konsole | 支持 | 版本差异较大,以实测为准 |
| Alacritty | 新版本支持 | 旧版本需要终端配置 |
| WezTerm | 支持 | 通常开箱可用 |
| 老版 PuTTY | 不支持 | 按下去等同直接提交 |
| SSH 客户端 | 取决于配置 | 先在远端试一次再决定写法 |
终端不认时的备用键位,按顺序试:Ctrl+J 最通用,它发送的是换行控制字符,不依赖终端把组合键翻译成特殊序列;Alt+Enter 在部分环境可用;macOS 上可以试 Option+Enter。三个都不行,直接跳到三引号模式。
反斜杠加回车:所有终端都能用
在行尾敲一个反斜杠,再按回车,输入框里插入一个换行,消息不发出。这个写法不依赖终端对 Shift 加回车的支持,SSH 到老服务器上也一样。敲完最后一行,单独按一次回车提交。
反斜杠必须是这一行的最后一个字符,后面多一个空格就不生效。Windows 路径也用反斜杠,粘贴代码时容易在行尾多带一个,发送前扫一眼。Ctrl+J 也能插入换行,它不依赖终端的键位配置,和反斜杠一样能绕开 Shift 加回车的兼容问题。
这个写法适合短稿:每行末尾多敲一个字符,写十行还能接受,写五十行就烦了。行数一多,换文件输入。
三引号多行模式:一个开关包住整段
在输入框单独敲三个双引号,按回车,会进入一个多行状态。之后每次回车都只换行,不再提交,直到你再单独敲一行三个双引号,再按一次回车,整段才发出去。
"""
请重构下面的代码,要求:
1. 把回调改成 async/await
2. 错误用 try/catch 处理
3. 补上 JSDoc 注释
function fetchUser(id, callback) {
db.query('SELECT * FROM users WHERE id = ?', [id], (err, rows) => {
if (err) return callback(err);
callback(null, rows[0]);
});
}
"""
它最大的好处是兼容性:只用普通字符,不依赖终端识别任何组合键,远程登录、老式终端、网页终端都能用。代价是两头的开关要记牢,而且不能随手在里面再写三个双引号。
和三引号相比,Shift 加回车更像「随用随走」:不用记开关,也不怕内容里有特殊符号,但对终端有要求。两个方案怎么选,可以看这张表:
| 维度 | 三引号模式 | Shift 加回车 |
|---|---|---|
| 终端要求 | 几乎没有 | 要看终端是否识别 |
| 视觉提示 | 提示符可能变化 | 通常没有变化 |
| 写错了想改 | 还在多行状态里,可以继续改 | 同样可以改 |
| 适合的场景 | 远程会话、陌生终端 | 本地开发、键位顺手 |
| 粘贴整段代码 | 适合,先开三引号再粘 | 取决于括号粘贴是否生效 |
两个常见坑
第一个坑是忘了收尾。敲了回车没反应、提示符也变了样,多半是还停在三引号状态里。补一行单独的三引号,或者按 Ctrl+C 取消这一轮输入,就能退出来。
第二个坑是内容本身带三引号。比如让它看一段 Python 代码,里面正好有文档字符串,那三个引号会被当成结束标记,后半段直接漏掉。这种情况换成 Shift 加回车,或者把代码存成文件让它自己读,别和三引号较劲。
长内容放进文件
提示词几百行时,终端里改起来很别扭。存成文件,让启动命令读进去:
claude "读取 task.md,按里面的步骤执行" # 进入对话,让它自己读文件
claude -p < task.md # 把文件内容当提示词,跑完就退出
只想拿一次结果、还要接进脚本,用 -p。文件输入还有个好处:提示词能进版本库。改了什么、哪次改动让结果变差,翻记录就知道。启动前用编辑器通读一遍,错别字和漏掉的约束都能提前拦住。
两种读法的差别值得分清。第一种是把文件路径告诉它,由它自己决定什么时候读、读哪几段,适合大文件;第二种是把文件内容直接当第一条消息送进去,适合中小文件、要求一次说清的任务。文件很大时优先第一种,别把几万字一次性塞进上下文。
想让别的命令的输出直接当输入,用管道:
git diff | claude -p "按风险排序,指出这次改动最可能出问题的地方"
管道送来的内容和命令行里写的提示词会拼在一起送进去:命令在前,文本在后。写的时候要意识到这一点,别在提示词里假设它只看到了你打的那句话。
脚本里写长提示词,heredoc 更整齐。定界符加单引号,里面的 $ 和反引号就不会被 shell 展开:
claude -p <<'PROMPT'
检查依赖清单:
1. 列出无人维护的包
2. 标出跨大版本升级的项
3. 给出升级顺序
只输出清单,不要执行安装。
PROMPT
定界符不加引号时,shell 会替换里面的变量,这既是功能也是风险:想传项目路径,可以写 $PROJECT_DIR;但提示词里如果本来就有美元符号、反引号或反斜杠,就会被 shell 先处理一遍,内容变形。除非确实要传变量,否则一律用带引号的写法。
heredoc 适合把提示词和调用写在同一个脚本里,复制走就能跑;缺点是改起来不如独立文件方便。需要反复调整措辞的提示词,还是存成独立文件。
粘贴被拆开、内容被截断
现代终端支持括号粘贴,多行内容一次进入输入框。粘贴后仍被逐行发送,先确认终端类型和配置是否启用;临时办法是把内容先存成文件,用 claude -p < task.md 送进去,别在键位上反复试。
快捷键也可能按错。Windows 终端里粘贴常用 Ctrl+Shift+V,macOS 用 Cmd+V,有的终端还提供右键或菜单。按下去没反应时,先确认你用的是终端的粘贴,而不是编辑器的。
另有三种截断来源。单行过长,某些终端有上限,拆行或改文件;复制来的内容夹带控制字符,先存文件看清再读;内容超出模型能处理的范围,别硬塞,给它路径让它自己读。最后一种最值得养成习惯:贴一整份文件,不如告诉它文件在哪,省 token 也更准,见上下文窗口。
粘贴变逐行提交
症状是每粘一行就发出去一条。原因是终端没有开启括号粘贴,输入框把内容里的换行都当成了回车。先看终端类型变量,正常的取值形如 xterm-256color、screen-256color 或 tmux-256color;再查本机的行编辑配置里有没有开启括号粘贴。tmux 里还要确认它没有把剪贴板事件吞掉。排查不出来时不要纠缠,直接把内容存成文件,用输入重定向送进去,三秒解决。
长提示词只收到前半段
症状是贴了几千字,模型只回应开头一小段。常见原因有四个,按这个顺序查:
- 终端单行长度限制。有的环境一行最多几千字节,超出的部分被截掉。把内容拆成多行再贴。
- 夹带了看不见的控制字符。从网页或文档复制时常带控制序列,可用
cat -A查看,出现大量 ^[ 一类的记号就是有问题;再用tr过滤掉控制字符,存成干净文件。 - 超出上下文容量。几万 token 的日志不适合整段贴,先用
/compact腾空间,或者拆成几批,最好让它按路径自己读。 - 代理或网络层截断。只在个别人机器上复现时,先怀疑网络链路。
这四类的共同解法都是「别在输入框里硬扛」:内容进文件,路径给它,读哪段由它决定。具体怎么让它按需读文件,见让它自己读文件。
想把提示词和代码分开
粘贴代码后它把要求和代码搅成一团来理解,最省事的修法是用代码围栏明确边界:先写要求,空一行,再贴三个反引号加语言名,接着贴代码,最后用三个反引号收尾,末尾再补一句问题。围栏本身就是给模型的信号,比在正文里说「下面这段是代码」更清楚。
一份可以直接用的任务书
请读取 src/old_parser.py 并重构:
- 改成函数式写法
- 补类型标注
- 保留原有说明文字
- 每改完一个函数先停,等我确认
约束:不改公开接口,不新增依赖。
用 claude -p < task.md 跑一次,或进入对话后说「读取 task.md,先复述计划」;先让它只读、复述,确认无误再放行修改。任务书里把「先做什么、停在哪、什么不能动」写清楚,比堆形容词有用。它每完成一段就停下来,你能及时纠偏,不会一口气改完十个文件才发现方向错了。
还需要批量处理多个文件时,可以把任务书和循环写进一个脚本:遍历目标文件,对每个文件调用一次非交互模式,把结果写到新文件里,处理完再人工抽查几份。批量任务的提示词更要固定,因为没人会逐条盯着输出。这条路线和批量处理文档里的做法是同一套思路。
故障排查:症状、原因、处理
| 症状 | 原因 | 处理 |
|---|---|---|
| Shift 加回车直接发送 | 终端不识别这个组合 | 换 Ctrl+J 或反斜杠加回车 |
| 粘贴后逐行发出 | 括号粘贴未开启 | 存文件输入,或改终端配置 |
| 三引号里回车也不发送 | 正常,说明还在多行状态 | 补一行三引号收尾 |
| 三引号内容缺了后半段 | 内容里自带三引号,提前闭合 | 改用 Shift 加回车或文件 |
| 多行状态退不出去 | 忘了收尾符 | 按 Ctrl+C 取消本轮输入 |
| 长文只收到开头 | 行长度限制、控制字符或上下文超限 | 按上面四步排查 |
| heredoc 里的变量没替换 | 定界符带了单引号 | 需要变量时去掉引号,但注意特殊字符 |
| 管道内容和提示词混在一起 | 两者本来就会拼接 | 调整提示词,明确指代对象 |
取消输入记住一个键就够:Ctrl+C 按一次只中断这次输入,不会退出整个工具。Esc 也能清掉当前草稿,选哪个看手习惯。
边界:什么情况下别用多行输入
不是所有任务都值得凑成一大段。需要来回确认的探索性任务,一句一句问反而更快;改一处小错,也不必开三引号或写文件。真正适合长输入的,是需求已经想清楚、约束需要一次交代完整的任务。
还有一个容易忽略的边界:多行输入解决的是「怎么送进去」,不解决「送进去什么」。把五十行日志整段贴进去,不如先筛出报错前后二十行;把整个仓库贴进去,不如给出路径和关注点。输入方式越省事,越容易把无关内容也带进去。写之前先删掉一半,往往比换一种输入方式更有效。
键位和写法只是入口,真正的效率来自把要求写完整、一次说清。下一节回到操作本身,把常用按键练熟:命令历史;想系统对照终端按键,看键盘快捷键。
自测
先自己回答,再展开对照;答不上来就回到对应小节。01为什么默认模式下粘贴多行代码会被拆成几条消息?看答案
输入框把回车当提交。终端若没启用括号粘贴,粘贴内容里的每个换行都会触发一次发送。
02提示词很长时,为什么更推荐放进文件?看答案
文件便于编辑、复用和进版本库,能避开单行长度限制;让它按路径自己读,也比整段贴进去更省上下文。