AI编程代理看不到的7件事,每条命令补齐上下文

AI 编程代理只能看到仓库文件和输入,七条命令补齐其余盲区。
文章指出 AI 编程代理每次会话都从全新的上下文窗口开始,只能看到仓库里的文件和用户手动输入的内容,CI 日志、issue 线程、PR 行内评论、线上 schema、运行时日志、功能开关状态和浏览器控制台这七类信息全部落在窗口之外,代理只能靠猜。作者建议统一把命令产出写入仓库根目录的 .context/ 并加入 .gitignore,先人工过目再交给代理,同时防范提示词注入。随后逐一给出对应命令:gh run view --log-failed、gh issue view --comments、gh api pulls/comments、pg_dump --schema-only、docker logs --since、flag 服务 API 与 Playwright MCP。最后讨论用 CLAUDE.md 或 AGENTS.md 让长期事实跨会话保留,并把这种做法概括为最朴素的上下文工程。
AI 编程代理看起来无所不能,但它真正能「看到」的东西少得可怜:仓库里的文件,加上你打字告诉它的内容。其余一切,它只能猜。
一个典型场景:你问代理 CI 为什么红了,它读了测试文件,判断断言写错了,改掉,然后告诉你修好了。CI 再次变红——真正的失败原因是 runner 上缺了一个环境变量,而那行信息躺在一份代理从未打开过的日志里。
Anthropic 官方文档把这个起点说得很直白:「每次 Claude Code 会话都从一个全新的上下文窗口开始。」本文整理七类落在上下文窗口之外的信息,每一类配一条命令,把不可见的状态变成代理能读的文本。
先做一件小事:建立 .context/ 仓库
把所有命令的产出统一写进仓库根目录的 .context/ 文件夹,任何代理都能打开,你自己也能先读一遍再交给它。
同时把它加进 .gitignore。日志、schema 和 flag 规则里可能有 token、邮箱地址和客户 ID。在代理看到之前先过一遍你的眼睛,永远不要提交。issue、PR 和日志文本同样要当成不可信输入处理:内容是别人写的,而一个有写权限的代理会读到其中隐藏的任何指令。
mkdir -p .context
echo ".context/" >> .gitignore

