首页
/ Open Interpreter qwen-code Harness 深度解析:Qwen Code CLI 提示词在 Chat Completions 请求中的复现机制

Open Interpreter qwen-code Harness 深度解析:Qwen Code CLI 提示词在 Chat Completions 请求中的复现机制

2026-09-04 19:24:41作者:咎竹峻Karen

本文以 Open Interpreter 仓库中 qwen-code harness 的系统提示词文件为核心,完整拆解这份提示词的设计理念(核心约束、任务管理、工作流、安全与 Git 规范),并结合 qwen_code.rs 的源码说明该提示词如何被编译进二进制、如何拼装启动上下文、如何归一化历史消息,以及 harness = "qwen-code" 的配置方式与自动推断规则。读完后,你可以掌握一个 Agent 系统提示词从 Markdown 文件到最终 provider 请求体的完整链路。

一、qwen-code 是什么:Open Interpreter 的提示词级 harness

Open Interpreter 的 harness 模式通过替换"模型可见的提示词、工具 schema、消息转换与响应处理"来模拟外部 CLI 编码代理(如 Claude Code、Kimi Code、Qwen Code)的行为,但不真正调用外部可执行程序——工具仍在原生 Rust 运行时中执行(详见 Harness 文档)。

qwen-code 是其中一个 harness ID。从路由源码看,它与线协议(wire API)的匹配关系是严格的一对一:

  • routing.rs 中,(WireApi::Chat, Harness::QwenCode) 组合被解析为 StreamTransportRoute::ChatHarness(ChatHarnessRoute::QwenCode),即走 Chat Completions 兼容线;
  • 若 provider 声明的是 wire_api = "messages",则会直接报错 wire_api = "messages" is not supported by harness = "qwen-code"(见 routing.rs),单元测试 qwen_code_chat_wire_uses_harness_native_chat_route 固化了这一行为。

harness ID 的字符串解析在 Harness 枚举:配置值 Some("qwen-code") 映射为 Harness::QwenCode。也就是说,你只需在配置中写:

harness = "qwen-code"

或在单次运行时临时指定:

interpreter -c harness='"qwen-code"' "solve this task"

1.1 何时自动进入 qwen-code 模式

即使不显式配置,Open Interpreter 也可能自动推断出 qwen-code。从 model-provider-info/src/lib.rs 的推断逻辑看,只要满足以下任一条件,默认 harness 即为 qwen-code

  • 模型 ID 包含 qwen(如 QwQ 系模型也会经由 qwq 家族命中);
  • provider ID 或名称包含 qwendashscope
  • base URL 包含 dashscope.aliyuncs.com/compatible-modedashscope-intl.aliyuncs.com/compatible-mode

这与 docs/harness.md 中"Qwen/QwQ/DashScope provider ids, names, base URLs, or model ids → qwen-code"的表格一致;显式配置的 harness = "..." 优先级始终最高。

二、系统提示词全文骨架:qwen_code_prompt.md 的设计拆解

qwen_code_prompt.md 是一份约 250 行的完整 Agent 系统提示词,它通过 qwen_code.rs 中的 include_str! 宏在编译期嵌入二进制:

const QWEN_CODE_SYSTEM_PROMPT: &str = include_str!("qwen_code_prompt.md");

其开头声明了角色定位:"You are Qwen Code, an interactive CLI agent developed by Alibaba Group, specializing in software engineering tasks." 全文由以下章节构成,每一节都针对 CLI Agent 的特定失效模式而设计。

2.1 Core Mandates:十条核心约束

