配套视频:https://www.bilibili.com/video/BV1TziYBaE8h/

本文基于 PromptLayer 创始人 Jared Zoneraich 在 AI 工程大会上的演讲整理,深入剖析了 Claude Code 及其他主流编码代理的工作原理、设计哲学和未来趋势。

引言:编码代理的突然爆发

如果你是一名开发者,你一定注意到了最近几个月编码代理(Coding Agents)的爆炸式增长。从 Claude Code 到 Cursor Composer,从 Codex 到 AMP,这些工具正在彻底改变我们编写代码的方式。

但你是否想过:是什么让这些编码代理突然变得如此强大?

作为一个在 AI 领域深耕三年的创业者,我(Jared Zoneraich)和我的团队每天处理数百万条 LLM 请求。在与客户的交流中,在自己使用这些工具的过程中,我逐渐发现了一个令人惊讶的真相:

最大的创新,往往是最简单的。

一、从复制粘贴到自主编程:编码代理简史

四个发展阶段

让我们先回顾一下编码代理的演进历程:

第一阶段:ChatGPT 复制粘贴时代

  • 你在 ChatGPT 中描述需求

  • 复制生成的代码

  • 粘贴到编辑器

  • 发现问题,再次复制粘贴

  • 循环往复

这在当时已经相当革命性了,但效率仍然有限。

第二阶段:Cursor Command-K

  • Cursor 作为 VS Code 的分支出现

  • 按下 Command-K,直接在编辑器中生成代码

  • 减少了复制粘贴的摩擦

  • 但本质上仍是单次生成

第三阶段:Cursor Assistant

  • 引入交互式对话

  • 代理可以来回沟通

  • 开始具备一定的上下文理解能力

第四阶段:Claude Code 自主时代

  • 完全自主的编码流程

  • 无需手动触碰代码

  • 自动探索、测试、修复

  • 真正的"无头"(Headless)工作流

为什么是现在?

如果你在这个领域待过一段时间,你会知道自主编码代理的概念并不新鲜。早在两年前就有人尝试,但效果都很糟糕。

那么,到底发生了什么变化?

二、Claude Code 的核心突破:简单架构 + 更好模型

经过深入研究(包括阅读源代码、分析工具调用、与客户交流),我总结出了 Claude Code 成功的两大核心要素:

1. 简单架构:给工具,然后退后

这是 Claude Code 最革命性的设计理念:

while (存在工具调用):
    执行工具
    将结果返回给模型
    继续循环
    
当没有工具调用时:
    询问用户下一步做什么

就这么简单。

没有复杂的 DAG(有向无环图)工作流,没有数百个分类提示,没有精心设计的状态机。只有一个简单的主循环,配合工具调用。

这种设计遵循了 Python 之禅的核心原则:

  • 简单胜于复杂(Simple is better than complex)

  • 复杂胜于繁琐(Complex is better than complicated)

  • 扁平胜于嵌套(Flat is better than nested)

2. 更好的模型:不要过度工程化

第二个关键因素更加"无聊"但同样重要:模型变得更好了。

Anthropic 发布的新模型在以下方面有显著提升:

  • 工具调用的准确性

  • 指令遵循能力

  • 自我纠错能力

  • 上下文理解能力

这带来了一个重要的设计哲学,Anthropic 称之为"AGI Pill"思维:

不要为当前模型的缺陷过度设计系统,因为很多问题会随着模型改进自然解决。否则你只是在浪费时间。

3. 摒弃传统范式

Claude Code 的另一个大胆之处在于,它摒弃了许多我们认为"必需"的技术:

  • 嵌入(Embeddings):不需要向量数据库

  • RAG(检索增强生成):用 grep 就够了

  • 分类器(Classifiers):模型自己能判断

  • 模式匹配(Pattern Matching):让模型探索

  • 复杂工作流:单一主循环足矣

这种"减法"设计理念,正是 Claude Code 成功的关键。

三、核心组件深度解析

1. Constitution:代码库的宪法

Claude Code 使用一个简单的 Markdown 文件(通常命名为 .claude.mdagents.md)来存储代码库的指令和约定。

为什么不用更复杂的方案?

Cursor 1.0 会在本地构建向量数据库,理解整个代码库结构。但 Claude Code 团队说:

