从零认识 ClaudeCode-01: 基于 QwenCoderPlus 打造一个 BashAgent
目录
- 项目背景与参考
- 基础模型调用 (One Call)
- 单轮调用的局限性
- 手动实现命令执行
- Agentic Loop 核心概念
- 工具调用 (Tool Use) 规范
- 系统提示词 (System Prompt)
- 完整 Agent 循环实现
- 测试与验证
- AI 总结
项目背景与参考 Content-[00:00]
目前市面上存在多种编程辅助工具,如 OpenAI 的 Codex、Toppy 的 Cloud Code,以及国内的 Kimi、MiniMax 等编程终端。虽然功能相似,但实际使用体验差距较大,主要源于基座模型能力的差异以及代码系统设计的不同。
本系列教程参考了 GitHub 上的开源项目 Learn Claude Code(由 shanshail Lab 开发),该项目核心依赖仅为 Anthropic 的 SDK,其余部分均用纯 Python 编写,代码简洁且系统设计经过深思熟虑。

基础模型调用 (One Call) Content-[00:55]
最原始的模型调用流程是:用户输入提示词 -> 调用 Model API -> 模型返回结果。
环境配置
需要配置三个关键参数:
BASE_URL:API 基础地址。API_KEY:认证密钥。MODEL_NAME:模型名称(如qwen-coder-plus)。
代码实现
使用 SDK 初始化客户端并调用 client.messages.create:
- 指定
model名称。 - 构建
messages列表,包含角色(user)和内容(提示词)。 - 设置
max_tokens(如 200)。

响应结构解析
模型返回的 JSON 数据中需关注以下字段:
role: 通常为assistant。stop_reason: 如end_turn表示对话结束。content: 列表形式,包含type(如text)和具体的文本内容text。

单轮调用的局限性 Content-[03:00]
通过案例测试发现,直接询问模型“统计 flow.md 文件有多少字符”,模型无法直接访问本地文件或执行命令,只能返回文本建议(如建议使用 wc 命令)。
这是因为单次调用(One Call)模式下,模型仅能生成文本,没有后续动作能力,无法感知本地环境状态。

手动实现命令执行 Content-[04:15]
为了让模型具备执行能力,可以采用一种“粗暴”的方法:
- 提示词约束:要求模型只返回 Linux 命令。
- 命令提取:在代码中解析模型返回的文本,提取出命令字符串(去除 Markdown 格式标记)。
- 子进程执行:使用 Python 的
subprocess模块执行提取出的命令。
流程:
- 获取模型返回的
text。 - 通过字符串分割(如按
\n或 Markdown 代码块标记)提取命令。 - 调用
subprocess.run(cmd, ...)执行。 - 捕获
stdout输出结果。

虽然这种方法能让模型执行简单命令,但对于多步骤任务(如:找到最大文件 -> 统计函数数 -> 写入注释),手动提取和串联逻辑非常复杂,且模型无法根据上一步的执行结果动态调整下一步操作。
Agentic Loop 核心概念 Content-[07:47]
为了解决多步骤任务,引入了 Agentic Loop(代理循环)。模型需要在循环中不断进行 观察 (Observe) -> 决策 (Decide) -> 执行 (Execute),而不是一次性给出所有命令。
循环流程图
- Chat Prompt: 用户输入初始指令。
- Call Model API: 发送请求(包含历史消息和可用工具)。
- Check Response:
- 如果是文本 (
text):直接返回给用户,结束循环。 - 如果是工具调用 (
tool_use):提取工具参数。
- 如果是文本 (
- Execute Tool: 本地执行工具(如运行 Bash 命令)。
- Append Result: 将执行结果作为新的消息(
tool_result)加入历史记录。 - Loop: 再次调用 Model API,直到模型认为任务完成(
stop_reason为end_turn)。

工具调用 (Tool Use) 规范 Content-[09:50]
为了让模型知道可以调用哪些工具,需要在 API 请求的 tools 参数中定义工具规范。
Bash Tool 定义示例
tools = [{
"name": "bash",
"description": "Run a bash command in the terminal.",
"input_schema": {
"type": "object",
"properties": {
"command": {"type": "string", "description": "The bash command to execute."}
},
"required": ["command"]
}
}]
name: 工具名称。description: 工具功能描述,指导模型何时使用。input_schema: 定义调用工具时所需的参数格式(JSON Schema)。

系统提示词 (System Prompt) Content-[10:50]
除了工具定义,还需要通过 system 参数设定系统提示词,明确 Agent 的角色和行为准则:
- 角色定义:你是一个 CLI Agent,使用 Bash 命令解决问题。
- 规则:
- 优先使用提供的工具。
- 在执行破坏性操作前需确认。
- 保持上下文清晰,避免污染对话。
- 子进程运行在隔离环境中,仅返回最终摘要。

完整 Agent 循环实现 Content-[12:00]
核心代码逻辑
- 初始化历史:
history = [{"role": "user", "content": prompt}]。 - While True 循环:
- 调用 API:传入
messages=history,tools=tools,system=SYSTEM_PROMPT。 - 保存响应:将模型的输出(assistant message)追加到
history。 - 判断结束:检查
response.stop_reason。如果是end_turn,则退出循环。 - 处理工具调用:
- 遍历
response.content,查找type == "tool_use"的块。 - 提取
command参数。 - 使用
subprocess执行命令,获取输出output。 - 构建
tool_result消息块(包含tool_use_id和执行结果content)。 - 将
tool_result以user角色追加到history,供下一轮模型参考。
- 遍历
- 调用 API:传入

关键点
- 消息管理:必须将每一轮的交互(用户提问、模型思考、工具调用、工具结果)都保存在
history中,否则模型会丢失上下文。 - Tool Result 格式:返回给模型的工具结果需遵循特定格式(
type: "tool_result",tool_use_id,content),以便模型理解这是对上一步工具调用的反馈。

测试与验证 Content-[19:25]
案例 1:统计文件字符数
- 指令:“统计 flow.md 有多少个字符”。
- 过程:
- 模型调用
bash工具,命令wc -c < flow.md。 - 系统执行命令,返回结果
1093。 - 模型接收结果,整理回复:“flow.md 文件包含 1093 个字符”。
- 模型调用
- 结果:成功自动执行并反馈。

案例 2:统计 Python 文件数量
- 指令:“统计当前目录下有几个 python 文件”。
- 过程:
- 模型调用
bash工具,命令find . -name "*.py" | wc -l。 - 系统执行返回
6。 - 模型回复:“当前目录有 6 个 python 文件”。
- 模型调用
- 结果:验证了 Agent 具备多步思考和执行能力。

AI 总结
本视频详细演示了如何从零开始构建一个基于 LLM 的 Bash Agent。核心在于从简单的“单次问答”进化为具备 Agentic Loop 的智能体。通过定义 Tool Use 规范(特别是 Bash 工具)和维护完整的 Message History,模型能够自主决定何时调用命令行工具,并根据执行结果进行下一步决策。这种架构是构建类似 Claude Code 等高级编程助手的基础,实现了从“被动回答”到“主动执行”的跨越。
从零认识 ClaudeCode-01: 基于 QwenCoderPlus 打造一个 BashAgent
http://localhost:8090/archives/cong-ling-ren-shi-claudecode-01-ji-yu-qwencoderplus-da-zao-yi-ge-bashagent
评论