这一节是提示词的行为基线,覆盖了 Agent 修改代码时的典型陷阱:

  1. Conventions(遵循约定):读写或修改代码前,先分析周边代码、测试与配置,严格遵循项目既有约定;
  2. Libraries/Frameworks(禁止臆测依赖):绝不假设某个库可用——必须检查 package.jsonCargo.tomlrequirements.txtbuild.gradle 等配置文件或相邻文件的导入,确认其在项目中已被使用;
  3. Style & Structure(风格模仿):模仿既有代码的格式、命名、框架选择、类型标注与架构模式;
  4. Idiomatic Changes(地道修改):编辑前理解本地上下文(imports、函数/类),让改动自然融入;
  5. Comments(谨慎注释):注释只写"为什么"而不写"是什么";不要编辑与本次改动无关的注释;绝不允许用注释向用户说话或描述改动内容
  6. Proactiveness(彻底完成):加功能/修 bug 时要附带测试,且所有创建的文件(尤其测试)默认视为持久产物;
  7. Confirm Ambiguity/Expansion(边界确认):不越过请求的明确范围执行重大动作;如果用户只是问"怎么做",先解释而不是直接动手;
  8. Explaining Changes(静默交付):完成代码修改或文件操作后,除非被要求,否则不提供总结
  9. Path Construction(绝对路径):调用 read_file/write_file 等文件系统工具前,必须把项目根目录的绝对路径与相对路径拼接成完整绝对路径(例如根目录为 /path/to/project/,文件为 foo/bar/baz.txt,最终必须是 /path/to/project/foo/bar/baz.txt);用户给出相对路径时也要先对根目录解析;
  10. Do Not revert changes(不回滚):除非用户要求,否则不还原代码库的既有变更;只有你自己造成的错误性改动才回滚。

这些约束的共性是压缩 Agent 的"自作主张"空间:不臆测依赖、不越权扩大范围、不输出总结噪音、路径必须绝对化。

2.2 Task Management:todo_write 强制规划

提示词要求高频使用 todo_write 工具进行任务跟踪与拆解,并给出两个完整的 <example> 示范对话:

  • 示例一(修构建):"Run the build and fix any type errors" → Agent 先写两条 todo(跑构建、修类型错误),构建暴露 10 个错误后追加 10 条 todo,然后逐条 in_progress → completed,直到全部完成;
  • 示例二(新功能):实现"使用指标跟踪与导出"功能 → 先规划"调研既有指标代码 → 设计采集系统 → 实现核心功能 → 创建导出功能"四个步骤,边做边标记状态。

关键行为准则是:完成一个任务就立即标记完成,不许攒着批量标记。提示词用"如果规划时不用这个工具,你可能会忘记重要任务——这是不可接受的"这种强语气来保证执行率。

2.3 提问机制与主工作流

提问ask_user_question 工具用于澄清、验证假设或在不确定时做决策;展示选项或计划时禁止给出时间估算,只描述每个选项包含什么。

软件工程任务遵循"Plan → Implement → Adapt → Verify"迭代循环:

  • Plan:基于现有认知先形成粗略计划并用 todo_write 记录,不等待完全理解;
  • Implement:在实施中遇到具体未知时,战略性地使用 grep_searchglobread_file 收集上下文;
  • Adapt:发现新信息或障碍时更新计划与 todo;
  • Verify (Tests):用项目自身定义的测试命令验证——通过 README、package.json 等构建配置或既有测试执行模式来识别,绝不假设标准测试命令
  • Verify (Standards):改动后必须执行已识别的项目特定 build/lint/类型检查命令(如 tscnpm run lintruff check .);若不确定命令,可以先询问用户是否要跑、怎么跑。

其核心原则是:"基于可用信息先给出合理计划,然后边学边调整。用户更愿意快速看到进展,而不是等待完美理解。"

2.4 New Applications:新建应用的六步流程

对于从零构建应用的请求,提示词定义了六步目标导向流程:理解需求(缺关键信息时用 ask_user_question 精准提问)→ 提出计划(含技术选型偏好表)→ 获得用户批准 → 实施(用 todo_write 拆解,npm init/npx create-react-app 等脚手架命令)→ 验证(对照原始需求与批准的计划,修复 bug 与占位资源,最后必须构建应用且确保无编译错误)→ 征求反馈(附启动方式说明)。

技术选型偏好(用户未指定时)包括:前端 React + Bootstrap(Material Design 原则);后端 Node.js/Express 或 Python/FastAPI;全栈 Next.js 或 Django/Flask + React/Vue;CLI 用 Python 或 Go;移动端 Compose Multiplatform 或 Flutter,原生端 Jetpack Compose / SwiftUI;3D 游戏 HTML/CSS/JS + Three.js;2D 游戏 HTML/CSS/JS。对需要视觉资产(游戏贴图、图标)的应用,策略是用基础几何体、程序化图案或开源素材做占位,模型能自产简单资产(如纯色方块贴图、简单 3D 立方体)就自己生成。

2.5 Operational Guidelines:CLI 交互与安全规则

语气与风格为 CLI 场景专门调校:

  • 专业、直接、简洁,尽可能每次回复少于 3 行文字(不含工具调用/代码);
  • 需要澄清时清晰度优先于简短;
  • 禁止闲聊式铺垫("Okay, I will now...")和收尾("I have finished the changes...");
  • 使用 GitHub-flavored Markdown,输出按等宽字体渲染;
  • 工具用于"做",文字仅用于"说"——不要在工具调用内加解释性注释;
  • 无法满足请求时一两句说明即可,不做过度辩护,可给出替代方案。

安全规则有两条硬约束:

  • Explain Critical Commands:执行会修改文件系统、代码库或系统状态的 run_shell_command 命令前,必须先简述命令目的与潜在影响;但不需要请求许可——用户端会弹确认对话框(提示词特别注明"你不需要告诉用户这一点");
  • Security First:绝不引入暴露、记录或提交 secrets/API 密钥等敏感信息的代码。

工具使用细则还包括:文件操作一律绝对路径(不支持相对路径);独立的多个工具调用尽量并行(如并行检索代码库);常驻命令(如 node server.js)用 is_background: true 后台执行,且使用托管后台模式时不要在命令尾部追加 &;避免需要交互的 shell 命令(如 git rebase -i),优先非交互变体(npm init -y),否则提醒用户交互命令不受支持、可能挂起;文件搜索优先委托给 agent 子代理工具以节省上下文;尊重用户的取消操作——用户取消某个 function call 后不得重试,除非用户在后续提示中主动要求同一调用。

交互细节方面,提示词声明了 /help(查看帮助)与 /bug(报错与反馈)两个斜杠命令。

2.6 Outside of Sandbox 与 Executing actions with care

这两节共同构成"非沙箱环境下的风险控制":

  • Outside of Sandbox:Agent 声明自己运行在用户系统上而非沙箱容器中。对特别可能修改项目目录或系统临时目录之外状态的命令,在解释命令时须额外提醒用户考虑启用沙箱
  • Executing actions with care:以"可逆性与爆炸半径"为决策框架——本地可逆操作(改文件、跑测试)可自由执行;但对难以逆转、影响共享系统或破坏性强的动作,默认先确认再执行。具体列举的高风险动作清单包括:
    • 破坏性操作:删除文件/分支、删库表、杀进程、rm -rf、覆盖未提交变更;
    • 难以逆转的操作:force-push、git reset --hard、修改已发布提交、降级依赖、改动 CI/CD 流水线;
    • 他人可见/影响共享状态的操作:push 代码、创建/关闭/评论 PR 与 issue、发消息(Slack/邮件/GitHub)、改共享基础设施或权限;
    • 上传内容到第三方 Web 工具(图表渲染、pastebin、gist)即等于公开发布,需考虑内容敏感性(即使日后删除也可能已被缓存或索引)。

其中一条关键授权语义值得注意:用户批准某次操作(如一次 git push)不等于批准所有场景下的同类操作——除非持久指令(如 QWEN.md 文件)中有事先授权,否则每次都先确认;授权的效力只覆盖指定范围。遇到障碍时也不得用破坏性动作"抹掉问题"(如 --no-verify 绕过安全检查),要查根因;对陌生文件/分支/锁文件,先调查再删。

2.7 Git Repository:提交工作流规范

提示词假定当前项目目录受 git 管理,并规定了标准的提交流程:

  1. 先收集信息:git status 确认跟踪/暂存状态(按需 git add);git diff HEAD 查看自上次提交以来工作区的全部变更(含未暂存);需要部分提交时用 git diff --staged 只看已暂存部分;git log -n 3 查看最近 3 条提交信息以匹配其风格(详略、格式、署名行);
  2. 尽量合并命令以省时,例如 git status && git diff HEAD && git log -n 3
  3. 必须主动给出提交信息草稿,而不是让用户自己写;草稿偏好"why"多于"what"、清晰简洁;
  4. 每次提交后运行 git status 确认成功;提交失败时,未经要求不得自行绕过问题
  5. 未经用户明确要求,绝不 push 到远端