"算了,就放个 Markdown 文件吧。让用户需要时自己改,让代理需要时自己改。"

这种简单性有几个优势:

  • 透明:用户可以直接查看和编辑

  • 灵活:代理可以动态更新

  • 高效:不需要复杂的索引和检索

  • 可靠:减少了系统复杂度

2. 主循环:革命性的简化

让我们看看这个主循环的伪代码:

def master_loop(user_request):
    context = [user_request]
    
    while True:
        response = model.call(context, tools=available_tools)
        
        if response.has_tool_calls():
            for tool_call in response.tool_calls:
                result = execute_tool(tool_call)
                context.append(result)
        else:
            # 没有工具调用,任务完成
            return response.message

这就是全部。

在 Anthropic 内部,这个循环被称为"N0"(可能是"Node Zero"的缩写)。

3. 核心工具集:少而精

Claude Code 的工具集非常精简,每个工具都有明确的用途:

Read:智能文件读取

{
  "name": "read",
  "description": "读取文件内容",
  "parameters": {
    "path": "文件路径",
    "start_line": "起始行(可选)",
    "end_line": "结束行(可选)"
  }
}

为什么不直接用 cat

因为有 token 限制。Read 工具可以:

  • 限制读取的行数

  • 提供更好的错误处理

  • 统计 token 使用量

Grep/Glob:替代 RAG 的搜索

这是一个有趣的设计选择。传统观点认为应该使用向量搜索和 RAG,但 Claude Code 选择了 grep。

为什么 grep 更好?

  1. 符合人类习惯:开发者本来就用 grep 搜索代码

  2. 训练数据丰富:模型对 grep 非常熟悉

  3. 精确匹配:不会有向量搜索的"模糊"问题

  4. 简单可靠:没有额外的依赖

Edit:差异对比而非重写

这是另一个关键设计:

{
  "name": "edit",
  "description": "使用 unified diff 格式编辑文件",
  "parameters": {
    "path": "文件路径",
    "diff": "unified diff 格式的更改"
  }
}

为什么用 diff 而不是重写整个文件?

想象一下,如果我让你审阅这篇文章,你需要:

  • 方案 A:重新写一遍整篇文章,包含你的修改

  • 方案 B:在原文上划掉要删除的,标注要添加的

显然方案 B 更简单、更不容易出错。

优势

  • 减少 token 使用(只发送变更部分)

  • 提高速度(生成更少内容)

  • 降低错误率(不会意外删除未修改的代码)

  • 更符合人类编辑习惯

Bash:万能适配器

这是最重要的工具。

Bash 为什么如此强大?

1. 简单且功能全面

  • 可以运行任何命令行工具

  • 可以执行脚本

  • 可以操作文件系统

  • 可以管理进程

2. 训练数据极其丰富

  • 模型在大量 Bash 代码上训练

  • 理解各种命令的语义

  • 知道如何组合命令

3. 让模型自由探索

这是最关键的一点。看一个真实例子:

# 模型想运行一个 Python 脚本来测试功能
$ cat > test_feature.py << 'EOF'
import requests
# ... 测试代码 ...
EOF

$ python test_feature.py
# ... 输出结果 ...

$ rm test_feature.py

模型可以:

  • 创建临时文件

  • 运行测试

  • 查看结果

  • 清理环境

这种探索能力是其他工具无法提供的。

其他辅助工具

  • Web Search/Fetch:使用更便宜的模型处理网络请求

  • To-dos:任务管理和进度跟踪

  • Tasks:子代理系统,用于复杂任务分解

4. To-Do Lists:结构化但不强制

这是一个非常有趣的设计:To-Do Lists 是结构化的,但不是通过代码强制执行的

工作原理

  1. 模型接收任务后,首先调用 create_todos 工具

  2. 生成一个结构化的任务列表(JSON 格式)

  3. 这个列表被注入到系统提示中

  4. 模型根据提示中的规则工作,但没有硬编码的约束

示例结构

{
  "todos": [
    {
      "id": "a1b2c3",
      "title": "读取配置文件",
      "status": "completed",
      "evidence": "文件内容已读取"
    },
    {
      "id": "d4e5f6",
      "title": "修改 API 端点",
      "status": "in_progress"
    },
    {
      "id": "g7h8i9",
      "title": "运行测试",
      "status": "pending"
    }
  ]
}

