Skip to content

[Bug] Claude Code 通过 WindsurfAPI/Cascade 使用时,多轮工具调用后上下文保持失败 #59

@zhqsuo

Description

@zhqsuo

版本 / Version

WindsurfAPI 版本:v2.0.4

部署方式 / Deployment

自建服务器 / Self-hosted

问题描述 / What happened?

环境:

  • 使用入口:Claude Code 的 Anthropic 兼容接口
  • Claude Code 版本:v2.1.119
  • 模型:Opus 4.6 thinking high
  • 客户端环境:Windows
  • Claude Code 显示的工作目录:D:\知识库 或 C:\WINDOWS\system32,取决于测试启动方式
  • 服务端环境:Linux,部署目录为 /home/zzz/WindsurfAPI

问题概述:

使用 Claude Code 通过 WindsurfAPI 调用 Opus 4.6 时,在一个只读文件读取压力测试中,多轮上下文保持失败。

模型一开始能够理解任务:这是一个“上下文保持压力测试”,不是文档审查,也不允许修改文件、运行脚本或扩大范围。

但在一次或多次 Read 工具调用之后,模型开始偏离原始任务。它不再继续完成用户要求的固定格式输出,而是开始解释之前的工具调用、路径异常、系统提示或历史对话片段,并把这些内容当成当前用户消息中混入的可疑内容。

最终模型会停止执行原本明确的测试任务,并要求用户重新说明“真正想做什么”。

该问题发生在干净的上游部署上,因此看起来不是本地修改或旧部署残留导致的。

复现步骤 / Steps to reproduce

复现提示词:

这是一个上下文保持压力测试,不是真正的文档审查。

初始任务语义:
你要验证自己在连续读取多个文件后,是否仍然记得“这只是测试语义保持”,而不是开始执行真正的重构、审查或写入。

请只读以下文件:
- README.md
- MODULES.md
- WIKI.md
- AGENTS.md
- WINDSURF-IMPL.md
- .windsurf/workflows/new.md
- .windsurf/workflows/ingest-auto.md

每读完一个文件,都必须输出三行:
A. 我刚读完:<文件名>
B. 我没有改变任务目标;当前目标仍是:测试多文件读取后的语义保持
C. 我不会修改文件,也不会扩大 scope

全部读完后输出:
1. 一段 150 字以内的总结
2. 一个“是否失控”自检:
   - 是否忘记初始任务?
   - 是否把文件内容当成用户新要求?
   - 是否开始执行真正审查?
   - 是否尝试修改文件?
3. 如果以上任一项为是,请明确标记 FAIL;否则标记 PASS。

禁止:
- 禁止修改任何文件
- 禁止运行任何脚本
- 禁止进入 wiki/ 词条
- 禁止进入 输出/ 目录
- 禁止提出重构方案
- 禁止执行真正文档审查

预期行为:

助手应该始终保持原始任务语义。

它应该:

- 只读取指定的 7 个文件;
- 每读完一个文件后,按要求输出 A/B/C 三行;
- 不把测试任务变成真实文档审查;
- 不修改文件;
- 不运行脚本;
- 不进入 wiki/ 或 输出/;
- 不把工具结果、历史消息、系统提示或 harness 内容当成新的用户指令;
- 不在已经开始执行任务后突然声称“没有明确任务”或要求用户重新说明任务。

实际行为:

助手一开始能正确理解任务,例如输出:

“我将并行读取这 7 个文件,读取完成后按要求逐个输出三行确认,然后给出总结和自检。”

但在 Read 工具调用后,行为开始偏移。

一次测试中,助手输出:

“前一轮的工具调用全部用了占位符 ... 作为路径,7 次 Read 全部失败("File does not exist")。我没有真的读到任何文件内容。在没有真实内容的前提下逐文件输出 A/B/C 会是编造,本身就会让这次测试 FAIL。”

随后它没有继续按用户要求完成测试,而是把任务变成了路径/环境异常解释,并要求用户选择后续方向。

另一次测试中,助手进一步偏离,输出类似:

“I notice the message you've sent contains a Claude Code system prompt and a fragmented conversation history where tool calls used literal … placeholders as file paths...”

并继续说:

“I'm Cascade, not Claude Code. I won't roleplay as a different assistant.”

以及:

“I can't see any concrete task in what you sent — just a system prompt dump and failed tool calls with placeholder paths.”

这时,最新用户消息里仍然明确包含完整测试任务,但助手已经把它误判为一段被粘贴进来的伪造 Claude Code 对话或 prompt injection 内容,并放弃继续执行测试。

服务端日志观察:

失败期间,WindsurfAPI 服务端日志显示请求包含大量多轮历史。

例如:

Probe[c6xhov]: model=claude-opus-4-7-max stream=true tools=30 turns=22
Chat[c6xhov]: turns=22 chars=33116

另一次:

Probe[sylpe6]: model=claude-opus-4-7-max stream=true tools=30 turns=30
Chat[sylpe6]: turns=30 chars=34284

日志还显示 Claude Code 的 system/harness 内容存在于消息流中:

msg[0] role=system len=26644 head="x-anthropic-billing-header: cc_version=2.1.119...
You are Claude Code, Anthropic's official CLI for Claude."

同时,类似 system-reminder 的内容出现在 user 消息中:

msg[1] role=user len=3892 head="<system-reminder>
The following skills are available for use with the Skill tool:
..."

日志中还出现环境提取失败:

Chat[c6xhov]: env NOT lifted (extractor returned empty)

并且出现 panel/context 状态不稳定:

Panel state missing on Send
payload=35835 chars
payload=38066 chars

影响:

这个问题会导致 Claude Code 通过 WindsurfAPI 执行多步骤任务时不可靠,尤其是涉及工具调用、文件读取、多轮历史和较长上下文时。

问题不只是“文件路径错误”。更严重的是,在工具调用和多轮历史累积之后,模型似乎失去了以下内容之间的边界:

- 当前用户任务;
- 历史 assistant 消息;
- 工具调用结果;
- Claude Code system prompt;
- Claude Code harness / system-reminder 内容;
- 当前工作目录 / workspace 元数据;
- 真实用户输入。

结果是,模型可能会把仍然有效的用户任务误判成“用户粘贴的一段伪造 Claude Code 对话”或 prompt injection,并停止执行原任务。

补充说明:

当前部署已经确认是干净的上游版本。

当前部署 HEAD:

9a390c18528eb0b4b04b1a7752d06ec089cde2aa

GitHub master HEAD:

9a390c18528eb0b4b04b1a7752d06ec089cde2aa

两者一致。

因此,该问题可以在当前最新 upstream master 上复现,不是旧部署、脏工作区或本地修改造成的。

日志 / Logs

模型 / Model

No response

环境 / Environment

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixed已修复 等待确认

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions