我让 AI 帮我写了一个 Code Agent!

我让 AI 帮我写了一个 Code Agent!

从零到一,深入理解 AI 编程助手的核心原理

前言

最近,我让 AI 帮我从零开始写了一个类似 Claude Code 的 AI 编程助手。在这个过程中,顺便了解了 Code Agent 产品的核心架构和实现原理。本文将分享这次实践的完整过程和关键收获。

项目概述

我们构建的是一个名为 Mini Claude Code 的 CLI 工具,它具备以下核心能力:

  • 🤖 ReAct Agent 循环 - 思考-行动-观察的自动化执行
  • 🔧 工具系统 - 文件操作、Shell 执行、代码搜索等
  • 🔌 MCP 协议支持 - 可扩展的外部工具集成
  • 💬 多模型支持 - 支持 Ollama、Groq、DeepSeek 等免费模型

核心架构

1. ReAct 模式:Agent 的灵魂

ReAct (Reasoning + Acting) 是 Code Agent 的核心工作模式。它让 AI 能够像人类一样思考和行动:

scss 复制代码
用户输入任务
    ↓
┌─────────────────────────────────┐
│  思考 (Thought)                 │
│  "我需要先读取文件了解代码结构"  │
└─────────────────────────────────┘
    ↓
┌─────────────────────────────────┐
│  行动 (Action)                  │
│  调用 read_file 工具            │
└─────────────────────────────────┘
    ↓
┌─────────────────────────────────┐
│  观察 (Observation)             │
│  获取文件内容,分析结果          │
└─────────────────────────────────┘
    ↓
继续思考 → 下一步行动 → ... → 任务完成

关键实现

typescript 复制代码
async runAgentLoop(input: string, maxIterations: number = 10): Promise<void> {
  let iteration = 0;
  let isComplete = false;
  const originalTask = input;

  while (!isComplete && iteration < maxIterations) {
    // 1. AI 思考并决定行动
    const response = await this.aiClient.streamChat(
      isFirstRound ? originalTask : '',
      onChunk
    );

    // 2. 解析工具调用
    if (response.toolCalls.length > 0) {
      const toolCall = response.toolCalls[0];
      
      // 3. 执行工具
      const result = await this.executeToolCall(toolCall.tool, toolCall.params);
      
      // 4. 将结果反馈给 AI(包含原始任务提醒)
      this.aiClient.addToolResult(toolCall.tool, result.output, result.success, originalTask);
    }

    // 5. 检查任务是否完成
    if (response.isComplete) {
      isComplete = true;
    }
  }
}

核心要点

  • 每轮只执行一个工具调用,等待结果后再决定下一步
  • 工具结果反馈时必须包含原始任务,避免 AI "忘记"目标
  • 设置最大迭代次数,防止无限循环

2. 工具系统:Agent 的双手

工具是 Agent 与外部世界交互的接口。我们实现了统一的工具抽象:

typescript 复制代码
export interface Tool {
  name: string;
  description: string;
  parameters: Record<string, unknown>;
  execute: (params: Record<string, unknown>, workspacePath: string) => Promise<ToolResult>;
}

内置工具

工具名 功能
read_file 读取文件内容
create_file 创建新文件
edit_file 编辑文件(搜索替换)
shell 执行 Shell 命令
search_code 搜索代码
list_files 列出目录文件
list_tools 列出所有可用工具

工具调用格式

AI 通过特定格式输出工具调用,CLI 解析并执行:

json 复制代码
{
  "tool": "read_file",
  "params": {
    "filePath": "/path/to/file.ts"
  }
}

3. System Prompt:Agent 的大脑

System Prompt 定义了 AI 的行为模式和能力边界:

typescript 复制代码
getSystemPrompt(): string {
  const toolsDescription = this.generateToolsDescription();
  
  return `你是 Mini Claude Code,一个智能编程助手,采用 ReAct 模式工作。

## 工作模式
1. **思考 (Thought)**: 分析当前情况,决定下一步行动
2. **行动 (Action)**: 调用工具执行操作
3. **观察 (Observation)**: 查看工具执行结果
4. **循环**: 根据观察结果继续思考,直到任务完成

## 可用工具
${toolsDescription}

## 输出格式
**思考**: [推理过程]
**行动**: \`\`\`tool { "tool": "xxx", "params": {...} } \`\`\`
**回复**: [给用户的回复]

## 重要规则
1. 每次只执行一个工具调用
2. 任务完成时标注 "[任务完成]"
...`;
}

关键设计

  • 动态生成工具描述,支持运行时添加新工具
  • 明确的输出格式约定,便于解析
  • 清晰的规则约束,引导 AI 正确行为

4. MCP 协议:Agent 的扩展能力

MCP (Model Context Protocol) 是 Anthropic 提出的标准化协议,让 AI 应用可以连接外部工具和数据源。

架构设计

arduino 复制代码
┌─────────────────┐     ┌─────────────────┐
│  Mini Claude    │     │  MCP Server     │
│     Code        │────▶│  (filesystem)   │
│                 │     └─────────────────┘
│  MCPManager     │     ┌─────────────────┐
│  MCPClient      │────▶│  MCP Server     │
│                 │     │  (git)          │
└─────────────────┘     └─────────────────┘

使用官方 SDK

typescript 复制代码
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';

// 创建客户端
this.client = new Client({ name: 'mini-claude-code', version: '0.1.0' });

// 连接服务器
this.transport = new StdioClientTransport({ command, args, env });
await this.client.connect(this.transport);

// 获取工具列表
const toolsResult = await this.client.listTools();

