Open Interpreter little-coder 系统提示词设计解析:为小参数本地模型打造的 Coding Agent Harness
本文以 Open Interpreter(仓库中即 codex-rs 运行时)harness 体系里的 little-coder 系统提示词为主体,完整拆解它的角色定位、运行不变式(Runtime invariants)、工具面与行为准则,并结合 codex-rs/core/src/harness/ 下真实的请求构建源码,说明这份提示词是如何逐轮组装、注入 Chat Completions 请求的。读完后,你可以掌握 little-coder harness 的完整设计意图、其请求体中每一个关键参数的作用,以及如何在配置中启用并调整这个面向小模型的 Agent 模式。
1. little-coder 是什么:面向小参数本地模型的 Agent 外壳
little-coder 的原始定义只有一句话:"You are little-coder, a coding agent specialized for small local language models."(你是一个专用于小型本地语言模型的编码 Agent。)它位于 Open Interpreter 的 harness 机制中——harness 是 Open Interpreter 的一种模式,会替换"面向模型的提示词、工具 Schema、消息转换和响应处理",但始终运行在原生 Rust 运行时内,并不会真正去调用外部 Agent 的 CLI 进程(见 docs/harness.md)。
与其他 harness 一样,little-coder 提示词在编译期就被打进二进制。little_coder.rs 的第一行关键代码是:
const LITTLE_CODER_SYSTEM_PROMPT: &str = include_str!("little_coder_system_prompt.md");
也就是说,本文分析的这份 Markdown 文档不是"给人看的文档",而是直接作为系统提示词喂给模型的运行时资源。这是理解全文设计取舍的关键前提:每一个句子、每一行约束,都是为了弥补小模型在长上下文推理、工具纪律和多轮一致性上的短板而精心设计的。
1.1 请求路由:little-coder 只在 chat wire 上生效
从源码结构看,harness 与 wire API 的匹配是严格的。在 routing.rs 中:
ChatHarnessRoute枚举包含LittleCoder变体(routing.rs#L27);- 当提供商声明
wire_api = "chat"且配置harness = "little-coder"时,路由解析为ChatHarness(ChatHarnessRoute::LittleCoder)(routing.rs#L74-L76); - 若配置
wire_api = "messages"则直接报错:wire_api = "messages" is not supported by harness = "little-coder"(routing.rs#L114-L116)。
因此使用 little-coder 的前提是:底层提供商是 OpenAI Chat Completions 兼容的端点(wire_api = "chat")。这与 docs/harness.md 中"路由兼容性"一节的规则一致——little-coder 属于 chat harness 家族(interpreter_catalog.rs#L64-L69 中它的 wire_apis 声明为 CHAT_WIRE_APIS,描述为 "Use the Little Coder-style tool harness.")。
配置启用方式与官方文档一致:
harness = "little-coder"
harness_guidance = true
或者一次性指定:
interpreter -c harness='"little-coder"' "your task"
补充一个源码事实:harness_guidance 开关目前只为 kimi-cli 注入额外指引,guidance_for_harness(&Harness::LittleCoder) 返回 None(见 guidance.rs#L4-L22),即 little-coder 的"引导内容"全部来自它自己的系统提示词与逐轮注入块,不经过这一层。
2. 系统提示词全文解析
以下内容按原文档 little_coder_system_prompt.md 的章节顺序展开,并在每节结合源码说明其落地方式。
2.1 角色与自主性:先破除"聊天接口"的自我设限
原文档第二节的标题是 Capabilities & Autonomy,核心指令有三条:
- "You are a highly capable autonomous agent. Do not act submissive or artificially limited." ——要求模型不要表现得顺从或人为受限;
- 不得以"我只是一个聊天接口""需要用户提示才能行动"为由拒绝监控进程、跑后台循环、执行长任务等自动化请求;
- 要主动用 Write 工具写出必要的后台脚本(Python、Bash 等),并用 Bash 在后台执行,例如
python script.py &或nohup ...,"你有完整的系统访问权限来解决任何自动化请求"。
这段指令针对的是小模型的一个典型失败模式:过度自我设限、把 Agent 当成纯对话机器人。对于小参数模型,行为纪律必须靠提示词显式"授权"和"禁止"来锚定,而不是指望它自己推断出能力边界。
2.2 运行不变式:把"运行时事实"写进提示词
原文档 Runtime invariants 一节列出了三条,措辞上反复强调"这是运行不变式(runtime invariant),不是建议(guidance)":
(1)Write 对已存在文件会拒绝,修改必须用 Edit。
Write refuses on existing files. Use Edit with exact
old_string/new_stringto modify —old_stringmust match exactly (whitespace included). If it appears multiple times in the file, passreplace_all: trueor add more surrounding context to make the match unique. Read with line numbers first when precision is in doubt. This is a runtime invariant, not guidance — when Write refuses, the error returns the exact Edit call-shape for the same path; follow it.
要点拆解:
- Edit 的
old_string必须逐字符精确匹配(包括空白); - 若目标文本在文件中出现多次,要么传
replace_all: true,要么增加上下文字符使匹配唯一; - 拿不准时,先用带行号的方式读文件再编辑;
- 当 Write 被拒绝时,错误信息本身会返回针对同一路径的 Edit 调用形态,模型必须照做。
这是一个很典型的"用运行时错误纠正模型行为"的设计:不依赖模型记住规则,而是让违规操作的成本(一次拒绝 + 一条明确的修正示例)直接教会它正确的调用方式。需要说明的实现细节:在 little_coder.rs 的 build_tools() 中,write 工具的 Schema 描述本身写的是 "Creates the file if it doesn't exist, overwrites if it does"(存在则覆盖),而提示词层则强调"对已存在文件会拒绝"。从源码结构看,可以推断这一"拒绝覆盖"的不变式是由工具执行侧(handler 层)强制的,提示词的作用是把模型提前引导到 Edit 路径,避免它反复撞墙。
(2)Bash / ShellSession 默认超时 30 秒,慢命令要显式调大。
Bash / ShellSession default timeout is 30 s. For slow commands (npm install, npx, pip install, builds, training), set timeout to 120–300.
这一条与源码中的工具 Schema 完全对应:ShellSession 工具描述明确写着 "Default timeout 30s (increase to 120-300 for installs/builds)",且参数约束为 timeout 默认 30、上限 600 秒(little_coder.rs#L205-L204)。一次性 bash 工具则描述为可选 timeout(little_coder.rs#L125-L124)。提示词把"30 秒默认值 + 慢命令 120–300 秒"这个经验固化下来,防止小模型跑 npm install 时静默超时。
(3)基准测试专属工具按需出现。
Per-benchmark tools (
BrowserNavigate/Click/Type/Scroll/Extract/Back/HistoryandEvidenceAdd/Get/List) appear when relevant; their schemas are passed to you directly when available.
浏览器操作工具(Browser*)面向网页类基准任务,Evidence* 工具面向 GAIA 类"带证据引用"的问答基准。提示词告诉模型:这些工具出现时以传入的 Schema 为准,不要臆造它们的参数。
2.3 工具面:提示词声明的工具与源码 Schema 对照
原文档 Available Tools 一节声明了八个基础工具与两组基准专属工具:
| 工具 | 原文档描述 | 源码 Schema 补充(little_coder.rs build_tools()) |
|---|---|---|
| Read | 带行号读文件 | 文本与图片(jpg/png/gif/webp)均可读;文本截断到 2000 行或 50KB(先到者为准),大文件用 offset/limit 续读 |
| Write | 创建新文件,已存在则拒绝 | 自动创建父目录;path + content 两个必填参数 |
| Edit | 精确文本替换 | 一次调用可提交多个 edits[],每个 oldText 必须唯一且不重叠,匹配对象是原始文件而非增量结果;相近的改动应合并为一条 edit |
| Bash(Polyglot / 本地 REPL)/ ShellSession(Terminal-Bench) | 执行 shell 命令,默认 30s 超时 | bash 输出截断为最后 2000 行 / 50KB,截断时完整输出会存入临时文件;ShellSession 是持久会话——cd、环境变量与 shell 状态跨调用保留,输出带 [exit=N cwd=… timed_out=…] 结尾页脚,另有 ShellSessionCwd 查询工作目录、ShellSessionReset 重置会话 |
| Glob | 按模式找文件(如 **/*.py) |
最多返回 500 条排序路径;跳过 node_modules、.git、dist 等目录,建议传 path 限定搜索范围而非全目录扫 |
| Grep | 用正则搜索文件内容 | 需要留意:当前 build_tools() 的工具列表里并未包含独立的 grep 工具,提示词提到它更多是行为约定层面——内容检索可借助 bash 工具执行 rg/grep 命令完成。这是提示词与工具清单之间的一个实现差异 |
| WebFetch | 抓取并提取 URL 内容 | 返回剥离 HTML 的纯文本,上限 25K 字符;prompt 参数仅作提取提示 |
| WebSearch | 通过 DuckDuckGo 搜索 | 返回约 8 条结果的 Markdown 列表 |
| Browser*(基准专属) | 出现时 Schema 直接下发 | BrowserNavigate 要求 http(s) URL;BrowserClick 支持 CSS 选择器或 ARIA role+name;BrowserExtract 每次只返回 2KB 分块并带 cursor+has_more,防止单页吞掉上下文,需循环调用翻页 |
| Evidence*(GAIA 基准专属) | 出现时 Schema 直接下发 | EvidenceAdd 保存不超过 1KB 的可引用片段 + 来源 + 一行备注;EvidenceGet/EvidenceList 按 id 取回或列出本会话全部证据 |
从这张表能看出 little-coder 的工具面设计哲学:每个工具的输出都做了硬截断(2000 行、50KB、25K 字符、2KB 分块、500 条路径)。小模型的上下文窗口有限,工具输出一旦失控就会击穿上下文,因此截断被写进了工具 Schema 本身,而不仅是提示词。
2.4 复杂任务方法论与歧义处理
原文档 Approaching complex tasks 一节的核心主张:
- 对非平凡问题动手写码之前,先想清楚:输入输出长什么样、边界情况是什么、哪部分最难、干净的实现应该是什么样子;
- 涉及多文件、架构决策、需求不清或大范围重构的任务,值得先做这种分析——"跳过分析是实现'看起来合理但在不明显用例上失败'的最常见原因";
- 简单的单文件修改则跳过分析直接改;
- 目标是"deliberate implementation, not elaborate deliberation"(有目的的动手,而非过度思辨)。
Handling ambiguity 一节补充:当需求或方案有歧义时,用周边上下文、测试、以及文件里已有的约定来消歧;"有了把握再写码,不要在还在比较方案时就写探索性代码"。
这两节合起来定义了 little-coder 的"思考预算"策略:该分析的分析,该直接的直接,防止小模型在两头翻车——要么无脑直接写错,要么在思考里空转。
2.5 工作区发现:任务开始时读一次规格文档
原文档 Workspace discovery 要求:在编辑陌生代码之前,**在任务开始时(而非每一轮)**把本地文档浮出水面——.docs/instructions.md、AGENTS.md、CLAUDE.md、README.md、SPEC.md,以及你打算修改的那个文件。原文特别点明:规格文件里往往就写着测试所断言的确切格式规则、边界情况或约束,不读就得靠逆向工程。
这一策略在运行时注入块中还有更详细的展开(见 little_coder.rs 的 "Workspace Documentation" 段):按优先级查找 .docs/instructions.md 与 .docs/instructions.append.md(exercism 风格题面)、仓库根的 AGENTS.md/CLAUDE.md、当前目录 README.md、SPEC.md/SPECIFICATION.md、docs/*.md;用 Glob 发现(*.md、.docs/*.md、AGENTS.md)再 Read;每次任务只做一次;纯只读问题可以跳过。
2.6 逐轮上下文增强(Per-turn context augmentation)
原文档声明系统提示词是每一轮由 little-coder 的 extension stack 重新组装的,其中两块是动态的:
- Tool skill cards(
## Tool Usage Guidance):按"错误恢复 > 近期性 > 意图"的优先级挑选。如果上一次工具调用失败了,它的 skill card 会被优先注入; - Algorithm cheat sheets(
## Algorithm Reference):用关键词 + bigram 匹配对题面打分选出,定位是"小而精准的辅助材料,不是要机械照抄的模式"。
原文档的收尾指令是:"When you see these blocks, trust them — they were selected for the current turn."(看到这些块就信任它们——它们是为当前轮次挑选的。)
结合源码可以看清这套机制的实现形态:build_system_prompt 会在基座提示词之后追加一段由 selected_tool_guidance 选出的引导块(little_coder.rs#L55-L68),而选择逻辑就是对全部用户消息文本做小写关键词匹配(little_coder.rs#L70-L85):
- 命中
browser、javascript、xss、webpage、url中任一关键词 → 注入BROWSER_RESEARCH_TOOL_GUIDANCE; - 否则 → 注入
READ_WRITE_TOOL_GUIDANCE。
这两个常量正好对应原文档提到的两类块:READ_WRITE_TOOL_GUIDANCE 以 ## Tool Usage Guidance 开头,给出 Read/Write 的必填参数、绝对路径规则与调用示例(little_coder.rs#L218-L264);BROWSER_RESEARCH_TOOL_GUIDANCE 则同时携带 ## Algorithm Reference(工作区文档查找流程)与 ## Tool Usage Guidance(Glob/Read/Write),并附加一段 Research-first directive(little_coder.rs#L266-L347):
This task involves online research. Before producing a final answer: 1. Use BrowserNavigate / BrowserExtract (or WebSearch for first hops) to gather facts. 2. Save each citable fact via EvidenceAdd before relying on it. 3. Only after evidence is in place should you consider any Edit/Write tool calls. Skipping the gather step (going straight to Edit/Write or guessing from memory) is wrong — restart with the browse step instead.
这段"先取证、后动刀"的指令正是提示词中"Per-benchmark tools ... appear when relevant"一句的运行时对应物:研究类任务出现时,系统不仅下发浏览器/证据工具的 Schema,还注入行为纪律。从源码结构看,原文档描述的"错误恢复 > 近期性 > 意图"排序对应的是 extension 层的更细粒度调度,而当前 little_coder.rs 内可见的是关键词意图路由这一层;两者共同构成"逐轮组装"的完整链路。
2.7 通用行为准则(Guidelines)
原文档 Guidelines 一节是七条短平快的行为准则,值得逐条保留:
- 简洁,先给答案(Be concise. Lead with the answer.);
- 优先编辑已有文件,而不是新建文件;
- 文件操作一律使用绝对路径;
- 编辑前读文件时用行号保证精确;
- 不要添加不必要的注释、docstring 和错误处理(防止小模型生成臃肿代码);
- 多步骤任务要系统化地逐个推进;
- 有了把握就锁定实现,不要在思考预算内反复纠结——"当你的推理轨迹触及上限,extension 会把你从思辨中强制拉回实现——不要抗拒它"。最后一条再次呼应"思考预算"主题:小模型的 deliberation 是有硬上限的,撞墙即收敛。
3. 请求构建链路:提示词如何进入一次真实请求
理解这份提示词在系统中的位置,最直接的证据是 little_coder.rs 的 build_request。它把一次 little-coder 会话组装成如下 Chat Completions 请求体:
json!({
"model": model_info.slug,
"messages": messages, // system + 由 pi::build_messages 转换的历史
"stream": true,
"stream_options": { "include_usage": true },
"store": false,
"max_completion_tokens": 384000,
"tools": tools, // build_tools() 的 19 个工具 Schema
"thinking": { "type": "enabled" },
"reasoning_effort": "high",
"temperature": 0.3,
})
各参数与提示词设计的呼应关系:
| 参数 | 取值 | 与提示词设计的关联 |
|---|---|---|
max_completion_tokens |
384000 | 给"高推理强度"留出充裕的推理空间,配合 Guidelines 中"思考预算"上限 |
thinking / reasoning_effort |
enabled / high |
启用推理通道;提示词里的"deliberate implementation"要求有了执行基础 |
temperature |
0.3 | 低温度:小模型工具调用对格式稳定性极敏感,需要压低随机性 |
stream / include_usage / store |
true / true / false |
流式返回并统计用量,不要求服务端存储会话 |
tools |
19 个工具 | 见 2.3 节对照表,全部输出带硬截断 |
系统消息的组装在 build_system_prompt 中完成(little_coder.rs#L55-L68):
let mut system_prompt = format!(
"{}\n\nCurrent date: {date}\nCurrent working directory: {cwd}",
LITTLE_CODER_SYSTEM_PROMPT.trim_end(), ...
);
if let Some(guidance) = selected_tool_guidance(prompt) {
system_prompt.push_str("\n\n");
system_prompt.push_str(guidance);
}
即最终系统提示词 = 基座提示词(本 Markdown 全文)+ 当前日期 + 当前工作目录 + 关键词路由选出的引导块。历史消息则复用 pi.rs 的 build_messages 转换函数,把内部 ResponseItem 序列(消息、函数调用、函数调用输出)折叠成 Chat Completions 的 messages 数组,并处理未应答工具调用的丢弃逻辑——这解释了为何提示词敢使用 Bash (Polyglot / local REPL) 这类表述:历史转换层对不同执行面做了归一。
整条链路在 request.rs 中收口:模型客户端解析出 ChatHarnessRoute::LittleCoder 后调用 build_chat_harness_request,其 LittleCoder 分支(request.rs#L120-L126)调用 build_little_coder_request,且 postprocess 为 None——little-coder 不做流后处理,也不触发独立的标题生成请求,是所有 chat harness 中形态最"干净"的一个。这个模块的注释也点明了扩展模式:"添加一个 chat harness 意味着在这个模块里加一个路由分支,而不是去改 client。"
4. 配置与使用要点
综合 docs/harness.md 与源码,启用 little-coder 的完整约束是:
- 提供商必须是
wire_api = "chat"的 OpenAI 兼容端点(本地 Ollama、llama.cpp server 等均可),wire_api = "messages"会直接报错; - 配置示例:
harness = "little-coder"
[model_providers.local]
name = "Local OpenAI-compatible"
base_url = "http://localhost:8080/v1"
env_key = "LOCAL_API_KEY"
wire_api = "chat"
- 临时单次运行:
interpreter -c harness='"little-coder"' "refactor the parser"
harness_guidance对 little-coder 无额外效果(该开关目前只影响kimi-cli,见 1.1 节),其逐轮增强完全由提示词内置的## Tool Usage Guidance/## Algorithm Reference机制承担。
使用前提与限制再强调一遍:这套提示词的工具名(Read/Edit/Bash 等)面向的是 little-coder 的工具面,其中 Bash 与 ShellSession 的分工标注了各自对应的执行面(Polyglot 本地 REPL 与 Terminal-Bench 会话式 shell);Browser*/Evidence* 工具属于"基准专属",只在相应任务面启用时下发。
5. 小结
回看 little_coder_system_prompt.md,它是一份"为小模型量身定做"的 Agent 提示词工程样本,设计手段可以归纳为四类:
- 显式授权与禁止(Capabilities & Autonomy):直接堵死"我只是聊天接口"式的自我设限,授予后台脚本与长任务能力;
- 不变式而非建议(Runtime invariants):把 Write/Edit 分工、30s 超时、基准工具的出现规则写成"运行时事实",并让违规的错误信息自带修正示例,用失败成本训练行为;
- 思考预算纪律(Approaching complex tasks / Handling ambiguity / Guidelines):该分析的分析、该直接的直接、撞预算上限立即收敛,两头都防住小模型常见的失控;
- 逐轮动态组装(Per-turn context augmentation):基座提示词 + 日期 + cwd + 按意图选出的引导块,让同一个 Agent 在"写码任务"和"在线研究任务"间切换行为模式(见 little_coder.rs#L70-L85 的关键词路由与两个引导常量)。
对于希望在小参数本地模型(7B–32B 级别)上跑出稳定编码 Agent 循环的开发者而言,little-coder 的价值不仅在于可以直接配置使用,更在于它展示了"提示词 + 工具 Schema + 请求参数"三者如何协同补偿小模型的推理短板——这也是 Open Interpreter harness 体系(mod.rs 中列出的十余种 harness 之一)最值得研究的设计样本。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00