规则(通过系统提示传达)

  • 一次只处理一个任务

  • 完成后标记为 completed

  • 如果遇到阻塞,拆分成更小的任务

  • 保持任务列表更新

为什么这样设计?

  1. 灵活性:模型可以根据情况调整

  2. 用户体验:用户可以看到进度

  3. 可恢复性:崩溃后可以从中断处继续

  4. 可控性:用户可以干预和调整

关键洞察

一年前这种纯提示驱动的方法不会有效。但现在的模型在指令遵循方面已经足够好,不需要硬编码的约束。

四、高级特性:上下文管理与子代理

1. 上下文管理:最大的敌人

在长时间运行的编码任务中,上下文窗口是最大的敌人

当上下文接近满载时:

  • 模型变得"愚蠢"

  • 响应变慢

  • 成本增加

  • 容易出错

Claude Code 的解决方案

异步缓冲区(H2A)

将 I/O 操作与推理解耦:

用户请求 → 主循环
              ↓
         推理模型
              ↓
         工具调用 → 异步执行 → 结果缓冲
              ↓
         压缩/摘要
              ↓
         返回主循环

上下文压缩器

当上下文达到约 92% 容量时触发:

  1. 保留头部:最初的指令和上下文

  2. 保留尾部:最近的交互

  3. 丢弃中间:旧的工具调用和结果

  4. 摘要关键信息:重要的中间结果被摘要保留

长期存储:利用沙盒

这是一个天才的设计

与其在上下文中保留所有信息,不如让模型将信息保存到文件系统:

# 模型可以这样做
$ cat > research_notes.md << 'EOF'
# 研究笔记
- 发现 API 端点在 /api/v2/users
- 认证使用 Bearer token
- 需要处理 rate limiting
EOF

# 之后需要时再读取
$ cat research_notes.md

优势

  • 无限的"记忆"容量

  • 结构化的信息存储

  • 可以随时检索

  • 不占用上下文窗口

我的预测

所有 ChatGPT 窗口、所有 Claude 窗口,都将在不久的将来内置沙盒环境。这太有用了。

2. 子代理系统:任务分解

对于复杂任务,Claude Code 使用子代理(Sub-agents)系统:

常见子代理类型

主代理(Master Agent)
├── Researcher(研究员)
│   └── 负责搜索文档、API 文档等
├── Docs Reader(文档阅读器)
│   └── 专门处理长文档
├── Test Runner(测试执行器)
│   └── 运行测试并分析结果
└── Code Reviewer(代码审查器)
    └── 检查代码质量和最佳实践

工作机制

  1. 独立上下文:每个子代理有自己的上下文窗口

  2. 专门提示:针对特定任务优化的系统提示

  3. 结果汇总:只将最终结果返回主代理

  4. 动态生成:根据需要创建和销毁

示例流程

主代理:需要实现一个新的 API 端点

↓ 创建 Researcher 子代理
Researcher:搜索现有 API 模式
Researcher:返回 → "我们使用 RESTful 设计,认证在中间件"

↓ 创建 Code Reviewer 子代理  
Code Reviewer:检查类似端点的实现
Code Reviewer:返回 → "建议使用 UserSchema 和 validate_token"

主代理:基于研究结果实现端点

关键优势

  • 上下文隔离:子任务不污染主上下文

  • 专业化:每个代理专注于特定任务

  • 并行化:可以同时运行多个子代理

  • 可扩展:轻松添加新类型的子代理

五、其他主流编码代理对比

1. Codex(OpenAI)

特点

  • Rust 编写的核心,开源

  • 类似的主循环架构

  • 更偏向事件驱动设计

  • 内核级沙盒(macOS Seatbelt, Linux Seccomp)

差异

  • 更强调安全性和隔离

  • 工具集略有不同

  • 社区驱动的开发

2. AMP(SourceGraph)

独特视角

AMP 的设计哲学非常有趣:

免费层级策略

  • 通过广告支持免费使用

  • 降低用户门槛

  • 快速积累用户数据

无模型选择器

  • 不让用户选择模型

  • 系统自动选择最合适的模型

  • 简化决策,提升体验

Handoff 机制

这是 AMP 最独特的设计:

线程 1(上下文快满了)
    ↓
创建新线程 2
    ↓
传递关键上下文摘要
    ↓
继续在新线程工作

