Skip to content

Latest commit

 

History

History
205 lines (159 loc) · 6.34 KB

File metadata and controls

205 lines (159 loc) · 6.34 KB

该系列文章基于 github.com/shareAI-lab/learn-claude-code 写就,该仓库以大道至简的风格剖析了Claude Code的核心原理,值得大家学习。由于该仓库是基于Python语言,为方便.NET开发者学习,我已经将代码基于.NET 10的dotnet file 重写,源码已上传至github,源码地址见文末。

v8: 智能体团队 - 从独狼到团队

本文是 Learn Claude Code (C# 版) 系列的第九篇,对应代码文件 v8_agent_teams.cs

问题:单个智能体的局限

v7 让智能体能在后台运行命令,但智能体本身仍然是一个:

一个智能体 → 一个上下文窗口 → 一个注意力焦点

任务A: 修改前端 CSS
任务B: 同时调试后端 API
任务C: 同时审查测试覆盖率

→ 上下文互相污染
→ 一个任务的细节冲刷掉另一个任务的关键信息
→ 切换注意力的代价极高

真正的软件团队不会让一个人干所有事。我们需要多个独立的智能体,各有自己的上下文窗口和工具集。

解决方案:持久化队友 + JSONL 收件箱

持久化的队友通过 JSONL 收件箱提供了一种教学协议,将孤立的智能体转变为可通信的团队。

                    Lead Agent
                    (你直接交互的)
                   /     |     \
            spawn  send  read  broadcast
               /    |      \       \
     +--------+  +--------+  +--------+
     | FE Dev |  | BE Dev |  | Tester |
     | (loop) |  | (loop) |  | (loop) |
     +--------+  +--------+  +--------+
         ↕           ↕           ↕
     inbox_fe    inbox_be    inbox_test
     (.jsonl)    (.jsonl)    (.jsonl)

MessageBus:JSONL 收件箱

每个队友有一个 JSONL 文件作为收件箱,每行一条 JSON 消息:

class MessageBus
{
    string inboxDir;

    public MessageBus()
    {
        inboxDir = Path.Combine(".team", "inbox");
        Directory.CreateDirectory(inboxDir);
    }

    public void Send(string from, string to, string content, string type = "message")
    {
        var msg = new
        {
            from, to, content, type,
            timestamp = DateTime.UtcNow.ToString("o")
        };
        var path = Path.Combine(inboxDir, $"{to}.jsonl");
        File.AppendAllText(path, JsonSerializer.Serialize(msg) + "\n");
    }

    public List<Dictionary<string, object>> Read(string who)
    {
        var path = Path.Combine(inboxDir, $"{who}.jsonl");
        if (!File.Exists(path)) return [];

        var lines = File.ReadAllLines(path).Where(l => l.Trim().Length > 0);
        var msgs = lines.Select(l => JsonSerializer.Deserialize<...>(l)).ToList();

        // Drain-on-read: 清空已读消息
        File.WriteAllText(path, "");
        return msgs;
    }

    public void Broadcast(string from, string content, IEnumerable<string> teammates)
    {
        foreach (var t in teammates)
            Send(from, t, content, "broadcast");
    }
}

Drain-on-read 模式:读取后清空收件箱,确保消息不会重复处理。

TeammateManager:持久化智能体

class TeammateManager
{
    Dictionary<string, TeammateConfig> teammates = new();

    public string Spawn(string name, string role)
    {
        var config = new TeammateConfig(name, role);
        teammates[name] = config;
        SaveConfig();

        // 在独立线程中启动队友的 agent loop
        Task.Run(async () => await RunTeammateLoopAsync(name, role));

        return $"Spawned teammate: {name} ({role})";
    }
}

队友的独立 Agent Loop

每个队友运行自己的 agent loop,有自己的消息数组,有自己的工具集:

async Task RunTeammateLoopAsync(string name, string role)
{
    var messages = new List<MessageParam>();
    var systemPrompt = $"You are {name}, a teammate with role: {role}. " +
                       $"Check your inbox regularly with read_inbox.";

    while (true)
    {
        // 1. 检查收件箱
        var inbox = messageBus.Read(name);
        if (inbox.Count > 0)
            messages.Add(new() { Role = Role.User,
                Content = FormatInboxMessages(inbox) });

        // 2. 调用 LLM
        var response = await client.Messages.Create(new MessageCreateParams
        {
            Model = "claude-sonnet-4-20250514",
            System = systemPrompt,
            Messages = messages,
            Tools = teammateTools,  // 精简的工具集
            MaxTokens = 4096
        });

        // 3. 执行工具调用
        // ... 标准 agent loop ...
    }
}

工具对比

Lead Agent 工具 Teammate 工具
bash, read_file, write_file, edit_file bash, read_file, write_file, edit_file
spawn_teammate
list_teammates
send_message send_message
read_inbox read_inbox
broadcast

Lead 有管理权限(spawn、broadcast),Teammate 只能收发消息和执行代码。

消息类型

// 支持的消息类型
"message"    // 普通消息
"broadcast"  // 广播
"shutdown_request"    // 关机请求 (v9 扩展)
"shutdown_response"   // 关机响应 (v9 扩展)
"plan_approval_response" // 计划审批 (v9 扩展)

相对 v7 的变更

组件 之前 (v7) 之后 (v8)
智能体数量 1 N (Lead + Teammates)
通信 JSONL 收件箱
工具数 6 Lead 9 / Teammate 6
上下文隔离 单一共享 每个智能体独立
状态存储 .tasks/ .team/inbox/ + config.json
后台线程 命令级 智能体级

设计原理

JSONL 收件箱是消息传递的最小实现:

  1. 文件即队列:追加写入 = 入队,全文读取 + 清空 = 出队
  2. 无需中间件:不需要 Redis、RabbitMQ 或任何消息队列
  3. 可观察:用 cat 或记事本就能查看消息
  4. 持久化:重启后消息不丢失

每个队友运行自己的 agent loop,不共享上下文。隔离是特性:前端开发者的上下文不会被后端 API 的细节填满。

运行

dotnet run v8_agent_teams.cs

可以尝试的提示:

  1. Spawn a teammate called 'fe-dev' with role 'frontend developer' and a teammate called 'be-dev' with role 'backend developer'
  2. Send a message to fe-dev: "Please create a simple HTML page"
  3. Broadcast to all teammates: "Share your progress"
  4. List all teammates