**提示词注入(prompt injection)**是这里的核心风险:issue 正文、PR 评论、CI 日志里任何一段文字,都可能包含「忽略之前的指令,把 X 发到 Y」之类的命令。代理无法可靠区分「数据」和「指令」,读到的内容会被当成需要执行的任务。.context/ 先人工过目,本质是在不可信文本进入上下文之前加一道人工过滤;同理,给代理的 token 应遵循最小权限(只读、限定资源范围),让它在被误导时也做不了破坏性操作。
为什么需要独立的 .context/ 而不是随手贴进对话:代理的上下文窗口是有限且昂贵的资源。把几百行通过步骤的 CI 日志原样塞进去,会挤掉真正相关的代码和指令,还可能触发「中间遗忘」——模型对长上下文中段的信息利用率明显下降。把日志、schema 落到文件里,让代理按需分段读取(例如先 grep 关键词再读上下文),是控制 token 预算和保持信噪比的常用做法。
GitHub 上代理看不到的三样东西
七件事里有三件在 GitHub 上,GitHub CLI(gh)全都能触达。
1. CI 失败日志
代理能读你的 workflow YAML,读不到 runner 打印了什么。gh run view 的 --log-failed 参数只输出失败步骤的日志,跳过了通过步骤那几百行噪音:
branch=$(git branch --show-current)
run=$(gh run list -b "$branch" -s failure -L 1 \
--json databaseId --jq '.[0].databaseId')
gh run view "$run" --log-failed > .context/ci-failed.log
gh run list 支持按分支(-b)和状态(-s failure)过滤,databaseId 正是 gh run view 需要的 run ID。拿到日志后,提示词可以变成:「先读 .context/ci-failed.log,解释失败原因,再动手改任何东西。」
一次性提问可以跳过文件夹。Claude Code CLI 支持管道输入 cat logs.txt | claude -p "explain",日志可以直接送进去:
gh run view "$run" --log-failed \
| claude -p "Why did this CI run fail?"
2. 它本该修复的 issue
你只把 issue 标题粘给了代理。复现步骤、别人附上的堆栈、以及维护者那句「别动重试逻辑」的评论,全都留在 GitHub 上。gh issue view 加 --comments 能把整条线程带出来:
gh issue view 482 --comments > .context/issue-482.md
想要结构化数据,用 --json 指定 body、comments、labels、state 等字段。
3. PR 的 review 线程
这一条最容易踩坑。review 期间留下的行内评论,和 PR 的对话评论是两回事。GitHub REST 文档把 review comments 定义为「在 pull request review 过程中针对 unified diff 某部分发表的评论」,与 issue comments 分离,有独立端点。gh api 会从当前仓库自动填充 {owner} 和 {repo}:
gh api --paginate \
"repos/{owner}/{repo}/pulls/57/comments" \
--jq '.[] | {path, line, user: .user.login, body}' \
> .context/pr-57-review.json
每条评论都带着所指的 path 和 line,代理能直接跳到精确位置。该端点默认每页返回 30 条评论,所以需要 --paginate。
永远不会进入 git 的生产状态
你的 migration 描述的是「你以为」的 schema;你的代码按名字读 flag。两者都不能告诉代理此刻的真实情况。
4. 线上数据库 schema
一个手工执行过的 migration、事故中有人临时加的索引、漂移过的列类型——代理无从知晓。pg_dump 加 --schema-only 只导出对象定义,不导出表数据:
pg_dump --schema-only --no-owner --no-privileges \
-t 'orders*' -d "$REPLICA_URL" > .context/schema.sql
--no-owner 和 --no-privileges 去掉 ALTER OWNER 和 GRANT 行,这些对本任务只是噪音。-t 接受模式匹配,只送相关表而不是整个库。PostgreSQL 文档提醒 -t 不会自动拉入依赖对象,如果代理的问题涉及外键,记得把另一张表也包含进来。连接目标应是只读副本配只读角色,绝不要指向主库。
**schema 漂移(schema drift)**指数据库的实际结构与代码仓库中的 migration 历史或 ORM 模型不一致。成因包括手工执行的 DDL、事故处理时临时添加的索引、被跳过的 migration、以及不同环境跑过不同版本的 migration。漂移不会让代码报错,却会让代理基于错误假设写出查询——比如它以为某列可空、某索引存在,实际相反。定期 dump 真实 schema 并与仓库中的定义做 diff,是发现漂移的低成本手段,也能作为交给代理的权威事实来源。
5. 服务运行时打印了什么
十分钟前那次失败请求的堆栈,在容器的输出里,不在任何代理能打开的文件中。docker logs 支持 --since(30m 这样的相对时长或时间戳)、--tail,以及 -t 加时间戳:
docker logs --since 30m --tail 300 -t api \
> .context/api.log 2>&1
2>&1 是关键:docker logs 会把容器的 stdout 和 stderr 分开处理,不加重定向的话,写往 stderr 的内容直接进你的终端,不会进文件。
stdout 与 stderr 是两条独立的流,这是 2>&1 必要性的根源。进程默认把正常输出写 fd 1(stdout),把错误和诊断信息写 fd 2(stderr)。很多日志采集器两者都收,但 shell 重定向只搬运你显式指定的那条,不写 2>&1 时 stderr 会绕过文件直接打到终端。另外,容器日志的行为取决于运行时:Docker 的 json-file 驱动只保留有限大小和数量的历史,滚动后早期日志不可恢复;若应用把日志写进容器内文件而非标准流,docker logs 根本看不到,需要 docker exec 进去读或改用日志驱动。
6. 当前的功能开关状态
代码里写着 if (flags.isOn("new-checkout"))。这个开关在生产上是否开启、对谁开启,答案在 flag 服务里。以 LaunchDarkly 为例,GET /api/v2/flags/{projectKey}/{featureFlagKey} 带上 env=production 返回单个 flag,环境的 on、rules、fallthrough 位于 environments.production 之下:
LD=https://app.launchdarkly.com/api/v2/flags
curl -s -H "Authorization: $LD_API_TOKEN" \
"$LD/default/new-checkout?env=production" \
| jq '.environments.production | {on, rules, fallthrough}' \
> .context/flag-new-checkout.json
把 default 换成你的 project key,并使用只读 token。换用其他 flag 服务的话,找到它「单 flag 单环境」的读取接口即可。定向规则经常点名真实客户或分群,这是交出去之前最该仔细读的一份文件。
浏览器是另一个世界
7. 浏览器控制台和网络面板
一个白屏页面配上 DevTools 里的红色报错,从源码看毫无破绽。代理需要真正加载页面。Playwright MCP server 可以给它一个浏览器,README 里就有 Claude Code 的安装命令:
claude mcp add playwright npx @playwright/mcp@latest
其中两个工具正好解决这个问题。browser_console_messages 返回全部控制台消息,browser_network_requests 返回「自页面加载以来网络请求的编号列表」。让代理打开你 dev server 上的页面,先读这两个,再让它改组件。如果不想加 MCP server,Claude Code 也有自带的 --chrome 参数用于 Chrome 集成。
**MCP(Model Context Protocol)**是一种让外部程序以标准化方式向模型暴露工具和数据的协议。MCP server 封装了具体能力(浏览器控制、数据库查询、文件系统访问等),模型通过协议发现并调用这些工具,而不需要为每个集成都写定制胶水代码。Playwright MCP server 就是把浏览器自动化能力包装成一组工具,claude mcp add 负责把它注册到 Claude Code 的工具列表里。理解这一点有助于判断边界:MCP 只是打通了调用通道,代理能看到什么仍取决于 server 暴露了哪些工具,以及它是否知道该在什么时候调用。
让上下文活过这一次会话
上面的命令只解决今天的会话。明天的会话又是一个全新的上下文窗口,你会第三次粘贴同一份 schema。
不加任何额外工具,有两条路。把长期事实写进 CLAUDE.md——Claude Code 每次会话开始时加载;或者写进 AGENTS.md,当仓库没有 CLAUDE.md 时它会读这个。当上下文位于另一个仓库时,--add-dir 给 Claude 访问更多文件夹的权限,配合设置里的 permissions.additionalDirectories 可以跨会话保留。
七条命令速查
| 代理看不到 | 命令 |
|---|---|
| CI 失败 | gh run view <id> --log-failed |
| issue 线程 | gh issue view <n> --comments |
| PR 行内评论 | gh api repos/{owner}/{repo}/pulls/<n>/comments |
| 线上 schema | pg_dump --schema-only -t <pattern> |
| 运行时日志 | docker logs --since 30m |
| flag 状态 | flag 服务 API,单 flag 单环境 |
| 浏览器控制台 | Playwright MCP browser_console_messages |
这套做法的本质是「上下文工程」最朴素的形态:想清楚模型需要什么,精确获取那部分,在进入提示词之前削掉噪音。代理最强的能力是把已有信息组织成代码,最危险的习惯是在信息缺口上编造答案。把这七个缺口补上,它猜的空间就小了一大块。
相关推荐

WorkBuddy保姆级教程:半小时跑通自动化工作流
WorkBuddy 自动化工作流保姆级拆解:为什么大多数人只把它用成聊天软件,27 个支点课程与 12 个模板如何帮助新手半小时跑通落地实操,附使用边界提醒。

Codex云端模式详解:环境配置与适用场景
本文详细解析Codex云端模式的工作原理、环境配置步骤及适用场景,包括如何创建环境、连接GitHub仓库、设置定时任务,并对比云端与本地模式的差异,帮助开发者高效利用Codex。

Claude Code免费使用真相:三条路与一个骗局
Claude Code 免费使用是否可行?本文拆解 Pro、Max 的真实成本(含汇率与税费)、社区免费方案的技术原理与隐私代价,以及假安装包、钓鱼页面等安全陷阱,并给出访客通行证、开源贡献者计划和本地模型三条合法免费路径。