与压缩的区别

  • 压缩:在同一线程中删除旧信息

  • Handoff:创建新线程,保留旧线程

优势

  • 可以回溯到之前的状态

  • 保留完整的历史记录

  • 更快的响应(不需要压缩)

三种模型层级

  • Fast:快速任务(GPT-3.5 级别)

  • Smart:复杂任务(GPT-4 级别)

  • Oracle:最困难的任务(O1 级别)

3. Cursor Composer

核心优势

UI 优先设计

  • 不是 CLI 工具

  • 精美的用户界面

  • 实时预览和反馈

极快的蒸馏模型

Cursor 的秘密武器:

  1. 收集大量用户数据(数百万次交互)

  2. 使用 GPT-4/Claude 生成训练数据

  3. 蒸馏到更小、更快的模型

  4. 专门针对编码任务优化

结果

  • 响应速度极快

  • 成本大幅降低

  • 质量接近大模型

混合模型策略

任务规划 → GPT-4o/Claude
    ↓
代码生成 → Cursor Composer(蒸馏模型)
    ↓
复杂推理 → GPT-4o

关键洞察

Cursor 让微调和蒸馏重新流行起来。他们证明了,在特定领域,小模型可以媲美甚至超越大模型。

4. Factory(Droids)

特点

  • 专注于子代理系统

  • 多个专业化的 "Droid"

  • 强调协作和任务分解

5. Cognition(Devon)

特点

  • 端到端的自主性

  • 自我反思机制

  • 长期任务规划

六、设计哲学:没有银弹

1. AI 治疗师问题

我想分享一个重要的观点:

在编码代理的设计中,不存在全局最优解。不同的策略适合不同的场景。

就像心理治疗一样:

  • 认知行为疗法对某些人有效

  • 精神分析对另一些人有效

  • 没有"最好"的疗法,只有"最适合"的疗法

在编码代理中也是如此

  • Claude Code 的简单架构适合通用编码任务

  • AMP 的 Handoff 机制适合长期项目

  • Cursor 的快速模型适合交互式编辑

  • Factory 的子代理适合复杂系统开发

关键是

  • 理解不同方法的权衡

  • 根据你的用例选择

  • 不要盲目追求"最好"

2. 依赖模型原则

这是我在研究中得出的最重要结论:

当你不确定时,不要试图穷举所有边界情况。让模型探索和自我纠正。

反例:过度工程化

两年前,大家都在构建这样的系统:

用户输入
    ↓
意图分类器 → [退款/技术支持/账单/其他]
    ↓
退款分支
    ├── 检查退款资格
    ├── 验证订单状态
    ├── 计算退款金额
    └── 执行退款

这种 DAG 工作流有数百个节点,每个节点都是精心设计的提示。

问题

  • 开发成本高

  • 维护困难

  • 不灵活

  • 容易出现边界情况

现代方法

用户输入
    ↓
主代理(带工具)
    ├── check_refund_eligibility()
    ├── process_refund()
    └── send_confirmation()

模型自己决定:

  • 是否需要退款

  • 如何验证

  • 何时执行

  • 如何处理异常

优势

  • 10 倍易于开发

  • 10 倍易于维护

  • 更灵活

  • 效果更好(因为模型更智能)

但是,这并不意味着完全不需要结构:

关键操作(如退款)→ 使用专门的工具
边界情况 → 在系统提示中指导
其他 → 让模型自由发挥

3. 简化的艺术

案例研究:我的失败实验

上周,我尝试改进我们的浏览器代理。我想:

"如果我给所有按钮添加 title 属性,代理就能更好地导航网站了!"

我花了几个小时:

  • 给每个按钮添加描述

  • 标注每个链接的功能

  • 创建详细的导航地图

结果:代理表现更差了。

原因

  • 太多信息分散了注意力

  • 模型开始过度思考

  • 失去了探索的灵活性

教训

  • 有时候,少即是多

  • 让模型探索比给它地图更好

  • 过度优化会适得其反

七、实战建议:如何构建你的编码代理

1. 从简单开始

最小可行代理

import anthropic