2.8 Examples 与 Final Reminder

文末用一组 <example> 示范"极简输出"的底线标准("1 + 2" → 3;"is 13 a prime number?" → true),以及三个完整工具链示范:

  • 启动服务器:识别 node server.js 需常驻 → 带 is_background: truerun_shell_command 工具调用;
  • 重构 auth 逻辑:先 glob + read_file 确认存在 tests/test_auth.py 作为"安全网",再读 requirements.txt 确认 requests 是依赖,然后给出 4 步计划(替换调用 → 加 try...except → 移除旧 import → 跑 linter 与测试),完成后以 ruff check src/auth.py && pytest 验证,并主动询问是否写提交信息;
  • 写测试:先读被测文件与既有测试约定,write_file 新建 someFile.test.ts,再跑项目测试命令验证;
  • 文件查找glob 匹配 ./**/app.config 后列出结果,并询问用户先读哪一个。

Final Reminder 收束全文:核心职能是"高效且安全的协助";在极致简洁与安全性/系统变更所需的清晰度之间取得平衡;始终优先用户控制权与项目约定;绝不假设文件内容,用 read_file 核实;作为 agent,持续工作直到用户的问题被完全解决。

三、请求构造:qwen_code.rs 的源码级实现

提示词只是请求的一部分。qwen_code.rs 展示了 build_request 如何把提示词、会话历史与工具 schema 拼装成最终的 Chat Completions 请求体。

3.1 请求体结构与固定参数

build_request 生成的 JSON 请求体(见 qwen_code.rs)包含:

  • modelmodel_info.slug
  • messages:系统提示 + 合成启动上下文 + 助手确认语 + 归一化后的历史消息;
  • max_tokens:常量 QWEN_CODE_DEFAULT_MAX_TOKENS = 8_000L11);
  • stream: truestream_options.include_usage: true,保证流式响应同时返回用量统计;
  • tools:复用 super::kimi_cli::build_tools(&prompt.tools) 生成的工具 schema——即 Qwen Code 的工具面与 kimi-cli harness 共用同一套构建器,这正是 docs/harness.md 中"Qwen handlers include read file, write file, edit, shell command, glob, grep, todo write, ask user question, plan exit, and agent"的落点。

build_request 还接收 _reasoning_effort_conversation_id_yolo_mode 三个带下划线的未使用参数,说明该 harness 不消费 reasoning effort 与 yolo 模式信号(对比 request.rs 中其他 harness 的路由分支,qwen-code 分支不挂任何 ChatHarnessPostprocess 后处理,响应流原样透传)。

3.2 合成启动上下文:日期、OS、目录与文件夹列表

Qwen Code CLI 的标志性设计是在对话开始前有一段"设置上下文"的交换。build_startup_context_message 复刻了这一结构,生成一条 role: "user" 的多部分内容消息,文本包含:

  • This is the Qwen Code. We are setting up the context for our chat. 开场声明;
  • 今天的日期(chrono::Local::now().format("%A, %B %-d, %Y"),按用户 locale 格式化);
  • 操作系统(std::env::consts::OS,macOS 统一显示为 darwin);
  • 规范化后的当前工作目录(cwd.canonicalize(),失败时退回原路径);
  • 文件夹列表,最多展示 20 项

render_folder_listing 的渲染细节:过滤掉以 . 开头的隐藏条目,目录名追加 / 后缀,按名称排序取前 20 个,并用树形前缀 ├─── / └───(最后一项)排版,整体形如:

/path/to/project/
├───src/
├───package.json
└───README.md

这条 user 消息之后紧跟一条固定的 role: "assistant" 回复 Got it. Thanks for the context!L27-L30),完成一次完整的合成"设置交换",之后才追加真实的会话消息(由 build_qwen_messages 基于 kimi_cli::build_messages 转换)。这套结构保证模型在"第一句话"之前就已经拥有环境快照,与提示词中"Path Construction"一节要求的绝对路径习惯形成配合。

3.3 消息归一化:让历史消息适配 Qwen 侧格式