// 调用工具
const result = await this.client.callTool({ name: toolName, arguments: args });

MCP 工具与内置工具统一消费

typescript 复制代码
// MCP 工具注册到 ALL_TOOLS
registerTool({
  name: `${serverName}::${mcpTool.name}`,  // 格式:服务器名::工具名
  description: mcpTool.description,
  execute: async (params) => {
    return await client.callTool(mcpTool.name, params);
  }
});

// 统一通过 getTool() 查找和执行
const tool = getTool(toolName);  // 不区分内置还是 MCP
await tool.execute(params, workspacePath);

5. 对话历史管理

对话历史是 Agent 的"记忆",需要精心管理:

typescript 复制代码
private conversationHistory: Message[] = [];

// 确保 System Prompt 始终是最新的
private ensureSystemPrompt(): void {
  const newSystemPrompt = this.getSystemPrompt();
  if (this.conversationHistory.length === 0) {
    this.conversationHistory.push({ role: 'system', content: newSystemPrompt });
  } else {
    this.conversationHistory[0].content = newSystemPrompt;  // 更新工具列表
  }
}

// 工具结果反馈(包含原始任务提醒)
addToolResult(toolName: string, result: string, success: boolean, originalTask?: string): void {
  let content = `**观察** - 工具 ${toolName} 执行结果:\n${result}`;
  if (originalTask) {
    content += `\n\n**提醒**: 你正在执行的原始任务是: "${originalTask}"`;
  }
  this.conversationHistory.push({ role: 'user', content });
}

// 历史裁剪,防止 token 超限
private trimHistory(): void {
  if (this.conversationHistory.length > maxLength) {
    const systemMessage = this.conversationHistory[0];
    this.conversationHistory = [systemMessage, ...this.conversationHistory.slice(-maxLength)];
  }
}

技术栈

组件 技术选型
运行时 Node.js + TypeScript
CLI 框架 Commander + Inquirer
AI 调用 OpenAI SDK (兼容多种 API)
MCP 支持 @modelcontextprotocol/sdk
终端美化 Chalk + Ora

项目结构

perl 复制代码
mini-claude-code/
├── src/
│   ├── index.ts          # 入口
│   ├── cli.ts            # CLI 交互 + ReAct 循环
│   ├── ai-client.ts      # AI 模型调用
│   ├── config.ts         # 配置管理
│   ├── tools/            # 工具实现
│   │   ├── index.ts      # 工具注册中心
│   │   ├── read-file.ts
│   │   ├── create-file.ts
│   │   ├── edit-file.ts
│   │   ├── shell.ts
│   │   ├── search-code.ts
│   │   ├── list-files.ts
│   │   └── list-tools.ts
│   └── mcp/              # MCP 支持
│       ├── index.ts
│       ├── types.ts
│       ├── client.ts     # MCP 客户端
│       └── manager.ts    # MCP 服务器管理
└── package.json

关键收获

1. ReAct 循环是核心

Code Agent 的本质是一个 ReAct 循环:思考 → 行动 → 观察 → 继续思考。这个循环让 AI 能够:

  • 分解复杂任务为多个步骤
  • 根据执行结果动态调整策略
  • 处理错误并尝试修复

2. 工具是能力的边界

AI 的能力取决于它能使用的工具。好的工具设计应该:

  • 功能单一、职责明确
  • 参数清晰、易于理解
  • 返回结构化的结果

3. Prompt 工程至关重要

System Prompt 决定了 AI 的行为模式:

  • 明确的输出格式约定
  • 清晰的规则约束
  • 动态的工具列表

4. 上下文管理是难点

Agent 需要在多轮对话中保持"记忆":

  • 原始任务不能丢失
  • 工具结果需要正确反馈
  • 历史需要适时裁剪

5. MCP 是扩展的未来

MCP 协议让 Agent 能力可以无限扩展:

  • 标准化的工具接口
  • 即插即用的服务器
  • 统一的消费方式

总结

通过这次实践,我深刻理解了 Code Agent 产品的核心原理:

  1. ReAct 模式 - Agent 的工作方式
  2. 工具系统 - Agent 的能力边界
  3. System Prompt - Agent 的行为定义
  4. MCP 协议 - Agent 的扩展机制
  5. 对话管理 - Agent 的记忆系统

这个项目虽然简单,但麻雀虽小五脏俱全。它展示了一个 Code Agent 的完整架构,也为进一步学习和扩展打下了基础。

相关推荐
工边页字2 小时前
面试官:请详细介绍下AI中的token,越详细越好!
前端·人工智能·后端
anyup2 小时前
月销 8000+,uView Pro 让 uni-app 跨端开发提速 10 倍
前端·uni-app·开源
小溪彼岸2 小时前
Cline升级Minimax-2.1、Kimi-k2.5限时免费使用
ai编程·cline
RealPluto3 小时前
私有化部署版 Dify 版本升级
ai编程
前端Hardy3 小时前
别再忽略 Promise 拒绝了!你的 Node.js 服务正在“静默自杀”
前端·javascript·面试
前端Hardy3 小时前
别再被setTimeout闭包坑了!90% 的人都写错过这个经典循环
前端·javascript·vue.js
小林coding3 小时前
专为程序员打造的简历模版来啦!覆盖前端、后端、测开、大模型等专业简历
前端·后端
前端Hardy3 小时前
你的 Vue 组件正在偷偷吃掉内存!5 个常见的内存泄漏陷阱与修复方案
前端·javascript·面试
沸点小助手3 小时前
「AI 编程搭子真香or翻车」沸点获奖名单公示|本周互动话题上新🎊
aigc·agent·ai编程