def simple_coding_agent(task):
    client = anthropic.Anthropic()
    
    tools = [
        {
            "name": "bash",
            "description": "执行 bash 命令",
            "input_schema": {
                "type": "object",
                "properties": {
                    "command": {"type": "string"}
                }
            }
        },
        {
            "name": "edit_file",
            "description": "编辑文件",
            "input_schema": {
                "type": "object",
                "properties": {
                    "path": {"type": "string"},
                    "diff": {"type": "string"}
                }
            }
        }
    ]
    
    messages = [{"role": "user", "content": task}]
    
    while True:
        response = client.messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=4096,
            tools=tools,
            messages=messages
        )
        
        if response.stop_reason == "end_turn":
            return response.content[0].text
        
        # 执行工具调用
        for tool_use in response.content:
            if tool_use.type == "tool_use":
                result = execute_tool(tool_use)
                messages.append({
                    "role": "assistant",
                    "content": response.content
                })
                messages.append({
                    "role": "user",
                    "content": [{
                        "type": "tool_result",
                        "tool_use_id": tool_use.id,
                        "content": result
                    }]
                })

这就是核心。 从这里开始,逐步添加功能。

2. 渐进式增强

阶段 1:基础工具

  • Bash

  • Read

  • Edit

阶段 2:上下文管理

  • 添加 token 计数

  • 实现简单的压缩

  • 保存中间结果到文件

阶段 3:任务管理

  • 添加 To-Do Lists

  • 实现进度跟踪

  • 支持任务恢复

阶段 4:子代理

  • 识别可分解的任务

  • 创建专门的子代理

  • 实现结果汇总

3. 团队组织建议

PromptLayer 的实践

我们为工程团队制定了一条规则:

如果用 Claude Code 能在 1 小时内完成,就直接做,不要排期。

效果

  • 大量边界情况被快速修复

  • 团队保持小规模

  • 开发速度提升

  • 工程师更专注核心功能

建议

  • 重新思考你的工程组织

  • 拥抱 AI 辅助开发

  • 但不要完全依赖(关键功能仍需人工审查)

4. 评估和选择

如何选择编码代理?

不要只看基准测试(Benchmarks)。实际使用体验更重要:

场景

推荐工具

原因

快速原型

Cursor Composer

速度快,UI 好

复杂重构

Claude Code

自主性强,可靠

长期项目

AMP

Handoff 机制好

学习探索

Codex

开源,可定制

混合使用

很多时候,最好的策略是混合使用:

规划阶段 → Cursor(快速迭代)
    ↓
实现阶段 → Claude Code(自主完成)
    ↓
测试阶段 → 手动审查
    ↓
部署阶段 → 传统 CI/CD

八、未来趋势:编码代理的下一步

1. 工具调用的演进

两派观点

多工具派

  • 数百个专业工具

  • 每个工具做一件事

  • 精细的权限控制

简化派(我倾向的):

  • 回归 Bash

  • 减少工具数量

  • 依赖模型智能

我的预测:简化派会胜出,因为:

  • 模型越来越智能

  • 过多工具增加复杂度

  • Bash 足够强大和灵活

2. 自适应推理预算

新趋势:将推理模型作为工具

tools = [
    {
        "name": "think",
        "description": "使用推理模型深度思考",
        "parameters": {
            "budget": "low/medium/high/ultra"
        }
    }
]

工作原理

  • 简单任务:快速模型,少量推理 token

  • 复杂任务:调用 think(budget="high")

  • 关键任务:调用 think(budget="ultra")

优势

  • 成本优化

  • 速度优化

  • 质量保证

3. 新的一流范式

To-Do Lists 的成功启示

To-Do Lists 证明了,简单的结构化方法可以带来巨大改进。

下一个可能的范式

  • Skills:可重用的技能库

  • Memory:长期记忆管理

  • Planning:多步骤规划

  • Reflection:自我反思和改进

关键是

  • 保持简单

  • 不强制执行(提示驱动)

  • 让模型灵活应变

4. 沙盒的普及

我的大胆预测

在 6 个月内,所有主流 AI 聊天界面都会内置沙盒环境。

原因

  • 长期记忆存储

  • 工具执行安全

  • 用户体验提升

  • 成本降低(减少上下文使用)

技术路径

  • 浏览器内沙盒(WebAssembly)

  • 云端容器(Docker/Kubernetes)

  • 混合方案(本地 + 云端)

5. 微调的复兴

Cursor 的启示

Cursor 证明了,通过大量用户数据微调的小模型,可以在特定任务上超越大模型。

