输出样式与状态栏
本教程共 34 篇 · 第 24 篇 · 更新于 2026-07-26 · 约 8 分钟阅读
24. 输出样式与状态栏
本节目标:搞懂输出样式(Output Styles)怎么改 Claude 的「说话方式」,学会用状态栏(Statusline)在终端底部挂一个自己定制的监控条。学完你能让 Claude 按你要的格式回答,还能随时盯着上下文用了多少、花了多少钱。
输出样式是什么
你跟 Claude 聊天,它默认的「说话方式」是软件工程师范儿:直接给方案、上代码、不废话。这挺好,但有时候你想要的不是这个。
打个比方:同样是修车,有的师傅闷头干完交钥匙,有的师傅边修边跟你讲「这块为什么这么换」。输出样式(Output Styles)就是管这个的——它改变 Claude 的「说话方式」,不改它「知道什么」。
具体来说,输出样式修改的是系统提示(System Prompt),设置角色、语气和输出格式。什么时候该用它?两种情况:
- 你老在每一轮里重复要求同一种格式或语气(比如「请先画个图再说」)
- 你想让 Claude 干的活儿根本不是软件工程(比如当写作助手、数据分析师)
Note跟项目、约定、代码库有关的说明,应该写在
CLAUDE.md里,不是输出样式。输出样式管「怎么说」,CLAUDE.md管「知道什么项目背景」。
四种内置样式
Claude Code 自带四种输出样式,不用配置直接能选。
默认(Default):就是现有的系统提示,帮你高效完成软件工程任务。你平时用的就是这个。
Proactive(主动型):Claude 立刻动手,自己做合理假设而不是停下来问你常规决策,倾向于行动而不是规划。它比自动模式(Auto Mode)的自主性更强,但不用改权限模式——工具运行前你照样会看到权限提示。
Explanatory(讲解型):在帮你干活的同时给你「Insights(洞察)」,帮你理解实现选择和代码库模式。适合你想边干边学。
Learning(学习型):协作式的边学边做。Claude 不仅分享 Insights,还会要求你自己贡献一些小的、战略性的代码片段,并在代码里加 TODO(human) 标记让你来实现。适合拿它当学习搭子。
切换方法:运行 /config,选输出样式,从菜单里挑。你的选择会存到本地项目级的 .claude/settings.local.json 里。
不想点菜单,直接改设置文件也行:
{
"outputStyle": "Explanatory"
}
Warning独立的
/output-style命令在 v2.1.73 中已弃用,在 v2.1.91 中被移除。现在统一用/config或直接改outputStyle设置字段。
输出样式是系统提示的一部分,Claude Code 在会话开始时读一次。改了之后要 /clear 或开新会话才生效。
写一个自定义输出样式
内置的四种不够用?你可以自己写。自定义输出样式就是一个 Markdown 文件:frontmatter 放元数据,正文是要追加到系统提示的说明。
三步走
-
在三个级别之一存文件。文件名就是样式名(除非你在 frontmatter 里设了
name):- 用户级:
~/.claude/output-styles - 项目级:
.claude/output-styles - 托管策略级:托管设置目录里的
.claude/output-styles
- 用户级:
-
写 frontmatter 和说明。关键是决定要不要保留 Claude Code 自带的软件工程说明。还要它编码就设
keep-coding-instructions: true;纯干别的就省掉。 -
运行
/config,在输出样式下选你的样式。/clear或下次启动会话时生效。
举个实际的例子——让 Claude 每次解释都先给一张 Mermaid 图表:
---
name: Diagrams first
description: Lead every explanation with a diagram
keep-coding-instructions: true
---
When explaining code, architecture, or data flow, start with a Mermaid diagram showing the structure, then explain in prose.
## Diagram conventions
Use `flowchart TD` for control flow and `sequenceDiagram` for request paths. Keep diagrams under 15 nodes.
frontmatter 字段一览
| 字段 | 作用 | 默认值 |
|---|---|---|
name | 样式名称,不设就从文件名继承 | 从文件名继承 |
description | 描述,在 /config 选择器里显示 | 无 |
keep-coding-instructions | 是否保留 Claude Code 内置的软件工程说明 | false |
force-for-plugin | 仅限插件用:启用插件时自动套用此样式,覆盖用户的 outputStyle 设置 | false |
Tip插件(Plugin)也能在自己的
output-styles/目录里带输出样式,安装插件就能用。
跟其他功能怎么区分
好几个功能都能自定义 Claude Code 的行为,容易混。我给你理一下:
| 功能 | 工作原理 | 什么时候用 |
|---|---|---|
| 输出样式 | 修改系统提示 | 每一轮都想要不同的角色、语气或响应格式 |
CLAUDE.md | 系统提示之后追加用户消息 | 始终让 Claude 了解项目约定和代码库上下文 |
--append-system-prompt | 追加到系统提示但不删任何内容 | 想一次性追加一段说明 |
| 子代理(Subagent) | 用自己的系统提示、模型和工具跑 | 想要一个单独作用域的辅助工具 |
| 技能(Skill) | 调用时加载任务专属说明 | 有可复用的工作流 |
一句话记:输出样式改「怎么说」,CLAUDE.md 改「知道什么背景」,子代理和技能改「干哪件具体的活」。
状态栏是什么
说完了输出样式,聊聊状态栏(Statusline)。
状态栏是 Claude Code 底部那一行可自定义的栏,能跑你配置的任何 shell 脚本。它通过标准输入(stdin)接收 JSON 会话数据,然后显示你的脚本打印的任何内容。
打个比方:状态栏就像你车上的仪表盘——速度、油量、里程,一眼扫过去就知道当前状态,不用专门去查。
它什么时候有用?
- 工作时想盯着上下文窗口(Context Window)用了多少
- 需要追踪会话花了多少钱
- 开了好几个会话,需要一眼区分谁是谁
- 希望 git 分支和状态一直可见
Note状态栏在本地跑,不消耗 API 令牌。它在自己单独一行里显示,位于内置页脚徽章上方,不会替换它们。
快速设置状态栏
用 /statusline 命令(推荐)
最快的方式:直接用自然语言告诉 Claude Code 你想要什么,它帮你生成脚本并自动更新设置。
/statusline show model name and context percentage with a progress bar
就这么一句话,Claude Code 会在 ~/.claude/ 里生成脚本文件,自动把配置写进你的设置。适合不想自己写脚本的人。
手动配置
想完全掌控,就手动来。在 ~/.claude/settings.json(或项目设置)里加 statusLine 字段:
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 2
}
}
command 字段在 shell 里跑,所以你也能直接写内联命令。下面这个用 jq 解析 JSON,显示模型名和上下文百分比:
{
"statusLine": {
"type": "command",
"command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'"
}
}
几个可选字段:
| 字段 | 作用 |
|---|---|
padding | 给状态栏内容加水平间距(字符数),默认 0 |
refreshInterval | 每 N 秒重跑一次命令(最小 1),适合显示时钟等时间相关数据 |
hideVimModeIndicator | 设 true 隐藏内置的 -- INSERT -- 文本,当你脚本自己渲染 vim 模式时用 |
要删掉状态栏,跑 /statusline delete 或 /statusline clear,或者手动从 settings.json 里删掉 statusLine 字段。
手写一个状态栏脚本
带你走一遍手动创建的流程,了解幕后发生了什么。目标:显示当前模型、工作目录和上下文窗口使用百分比。
第一步:写脚本
Claude Code 通过 stdin 给你的脚本发 JSON 数据。这个脚本用 jq(命令行 JSON 解析器,可能需要装)提取字段,然后打印格式化的行。存到 ~/.claude/statusline.sh:
#!/bin/bash
# 读取 Claude Code 从 stdin 发来的 JSON 数据
input=$(cat)
# 用 jq 提取字段
MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
# "// 0" 在字段为 null 时提供兜底值
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
# 输出状态行 - ${DIR##*/} 只取文件夹名
echo "[$MODEL] ${DIR##*/} | ${PCT}% context"
第二步:给执行权限
chmod +x ~/.claude/statusline.sh
第三步:写进设置
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh"
}
}
设置会自动重载,但改动在你跟 Claude Code 下一次交互前不会出现。
Tip配好之前,先用模拟输入单独测一下脚本,避免上线后空白或报错:
echo '{"model":{"display_name":"Opus"},"workspace":{"current_dir":"/home/user/project"},"context_window":{"used_percentage":25},"session_id":"test"}' | ./statusline.sh
状态栏能拿到哪些数据
Claude Code 通过 stdin 给脚本发的 JSON 字段很多,挑最常用的列一下:
| 字段 | 描述 |
|---|---|
model.display_name | 当前模型显示名 |
workspace.current_dir | 当前工作目录 |
workspace.project_dir | 启动 Claude Code 的目录 |
cost.total_cost_usd | 估计的会话成本(美元),客户端算的,跟实际账单可能有出入 |
cost.total_duration_ms | 自会话开始的总耗时(毫秒) |
context_window.used_percentage | 上下文窗口已用百分比 |
context_window.context_window_size | 最大上下文窗口大小(token),默认 200000,扩展模型 1000000 |
rate_limits.five_hour.used_percentage | 5 小时滚动窗口已用百分比(仅订阅用户) |
session_id | 唯一会话标识符 |
version | Claude Code 版本号 |
output_style.name | 当前输出样式名 |
effort.level | 当前推理强度(low/medium/high/xhigh/max) |
vim.mode | vim 模式(NORMAL/INSERT/VISUAL) |
Warning有些字段可能不存在或为
null:第一次 API 响应前很多字段是空的;rate_limits只对订阅用户(Pro/Max)在首次 API 响应后才有。脚本里一定要用兜底处理,比如jq里写// 0或// empty。
完整的 JSON 结构长这样(精简版):
{
"model": { "id": "claude-opus-5", "display_name": "Opus" },
"workspace": {
"current_dir": "/current/dir",
"project_dir": "/original/dir",
"repo": { "host": "github.com", "owner": "anthropics", "name": "claude-code" }
},
"cost": {
"total_cost_usd": 0.0123,
"total_duration_ms": 45000,
"total_lines_added": 156,
"total_lines_removed": 23
},
"context_window": {
"total_input_tokens": 15500,
"total_output_tokens": 1200,
"context_window_size": 200000,
"used_percentage": 8,
"remaining_percentage": 92
},
"effort": { "level": "high" },
"rate_limits": {
"five_hour": { "used_percentage": 23.5, "resets_at": 1738425600 },
"seven_day": { "used_percentage": 41.2, "resets_at": 1738857600 }
},
"session_id": "abc123...",
"version": "2.1.220"
}
几个实用脚本示例
上下文进度条
显示模型名和上下文使用百分比,带一个 10 格的进度条:
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
# 构建进度条
BAR_WIDTH=10
FILLED=$((PCT * BAR_WIDTH / 100))
EMPTY=$((BAR_WIDTH - FILLED))
BAR=""
[ "$FILLED" -gt 0 ] && printf -v FILL "%${FILLED}s" && BAR="${FILL// /█}"
[ "$EMPTY" -gt 0 ] && printf -v PAD "%${EMPTY}s" && BAR="${BAR}${PAD// /░}"
echo "[$MODEL] $BAR $PCT%"
成本和耗时
跟踪会话花了多少钱、跑了多久:
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')
COST_FMT=$(printf '$%.2f' "$COST")
DURATION_SEC=$((DURATION_MS / 1000))
MINS=$((DURATION_SEC / 60))
SECS=$((DURATION_SEC % 60))
echo "[$MODEL] $COST_FMT | ${MINS}m ${SECS}s"
多行 + 颜色
第一行显示 git 信息,第二行显示带颜色的进度条和成本。上下文 70% 以下绿色,70-89% 黄色,90% 以上红色:
#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name')
DIR=$(echo "$input" | jq -r '.workspace.current_dir')
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
DURATION_MS=$(echo "$input" | jq -r '.cost.total_duration_ms // 0')
CYAN='\033[36m'; GREEN='\033[32m'; YELLOW='\033[33m'; RED='\033[31m'; RESET='\033[0m'
# 按上下文用量选颜色
if [ "$PCT" -ge 90 ]; then BAR_COLOR="$RED"
elif [ "$PCT" -ge 70 ]; then BAR_COLOR="$YELLOW"
else BAR_COLOR="$GREEN"; fi
FILLED=$((PCT / 10)); EMPTY=$((10 - FILLED))
printf -v FILL "%${FILLED}s"; printf -v PAD "%${EMPTY}s"
BAR="${FILL// /█}${PAD// /░}"
MINS=$((DURATION_MS / 60000)); SECS=$(((DURATION_MS % 60000) / 1000))
BRANCH=""
git rev-parse --git-dir > /dev/null 2>&1 && BRANCH=" | $(git branch --show-current 2>/dev/null)"
echo -e "${CYAN}[$MODEL]${RESET} ${DIR##*/}$BRANCH"
COST_FMT=$(printf '$%.2f' "$COST")
echo -e "${BAR_COLOR}${BAR}${RESET} ${PCT}% | ${YELLOW}${COST_FMT}${RESET} | ${MINS}m ${SECS}s"
Tip状态栏脚本在活跃会话期间频繁运行。像
git status这种命令在大仓库里可能很慢,建议缓存到临时文件,每 5 秒刷新一次,别每条消息都跑一遍。
Windows 上的配置
在 Windows 上,Claude Code 通过 Git Bash(如果装了)跑状态栏命令,没装 Git Bash 就走 PowerShell。
用 PowerShell 脚本的话,配置里用 powershell 调用:
{
"statusLine": {
"type": "command",
"command": "powershell -NoProfile -File C:/Users/username/.claude/statusline.ps1"
}
}
对应的 PowerShell 脚本:
$input_json = $input | Out-String | ConvertFrom-Json
$cwd = $input_json.cwd
$model = $input_json.model.display_name
$used = $input_json.context_window.used_percentage
$dirname = Split-Path $cwd -Leaf
if ($used) {
Write-Host "$dirname [$model] ctx: $used%"
} else {
Write-Host "$dirname [$model]"
}
WarningGit Bash 会把未加引号的反斜杠当转义字符,所以 Windows 风格路径(如
C:\Users\username\script.sh)在command字段里要用正斜杠写:C:/Users/username/.claude/statusline.sh。~快捷方式也有效,会展开到你的 Windows 主目录。
状态栏的运行机制
了解几个关键点,调试时不抓瞎:
什么时候更新:你的脚本在每条新的助手消息之后、/compact 完成后、权限模式变更时或 vim 模式切换时运行。更新有 300ms 防抖,快速变更会批量处理。如果脚本还在跑时又触发了更新,正在跑的那个会被取消。
能输出什么:多行(每个 echo 一行)、ANSI 颜色(如 \033[32m 是绿色)、可点击链接(OSC 8 转义序列,需要 iTerm2、Kitty、WezTerm 等支持的终端)。
终端大小:Claude Code 捕获脚本输出而非直接连终端,所以 tput cols 在脚本里读不到终端宽度。改读 COLUMNS 和 LINES 环境变量——Claude Code 在跑脚本前会设好这俩值(需要 v2.1.153+)。
信任要求:状态栏命令只在接受了当前目录的工作区信任对话框后才会跑。没接受信任时你会看到 statusline skipped · restart to fix,重启 Claude Code 并接受信任提示就行。
小结
- 输出样式改「怎么说」:四种内置(默认/Proactive/Explanatory/Learning),能自己写 Markdown 文件扩展,用
/config切换 - 状态栏是终端底部的自定义监控条:用
/statusline一句话生成,或手动写 shell 脚本 - 状态栏数据:模型、上下文用量、成本、git 状态、速率限制等都能拿到,注意用兜底处理 null
- Windows:路径用正斜杠,PowerShell 脚本用
powershell -File调用 - 性能:慢操作要缓存,脚本要快,否则状态栏会卡
下一章讲 IDE 集成——怎么把 Claude Code 塞进 VS Code、Cursor、JetBrains 里,在编辑器里直接用。