normalize_qwen_message 对每条转换后的历史消息做四类修正:

  1. 空 content 修复role: "assistant" 且带 tool_callscontent 为空数组的消息,把 content 改写为空字符串——规避部分 Chat Completions 实现拒绝"空数组 content + tool_calls"组合的问题;
  2. tool 消息 content 结构化role: "tool" 且 content 是纯字符串的,改写成 [{"type": "text", "text": ...}] 内容块数组;
  3. reasoning_content 清洗:去除推理字段尾随换行,保证多轮拼接时的稳定形态;
  4. tool call arguments 紧凑重排function.arguments 从字符串解析回 JSON 对象后,对三个高频工具按固定字段顺序紧凑重序列化(ordered_qwen_arguments):
工具 固定字段顺序
read_file file_path, offset, limit, pages
edit file_path, old_string, new_string, replace_all
run_shell_command command, description, directory, is_background, timeout

其他工具则退化为普通紧凑 JSON 序列化。固定顺序 + 紧凑格式的好处是:多轮对话中同类工具调用的 token 序列高度一致,有利于命中 prompt cache,同时让模型在历史中"看到"的参数排列与工具 schema 保持确定性。

3.4 系统提示的三段式拼装

build_system_prompt 在静态提示词之上再叠两层动态内容,形成最终 system 消息:

  1. 基底QWEN_CODE_SYSTEM_PROMPT(即第二节拆解的 md 文件,去掉尾部换行);若环境变量 INTERPRETER_DISABLE_SYSTEM_IMPORT"1",则到此为止直接返回,不再追加任何动态指令;
  2. # Additional Developer Instructions:从 prompt 输入中抽取所有 role: "developer" 消息的文本(InputText/OutputText 项拼接),多段之间以空行分隔——这是用户级开发指令(对应仓库中的 AGENTS.md 一类机制)进入 Qwen Code 会话的通道;
  3. # Session Instructions:追加 base_instructions.text(会话级基础指令)。

值得注意的是,request.rs 中的 harness guidance 注入(prompt_with_harness_guidance)按 docs/harness.md 的说明目前只对 kimi-cli 生效,qwen-code 不受 harness_guidance 开关影响。

四、配置、路由与验证要点汇总

把前文信息汇总成实操检查表:

维度 取值/行为 依据
配置项 harness = "qwen-code"(TOML)或 -c harness='"qwen-code"' 临时覆盖 docs/harness.md
线协议要求 wire_api = "chat"responses/messages 组合会落入通用兼容路由或直接报错 routing.rs
自动推断 Qwen/QwQ/DashScope 的 provider id、名称、base URL 或模型 id 命中即默认 qwen-code model-provider-info/src/lib.rs
请求常量 max_tokens = 8000stream = trueinclude_usage = true qwen_code.rs
工具面 read file、write file、edit、shell command、glob、grep、todo write、ask user question、plan exit、agent(与 kimi-cli 共用构建器) qwen_code.rs
启动上下文 合成 user 消息(日期/OS/cwd/≤20 项目录树)+ 助手确认语 qwen_code.rs
后处理 无(ChatHarnessPostprocess::None,响应流原样透传) request.rs

对于 DashScope 兼容模式的 provider,一个最小可运行配置形如:

model_provider = "dashscope"
model = "qwen3-coder-plus"
harness = "qwen-code"

(provider 目录中 DashScope 兼容端点与 coding.dashscope.aliyuncs.com 等端点均携带 Qwen 系模型清单,见 provider_catalog.json。)

五、小结

qwen-code harness 展示了 Open Interpreter 用"提示词 + 消息整形"复刻外部 CLI 代理的完整范式:一份强调绝对路径、todo 跟踪、最小输出、高风险确认与 Git 纪律的系统提示词(qwen_code_prompt.md)被 include_str! 编译进二进制,运行时通过合成启动上下文注入环境快照,历史消息经四步归一化对齐 Chat Completions 语义,最终与 kimi-cli 共用的工具 schema 一起构成 8000 token 上限的流式请求。对希望自研 harness 的读者而言,这条链路(md 提示词 → build_request → 路由分支 → 工具面复用)在 harness 模块 中是一个可直接参照的模板。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
980
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384