未来趋势

  • 更多公司会微调自己的模型

  • 蒸馏技术会更加成熟

  • 专业化模型会涌现

机会

  • 垂直领域的编码代理(如前端、后端、DevOps)

  • 特定语言的优化模型(如 Rust、Go)

  • 企业定制模型

九、关键洞察总结

经过深入研究和实践,我总结出以下关键洞察:

1. 简单性是最大的创新

最大的突破往往不是添加功能,而是删除复杂性。

Claude Code 的成功不在于它有多少功能,而在于它删除了多少不必要的复杂性。

2. 信任模型,但验证结果

模型已经足够好,不要过度工程化。但关键操作仍需验证。

平衡点

  • 让模型自由探索(大部分任务)

  • 使用工具约束(关键操作)

  • 人工审查(最终结果)

3. 用户体验不可忽视

技术能力重要,但用户体验同样重要。

To-Do Lists 的成功很大程度上是因为它改善了用户体验:

  • 用户知道进度

  • 可以随时干预

  • 崩溃后可恢复

4. 没有绝对的赢家

不同的代理适合不同的场景。多样性有价值。

不要寻找"最好"的编码代理,而要找"最适合"的。

5. 数据是护城河

Cursor 的微调模型证明,数据可以建立竞争优势。

如果你在构建编码代理:

  • 收集用户数据(在合规前提下)

  • 持续微调和优化

  • 建立反馈循环

6. 开放心态

学习各家所长,灵活组合。

  • Claude Code 的简单架构

  • AMP 的 Handoff 机制

  • Cursor 的微调策略

  • Factory 的子代理系统

混合使用,创造你自己的方案。

7. 持续进化

这个领域变化极快。保持学习,保持实验。

  • 每周都有新的模型发布

  • 每月都有新的工具出现

  • 每季度都有新的范式涌现

唯一不变的是变化本身。

结语:编码的未来

站在 2025 年初,回顾过去三年的发展,我深深感到:

我们正处于软件开发范式转变的关键时刻。

编码代理不仅仅是工具,它们正在改变:

  • 我们如何思考问题

  • 我们如何组织团队

  • 我们如何构建软件

但核心不变

  • 好的设计仍然重要

  • 简单性仍然是美德

  • 人类的创造力仍然不可替代

我的建议

  1. 拥抱变化:不要抗拒,而要主动学习

  2. 保持批判:不要盲目追随,而要理解原理

  3. 持续实验:不要等待完美,而要快速迭代

  4. 分享知识:不要闭门造车,而要开放交流

最后

编码代理的成功秘诀不在于复杂的架构,而在于简单的设计、信任模型的能力,以及提供合适的工具让模型自主探索和解决问题。

这就是 Claude Code 的核心哲学,也是我认为编码代理未来发展的方向。


关于作者

Jared Zoneraich 是 PromptLayer 的创始人,一个专注于 AI 工程的平台。PromptLayer 每天处理数百万条 LLM 请求,服务于全球的 AI 开发者和企业。

如果你对编码代理、提示工程或 AI 工程有任何问题或想法,欢迎在 Twitter/X 上找我:@JaredZ


参考资源

  • Claude Code 官方文档

  • Cursor 官方博客

  • AMP 技术博客

  • Codex GitHub 仓库

  • PromptLayer 平台

延伸阅读

  • "The Zen of Python" - Python 设计哲学

  • "Simple Made Easy" - Rich Hickey 的经典演讲

  • "Worse is Better" - Richard Gabriel 的设计哲学

  • Anthropic 的 Constitutional AI 论文


如果这篇文章对你有帮助,欢迎点赞、收藏、转发。也欢迎在评论区分享你的经验,我们一起交流学习!


我是 dtsola【IT解决方案架构师 | AI创业者】 ;专注AI创业、商业、技术、心理学、哲学内容分享。

提供服务:AI项目咨询 | 技术解决方案 | IT项目实施 | 企业技术顾问

博客:https://www.dtsola.com

公众号&VX:dtsola

需提供服务,加微信 dtsola,备注:IT咨询,并说明来意。


#AI编程 #VibeCoding #智能体 #ClaudeCode #独立开发者 #AI创业 #一人公司 #程序员 #软件工程师 #软件工程


Work Less, Earn More, Enjoy Life.