20 行代码,构建 Claude Code 核心能力

40 阅读5分钟

A3S Code 是一个可嵌入的 Rust 编码 Agent 框架。20 行代码,你就能构建一个具备 Claude Code 核心能力的终端助手。

import { Agent } from '@a3s-lab/code';
import * as readline from 'readline';

const agent = await Agent.create('agent.hcl');
const session = agent.session(process.cwd());

const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
console.log('A3S Code — 输入你的问题,Ctrl+C 退出\n');

while (true) {
  const input = await new Promise<string>((resolve) => rl.question('> ', resolve));
  if (!input.trim()) continue;

  const events = await session.stream(input);
  for await (const event of events) {
    if (event.type === 'text_delta') process.stdout.write(event.text);
    else if (event.type === 'tool_use') console.log(`\n[${event.tool}]`);
    else if (event.type === 'end') console.log('\n');
  }
}

这就是全部核心代码。 它已经具备:多轮对话、流式输出、工具执行(读文件、写文件、运行命令)、代码库上下文理解。

为什么这么简单? 因为 Claude Code 是终端工具,没有编程 API。OpenCode 也是 CLI,不能嵌入。A3S Code 是库——可以被你的代码直接调用,可以嵌入任何产品。

为什么编码智能体是 Agentic AI 的核心? 真正的"自主"需要一个条件:Agent 能够自己判断结果对不对,而不依赖人类来告诉它。客服 Agent 需要人类评价回答质量,写作 Agent 需要人类判断内容好坏——它们本质上是"执行者",不是"自主体"。编码 Agent 不同:编译器要么通过要么报错,测试要么绿要么红。这个客观的、可自动化的反馈回路让 Agent 能够真正自主——执行、验证、发现错误、自我修正,循环往复,不需要人类介入。一旦建立了这个能力,它可以迁移到任何有客观反馈的结构化环境:数据管道、基础设施配置、API 集成。这就是为什么编码智能体不只是 AI 的一个垂直应用,而是整个 Agentic AI 领域的核心形态。

Claude CodeOpenCodeOpenClawA3S Code
核心定位开发者终端工具开放生态终端工具消息平台个人助理可嵌入 Agent 基础设施
使用方式CLI 交互CLI 交互消息平台对话代码调用(库)
可嵌入性无编程 API无编程 API无编程 API核心设计目标
扩展方式MCP + Skills + HooksMCP + 插件插件Trait 扩展点 + MCP
多租户不支持不支持不支持支持
并行任务子 Agent 并行有限支持不支持Lane 队列 + 多机器分发
开源

这不是功能优劣的对比,是设计目标的对比。如果你在使用编码 Agent,Claude Code 是最成熟的选择。如果你在构建包含编码 Agent 能力的产品,A3S Code 提供了你需要的基础设施。


一、为什么 20 行就够了?极简核心 + 工具自举

这是构建 Agentic AI 系统最重要的架构原则,也是 A3S Code 的设计基础。

什么是极简核心?

极简核心的意思是:系统的不可替换部分应该尽可能小。

一个编码 Agent 的真正核心,只有五个组件:

Agent          ← 配置加载、会话生命周期管理
AgentSession   ← 工作区绑定的执行上下文
AgentLoop      ← 驱动 LLM 轮次的执行引擎
ToolExecutor   ← 工具注册、调度、执行
LlmClient      ← LLM 提供商的统一抽象

这五个组件是系统的骨架。它们之间的关系是固定的:Agent 创建 AgentSessionAgentSession 持有 AgentLoopAgentLoop 在每个轮次里调用 LlmClient 获取决策,再通过 ToolExecutor 执行工具。

这个骨架不应该随业务需求变化。它是稳定的、可测试的、可独立推理的。

什么是工具自举?

工具自举的意思是:Agent 的所有扩展能力,都通过工具来实现,而不是通过修改核心。

这个原则有两层含义:

第一层:内置工具覆盖基础能力。 文件读写、代码搜索、命令执行、网络请求——这些是编码 Agent 的基础动作,以内置工具的形式存在,开箱即用。

第二层:外部工具扩展专业能力。 数据库操作、代码审查、部署流水线、第三方 API——这些通过 MCP(Model Context Protocol)或自定义工具接入,不需要修改核心代码。

工具自举的关键洞察是:LLM 本身就是最好的工具路由器。 你不需要写复杂的意图识别逻辑,只需要给 LLM 提供足够清晰的工具描述,它会自己决定什么时候用什么工具。

这个设计的结果是:系统的能力边界由工具集决定,而工具集可以在运行时动态扩展,核心代码保持不变。

为什么这个原则重要?

考虑反面:如果你把权限控制、记忆管理、技能系统、MCP 集成都写进核心,会发生什么?

核心变得臃肿,每个新需求都需要修改核心,不同功能之间产生耦合,测试变得困难,维护成本指数级上升。

极简核心 + 工具自举把这些问题全部消解:核心只做一件事(驱动 LLM 轮次),其他一切都是可插拔的扩展。

在 A3S Code 里,这个原则体现为 19 个 trait 扩展点,每个都有默认实现:

// 不满意默认的权限系统?实现自己的
class MyPermissionChecker implements PermissionChecker {
  async check(tool: string, args: unknown): Promise<Permission> {
    // 你的逻辑
  }
}

const session = agent.session('.', {
  permissionChecker: new MyPermissionChecker(),
});

系统开箱即用,任何部分都可以替换,核心保持稳定。

工具自举的另一层含义:不需要预处理知识。 传统 RAG 的思路是"预先把知识向量化或图谱化,再检索注入"。但工具自举揭示了另一条路:Agent 不需要预先知道所有知识,它可以在需要的时候通过工具去读取。代码库不需要提前向量化——Agent 直接用 read_filesearch_code 工具按需读取。这不只是省去了预处理的工程成本,更重要的是:工具调用本身就是最精准的上下文检索,因为是 Agent 自己决定读什么,而不是检索系统猜测什么相关。


二、A3S Code 的完整能力边界

极简核心 + 工具自举是架构原则,但 A3S Code 的实际能力边界远不止于此。下面系统介绍所有核心特性,包括记忆系统、上下文检索、Hooks、安全层、规划器等。

2.1 记忆系统:跨会话的长期记忆

MemoryStore 让 Agent 在多次会话之间保留关键信息。不同于 SessionStore(保存对话历史),MemoryStore 存储的是提炼后的知识——用户偏好、项目上下文、重要决策。

import { MemoryStore, Memory } from '@a3s-lab/code';

class VectorMemoryStore implements MemoryStore {
  async save(memory: Memory): Promise<void> {
    // 存储到向量数据库(如 Pinecone、Qdrant)
    await vectorDB.upsert({
      id: memory.id,
      vector: await embed(memory.content),
      metadata: { timestamp: memory.timestamp, tags: memory.tags },
    });
  }

  async search(query: string, limit: number): Promise<Memory[]> {
    // 语义搜索相关记忆
    const results = await vectorDB.query(await embed(query), limit);
    return results.map((r) => ({
      id: r.id,
      content: r.metadata.content,
      timestamp: r.metadata.timestamp,
      tags: r.metadata.tags,
    }));
  }
}

const session = agent.session('.', {
  memoryStore: new VectorMemoryStore(),
});

// Agent 自动从记忆中检索相关上下文
await session.stream('继续上次的重构任务');
// → Agent 检索到「上次重构目标:auth 模块改用 JWT」

2.2 上下文检索(RAG):动态注入外部知识

ContextProvider 在每个轮次前自动检索相关文档,注入到 LLM 上下文。这是 RAG(Retrieval-Augmented Generation)的标准实现。

import { ContextProvider, ContextChunk } from '@a3s-lab/code';

class CodebaseContextProvider implements ContextProvider {
  async retrieve(query: string, maxChunks: number): Promise<ContextChunk[]> {
    // 从代码库索引中检索相关代码片段
    const results = await codeSearch.search(query, maxChunks);
    return results.map((r) => ({
      content: r.code,
      source: r.filePath,
      score: r.relevance,
    }));
  }
}

const session = agent.session('.', {
  contextProvider: new CodebaseContextProvider(),
});

// 用户问题触发自动检索
await session.stream('auth 模块的 JWT 验证逻辑在哪里?');
// → ContextProvider 检索到 src/auth/jwt.ts 的相关代码
// → LLM 基于检索到的代码回答

2.3 Hooks 系统:事件驱动的自动化

Hooks 在工具调用前后自动执行,用于日志记录、审计、自动化流程。

import { HookHandler, ToolCallEvent, ToolResultEvent } from '@a3s-lab/code';

class AuditHookHandler implements HookHandler {
  async onToolCall(event: ToolCallEvent): Promise<void> {
    // 工具调用前:记录审计日志
    await auditLog.write({
      timestamp: Date.now(),
      tool: event.tool,
      args: event.args,
      sessionId: event.sessionId,
    });

    // 高风险操作:发送通知
    if (['bash', 'write', 'delete'].includes(event.tool)) {
      await slack.notify(`⚠️ Agent 正在执行 ${event.tool}`);
    }
  }

  async onToolResult(event: ToolResultEvent): Promise<void> {
    // 工具执行后:记录结果
    await auditLog.write({
      timestamp: Date.now(),
      tool: event.tool,
      success: !event.result.isError,
      duration: event.duration,
    });
  }
}

const session = agent.session('.', {
  hookHandler: new AuditHookHandler(),
});

2.4 安全层:输入污点分析和输出净化

SecurityProvider 在工具执行前检测输入是否包含恶意内容,在输出前净化敏感信息。

import { SecurityProvider, TaintAnalysis, SanitizeResult } from '@a3s-lab/code';

class ProductionSecurityProvider implements SecurityProvider {
  async analyzeTaint(input: string): Promise<TaintAnalysis> {
    // 检测命令注入、路径遍历、SQL 注入
    const threats = [];
    if (/;\s*(rm|curl|wget|nc)\s/.test(input)) threats.push('command_injection');
    if (/\.\.[\\/\\]/.test(input)) threats.push('path_traversal');
    if (/(union|select|drop|insert)\s+/i.test(input)) threats.push('sql_injection');

    return {
      isTainted: threats.length > 0,
      threats,
      riskLevel: threats.length > 0 ? 'high' : 'low',
    };
  }

  async sanitizeOutput(output: string): Promise<SanitizeResult> {
    // 移除敏感信息:API key、密码、token
    let sanitized = output;
    sanitized = sanitized.replace(/sk-[a-zA-Z0-9]{48}/g, '[REDACTED_API_KEY]');
    sanitized = sanitized.replace(/password["\s:=]+[^\s"]+/gi, 'password=[REDACTED]');
    sanitized = sanitized.replace(/Bearer\s+[^\s]+/g, 'Bearer [REDACTED]');

    return { sanitized, redacted: sanitized !== output };
  }
}

const session = agent.session('.', {
  securityProvider: new ProductionSecurityProvider(),
});

2.5 规划器:复杂任务的自动分解

Planner 把复杂任务分解为子任务序列,Agent 按计划逐步执行。

import { Planner, Task, Plan } from '@a3s-lab/code';

class HierarchicalPlanner implements Planner {
  async plan(goal: string, context: string): Promise<Plan> {
    // 调用 LLM 生成任务分解
    const response = await llm.complete({
      prompt: `目标:${goal}\n上下文:${context}\n\n请分解为可执行的子任务序列。`,
    });

    const tasks: Task[] = parseTasksFromResponse(response);
    return {
      goal,
      tasks,
      estimatedSteps: tasks.length,
    };
  }
}

const session = agent.session('.', {
  planner: new HierarchicalPlanner(),
});

// 复杂任务自动分解
await session.stream('重构整个 auth 模块,改用 JWT,添加 refresh token 机制,更新所有测试');
// → Planner 分解为:
//   1. 阅读现有 auth 代码
//   2. 设计 JWT + refresh token 方案
//   3. 实现新的 auth 逻辑
//   4. 更新测试
//   5. 验证所有测试通过

2.6 上下文压缩:自动管理 Token 预算

当对话历史超过阈值时,ContextCompactor 自动压缩旧轮次,保留关键信息。

// 在 agent.hcl 中配置
context_compaction {
  enabled           = true
  trigger_threshold = 100000  # 超过 10 万 token 触发压缩
  target_size       = 50000   # 压缩到 5 万 token
  strategy          = "semantic"  # 语义压缩(保留关键信息)
}

压缩策略:

  • Truncate:直接删除最早的轮次
  • Summarize:用 LLM 总结旧轮次,保留摘要
  • Semantic:基于语义相似度保留最相关的轮次

2.7 多语言 SDK:Rust / Node.js / Python

A3S Code 是 Rust 核心库,通过 FFI 提供 Node.js 和 Python 原生绑定。

Rust API(零开销,最高性能):

use a3s_code::{Agent, AgentSession};

#[tokio::main]
async fn main() -> Result<()> {
    let agent = Agent::new("agent.hcl").await?;
    let session = agent.session("/project", None)?;

    let mut stream = session.stream("重构 auth 模块").await?;
    while let Some(event) = stream.next().await {
        match event {
            Event::TextDelta(text) => print!("{}", text),
            Event::ToolUse(tool) => println!("\n[{}]", tool.name),
            Event::End => println!(),
            _ => {}
        }
    }
    Ok(())
}

Python SDK(异步优先,类型提示):

from a3s_code import Agent, SessionLane
import asyncio

async def main():
    agent = await Agent.create("agent.hcl")
    session = agent.session(".", tools=finance_tools)

    # 并行研究
    tasks = [
        {"prompt": f"分析 {sym}", "lane": SessionLane.GENERATE}
        for sym in ["AAPL", "MSFT", "NVDA"]
    ]
    results = await session.submit_batch(tasks)
    print(results)

asyncio.run(main())

2.8 特性总结

特性用途扩展点
记忆系统跨会话长期记忆MemoryStore
上下文检索RAG 动态注入知识ContextProvider
Hooks事件驱动自动化HookHandler
安全层输入污点分析、输出净化SecurityProvider
规划器复杂任务分解Planner
上下文压缩自动管理 token 预算配置驱动
多语言 SDKRust/Node.js/Python原生绑定

这些特性全部是可选扩展——系统有默认实现,开箱即用;如果需要定制,实现对应的 trait 即可。核心代码保持不变。

2.9 上下文工程:渐进式披露

上下文工程(Context Engineering)的核心问题是:如何在有限的 token 预算内,让 Agent 在每个轮次都拥有恰好足够的信息?

答案是渐进式披露(Progressive Disclosure):Agent 不是一次性把所有知识塞进上下文,而是按需、分层地获取信息。

以理解一个陌生代码库为例,Agent 的自然行为是:

  1. 读目录结构 → 了解全局布局(低成本,高覆盖)
  2. 读关键文件的顶部注释 → 了解模块职责(中等成本)
  3. 定位具体函数 → 读取实现细节(高成本,精准)

每一步都是按需披露,上下文始终保持精简。这比"把整个代码库向量化后检索"更准确,因为 Agent 自己知道它需要什么。

A3S Code 的实现:

// ContextProvider:每个轮次前自动检索相关上下文
class ProgressiveContextProvider implements ContextProvider {
  async retrieve(query: string, maxChunks: number): Promise<ContextChunk[]> {
    // 第一层:目录结构(总是注入)
    const structure = await getProjectStructure();
    // 第二层:语义相关的文件摘要
    const summaries = await searchFileSummaries(query, maxChunks - 1);
    // 第三层:精确匹配的代码片段(按需)
    const snippets = await searchCodeSnippets(query, 2);
    return [structure, ...summaries, ...snippets];
  }
}

const session = agent.session('.', {
  contextProvider: new ProgressiveContextProvider(),
  // MemoryStore 保留跨会话的关键发现,避免重复探索
  memoryStore: new FileMemoryStore('.a3s/memory'),
});

ContextProvider 控制每轮注入什么,MemoryStore 保留跨会话的关键知识,ContextCompactor 在 token 超限时自动压缩旧轮次——三者共同构成 A3S Code 的上下文工程体系。


三、A3S Code + A3S Box:给 Agent 提供沙箱环境

Agent 执行代码时,默认在宿主机上运行——这意味着恶意代码、意外删除、资源耗尽等风险直接暴露给你的系统。A3S Box 是一个轻量级 MicroVM 沙箱,为 Agent 的代码执行提供完全隔离的环境。

3.1 A3S Box 是什么?

A3S Box 是基于 libkrun 的嵌入式 MicroVM 沙箱,特点是:

  • 轻量级:启动时间 < 100ms,内存占用 < 50MB
  • 无守护进程:直接嵌入你的应用,不需要 Docker daemon
  • 完全隔离:独立的文件系统、网络、进程空间
  • TEE 支持:可选的可信执行环境(AMD SEV-SNP)

状态机:Created → Ready → Busy → Stopped

3.2 为什么 Agent 需要沙箱?

考虑这个场景:用户让 Agent「清理项目中的临时文件」,Agent 执行了 rm -rf /tmp/*——但由于路径解析错误,实际执行的是 rm -rf /*

没有沙箱:宿主机文件系统被破坏。

有沙箱:只有 Box 内的文件系统受影响,宿主机安全。

其他风险场景:

  • Agent 下载并执行恶意脚本
  • Agent 启动占用所有 CPU 的进程
  • Agent 意外暴露敏感文件(如 .env

A3S Box 把这些风险全部隔离在沙箱内。

3.3 集成方式:将 Agent 的代码执行路由到 Box

import { Agent } from '@a3s-lab/code';
import { BoxSdk } from '@a3s-lab/box';

async function main() {
  // 创建 Box SDK 实例
  const boxSdk = new BoxSdk();

  // 创建沙箱:Alpine Linux,512MB 内存,挂载当前目录
  const sandbox = boxSdk.create({
    image: 'alpine:latest',
    memoryMb: 512,
    mounts: [{ hostPath: process.cwd(), guestPath: '/workspace', readonly: false }],
    workdir: '/workspace',
  });

  // 定义 Box 工具:在沙箱内执行命令
  const boxTools = [
    {
      name: 'bash',
      description: '在隔离的沙箱环境中执行 shell 命令',
      parameters: {
        type: 'object',
        properties: {
          command: { type: 'string', description: 'Shell 命令' },
        },
        required: ['command'],
      },
      execute: async (args: { command: string }) => {
        const result = await sandbox.exec('sh', ['-c', args.command]);
        return {
          content: result.stdout,
          isError: result.exitCode !== 0,
        };
      },
    },
  ];

  // Agent 的 bash 工具现在路由到 Box
  const agent = await Agent.create('agent.hcl');
  const session = agent.session('.', { tools: boxTools });

  // 用户请求执行危险操作,但只影响沙箱
  await session.stream('删除所有 .tmp 文件');
  // → Agent 调用 bash 工具
  // → 命令在 Box 内执行,宿主机安全

  // 任务完成后停止沙箱
  sandbox.stop();
}

3.4 扩展 Box 工具:文件上传/下载、快照

除了命令执行,Box 还支持文件传输和快照管理:

const boxTools = [
  {
    name: 'box_exec',
    description: '在沙箱中执行命令',
    execute: async (args: { command: string }) => {
      const result = await sandbox.exec('sh', ['-c', args.command]);
      return { content: result.stdout, isError: result.exitCode !== 0 };
    },
  },
  {
    name: 'box_upload',
    description: '上传文件到沙箱',
    parameters: {
      type: 'object',
      properties: {
        localPath: { type: 'string' },
        guestPath: { type: 'string' },
      },
      required: ['localPath', 'guestPath'],
    },
    execute: async (args: { localPath: string; guestPath: string }) => {
      const data = await fs.readFile(args.localPath);
      await sandbox.upload(data, args.guestPath);
      return { content: `已上传 ${args.localPath}${args.guestPath}` };
    },
  },
  {
    name: 'box_download',
    description: '从沙箱下载文件',
    parameters: {
      type: 'object',
      properties: {
        guestPath: { type: 'string' },
        localPath: { type: 'string' },
      },
      required: ['guestPath', 'localPath'],
    },
    execute: async (args: { guestPath: string; localPath: string }) => {
      const data = await sandbox.download(args.guestPath);
      await fs.writeFile(args.localPath, data);
      return { content: `已下载 ${args.guestPath}${args.localPath}` };
    },
  },
];

3.5 Skill 机制:教 Agent 如何操作 Box

通过 Skill 文件,你可以教 Agent 在什么场景下使用 Box,以及如何安全地操作沙箱。

<!-- skills/box_operator.md -->
# Box 沙箱操作员

## 可用工具
- `box_exec`: 在沙箱中执行命令
- `box_upload`: 上传文件到沙箱
- `box_download`: 从沙箱下载文件

## 操作规范

### 何时使用沙箱
以下操作**必须**在沙箱中执行,不得在宿主机上运行:
- 执行用户提供的脚本或命令
- 安装第三方依赖(npm install, pip install)
- 运行测试(可能包含恶意测试用例)
- 编译未知来源的代码
- 任何涉及 `rm``mv``chmod` 的文件操作

### 安全检查清单
在执行任何命令前,检查:
1. 命令是否包含 `rm -rf /``:(){ :|:& };:` 等危险模式
2. 是否需要 root 权限(沙箱内无 root)
3. 是否需要网络访问(默认隔离)

### 文件传输规范
- 上传前验证文件大小(< 100MB)
- 下载前验证路径(不得包含 `..`- 敏感文件(.env, id_rsa)不得上传到沙箱

## 示例工作流

用户请求:「运行项目的测试套件」

1. 检查测试命令(如 `npm test`)
2. 上传项目文件到沙箱 `/workspace`
3. 在沙箱中执行 `npm install && npm test`
4. 下载测试报告到宿主机
5. 停止沙箱释放资源

加载 Skill 后,Agent 会自动遵循这些规范:

const session = agent.session('.', {
  tools: boxTools,
  skills: ['box_operator'],
});

// Agent 自动判断需要使用沙箱
await session.stream('帮我运行测试,然后清理所有临时文件');
// → Agent 读取 box_operator skill
// → 识别「运行测试」和「清理文件」是危险操作
// → 自动使用 box_exec 在沙箱中执行
// → 宿主机安全

3.6 完整示例:沙箱化的编码 Agent

import { Agent } from '@a3s-lab/code';
import { BoxSdk } from '@a3s-lab/box';
import * as fs from 'fs/promises';

async function main() {
  const boxSdk = new BoxSdk();
  const sandbox = boxSdk.create({
    image: 'node:20-alpine',
    memoryMb: 1024,
    mounts: [{ hostPath: process.cwd(), guestPath: '/workspace' }],
    workdir: '/workspace',
    network: true, // 允许网络访问(npm install)
  });

  const boxTools = [
    {
      name: 'bash',
      description: '在隔离沙箱中执行命令',
      execute: async (args: { command: string }) => {
        const result = await sandbox.exec('sh', ['-c', args.command]);
        return { content: result.stdout, isError: result.exitCode !== 0 };
      },
    },
  ];

  const agent = await Agent.create('agent.hcl');
  const session = agent.session('.', {
    tools: boxTools,
    skills: ['box_operator'],
  });

  console.log('沙箱化编码 Agent 就绪。所有代码执行都在隔离环境中进行。\n');

  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
  rl.on('close', () => {
    sandbox.stop();
    process.exit(0);
  });

  while (true) {
    const input = await new Promise<string>((resolve) => rl.question('> ', resolve));
    if (!input.trim()) continue;

    const events = await session.stream(input);
    for await (const event of events) {
      if (event.type === 'text_delta') process.stdout.write(event.text);
      else if (event.type === 'tool_use') process.stdout.write(`\n[沙箱] ${event.tool} `);
      else if (event.type === 'end') console.log('\n');
    }
  }
}

main().catch(console.error);

3.7 Box 的其他能力

持久化工作区:多次会话共享同一个沙箱状态

const sandbox = boxSdk.create({
  image: 'ubuntu:22.04',
  workspace: { name: 'my-project', guestPath: '/workspace' },
});
// 工作区内容在沙箱停止后保留,下次启动时恢复

端口转发:访问沙箱内的服务

const sandbox = boxSdk.create({
  image: 'node:20',
  portForwards: [{ guestPort: 3000, hostPort: 3000 }],
});
// 沙箱内的 3000 端口映射到宿主机 3000

TEE 模式:可信执行环境(需要硬件支持)

const sandbox = boxSdk.create({
  image: 'alpine:latest',
  tee: true, // 启用 AMD SEV-SNP
});
// 沙箱内存加密,宿主机无法读取

四、用 TypeScript SDK 构建类 Claude Code 的产品

理解了架构原则,现在来实践。我们用 A3S Code 的 TypeScript SDK 构建一个具备 Claude Code 核心能力的终端编码助手。

目标产品具备:

  • 多轮对话,理解代码库上下文
  • 流式输出,实时显示 Agent 思考过程
  • 工具执行(读文件、写文件、运行命令)
  • 权限控制,敏感操作需要用户确认
  • MCP 服务器支持,动态扩展工具集
  • 会话持久化,支持恢复上次对话

4.1 安装和配置

npm install @a3s-lab/code

创建 agent.hcl 配置文件:

# 支持任何 OpenAI 兼容端点
default_model = "anthropic/claude-sonnet-4-20250514"

providers {
  name    = "anthropic"
  api_key = env("ANTHROPIC_API_KEY")
}

# 可选:接入 MCP 服务器
mcp_servers {
  name    = "filesystem"
  command = "npx"
  args    = ["-y", "@modelcontextprotocol/server-filesystem", "."]
}

4.2 核心会话循环

这是整个产品的骨架——一个读取用户输入、流式输出 Agent 响应的循环。升级版本展示完整的事件处理:thinking 过程、工具调用结果、token 用量统计、以及中断恢复:

import { Agent, AgentSession, StreamEvent } from '@a3s-lab/code';
import * as readline from 'readline';

const agent = await Agent.create('agent.hcl');
const session = agent.session(process.cwd());

const rl = readline.createInterface({ input: process.stdin, output: process.stdout });

// 优雅退出:Ctrl+C 时等待当前轮次完成
let currentAbort: AbortController | null = null;
rl.on('close', async () => {
  currentAbort?.abort();
  await session.flush(); // 等待持久化完成
  process.exit(0);
});

console.log('A3S Code — 输入你的问题,Ctrl+C 退出\n');

while (true) {
  const input = await new Promise<string>((resolve) => rl.question('> ', resolve));
  if (!input.trim()) continue;

  currentAbort = new AbortController();
  const startTime = Date.now();

  try {
    const events = await session.stream(input, { signal: currentAbort.signal });

    let toolCount = 0;
    let inputTokens = 0;
    let outputTokens = 0;

    for await (const event of events) {
      switch (event.type) {
        case 'thinking':
          // Agent 的推理过程(仅在支持 extended thinking 的模型上出现)
          process.stdout.write(`\x1b[2m${event.thinking}\x1b[0m`);
          break;

        case 'text_delta':
          process.stdout.write(event.text);
          break;

        case 'tool_use':
          toolCount++;
          process.stdout.write(`\n\x1b[36m[${event.tool}]\x1b[0m `);
          break;

        case 'tool_result':
          // 工具执行完成:显示耗时和结果摘要
          const preview = typeof event.result.content === 'string'
            ? event.result.content.slice(0, 80).replace(/\n/g, ' ')
            : '[binary]';
          process.stdout.write(
            event.result.isError
              ? `\x1b[31m✗ ${preview}\x1b[0m\n`
              : `\x1b[32m✓\x1b[0m ${preview}…\n`
          );
          break;

        case 'usage':
          // token 用量(每轮结束时触发)
          inputTokens = event.inputTokens;
          outputTokens = event.outputTokens;
          break;

        case 'end':
          const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
          console.log(
            `\n\x1b[2m[${toolCount} tools · ${inputTokens}${outputTokens}↓ tokens · ${elapsed}s]\x1b[0m\n`
          );
          break;
      }
    }
  } catch (err) {
    if ((err as Error).name === 'AbortError') {
      console.log('\n[已中断]\n');
    } else {
      console.error(`\n\x1b[31m错误:${(err as Error).message}\x1b[0m\n`);
    }
  } finally {
    currentAbort = null;
  }
}

4.3 添加权限控制

Claude Code 的一个核心设计是:危险操作需要用户确认。我们用 A3S Code 的权限系统实现同样的效果:

import { Agent, PermissionChecker, Permission } from '@a3s-lab/code';
import * as readline from 'readline';

// 需要确认的高风险工具
const DANGEROUS_TOOLS = new Set(['bash', 'write', 'edit', 'patch']);

class InteractivePermissionChecker implements PermissionChecker {
  private rl: readline.Interface;

  constructor(rl: readline.Interface) {
    this.rl = rl;
  }

  async check(tool: string, args: unknown): Promise<Permission> {
    // 只读工具直接放行
    if (!DANGEROUS_TOOLS.has(tool)) {
      return Permission.Allow;
    }

    // 显示将要执行的操作
    const preview = this.formatPreview(tool, args);
    console.log(`\n⚠️  Agent 想要执行:\n${preview}`);

    const answer = await new Promise<string>((resolve) => {
      this.rl.question('允许?[y/N] ', resolve);
    });

    return answer.toLowerCase() === 'y' ? Permission.Allow : Permission.Deny;
  }

  private formatPreview(tool: string, args: unknown): string {
    const a = args as Record<string, unknown>;
    switch (tool) {
      case 'bash':
        return `  $ ${a.command}`;
      case 'write':
        return `  写入文件: ${a.file_path}`;
      case 'edit':
        return `  编辑文件: ${a.file_path}`;
      default:
        return `  ${tool}: ${JSON.stringify(args, null, 2)}`;
    }
  }
}

// 集成到 session
const session = agent.session(process.cwd(), {
  permissionChecker: new InteractivePermissionChecker(rl),
});

4.4 添加 MCP 服务器动态注册

Claude Code 支持在配置文件里声明 MCP 服务器。A3S Code 还支持在运行时动态注册,这让你可以根据用户的项目类型按需加载工具:

// 检测项目类型,按需加载 MCP 服务器
async function loadProjectMcpServers(session: AgentSession, projectPath: string) {
  const fs = await import('fs/promises');

  // 检测到 package.json → 加载 Node.js 相关工具
  try {
    await fs.access(`${projectPath}/package.json`);
    const count = await session.addMcpServer(
      'nodejs-tools',
      'npx',
      ['-y', '@modelcontextprotocol/server-filesystem', projectPath],
    );
    console.log(`[MCP] 加载 Node.js 工具集,${count} 个工具可用`);
  } catch {}

  // 检测到 Cargo.toml → 加载 Rust 相关工具
  try {
    await fs.access(`${projectPath}/Cargo.toml`);
    const count = await session.addMcpServer(
      'rust-tools',
      'npx',
      ['-y', '@modelcontextprotocol/server-filesystem', projectPath],
    );
    console.log(`[MCP] 加载 Rust 工具集,${count} 个工具可用`);
  } catch {}
}

4.5 添加会话持久化

Claude Code 支持恢复上次会话。A3S Code 通过 SessionStore trait 实现同样的能力:

import { SessionStore, SessionData } from '@a3s-lab/code';
import * as fs from 'fs/promises';
import * as path from 'path';

class FileSessionStore implements SessionStore {
  private storePath: string;

  constructor(storePath: string) {
    this.storePath = storePath;
  }

  async save(sessionId: string, data: SessionData): Promise<void> {
    const filePath = path.join(this.storePath, `${sessionId}.json`);
    await fs.mkdir(this.storePath, { recursive: true });
    await fs.writeFile(filePath, JSON.stringify(data, null, 2));
  }

  async load(sessionId: string): Promise<SessionData | null> {
    const filePath = path.join(this.storePath, `${sessionId}.json`);
    try {
      const content = await fs.readFile(filePath, 'utf-8');
      return JSON.parse(content);
    } catch {
      return null;
    }
  }

  async delete(sessionId: string): Promise<void> {
    const filePath = path.join(this.storePath, `${sessionId}.json`);
    await fs.unlink(filePath).catch(() => {});
  }
}

// 使用项目目录作为会话 ID,实现「每个项目一个会话」
const projectId = Buffer.from(process.cwd()).toString('base64url');
const session = agent.session(process.cwd(), {
  sessionId: projectId,
  sessionStore: new FileSessionStore(path.join(process.env.HOME!, '.a3s/sessions')),
  permissionChecker: new InteractivePermissionChecker(rl),
});

4.6 添加斜杠命令

Claude Code 有 /help/clear/cost 等内置命令。A3S Code 的 SlashCommand 接口让你实现同样的功能:

import { SlashCommand, CommandContext, CommandOutput } from '@a3s-lab/code';

// /cost 命令:显示本次会话的 token 消耗
class CostCommand implements SlashCommand {
  name = 'cost';
  description = '显示本次会话的 token 消耗和估算费用';

  execute(_args: string, ctx: CommandContext): CommandOutput {
    const usage = ctx.tokenUsage;
    // Claude Sonnet 4 定价(仅供参考)
    const inputCost = (usage.promptTokens / 1_000_000) * 3.0;
    const outputCost = (usage.completionTokens / 1_000_000) * 15.0;
    const total = inputCost + outputCost;

    return CommandOutput.text(
      `Token 消耗:\n` +
      `  输入:${usage.promptTokens.toLocaleString()} tokens ($${inputCost.toFixed(4)})\n` +
      `  输出:${usage.completionTokens.toLocaleString()} tokens ($${outputCost.toFixed(4)})\n` +
      `  合计:$${total.toFixed(4)}`
    );
  }
}

// /clear 命令:清空对话历史
class ClearCommand implements SlashCommand {
  name = 'clear';
  description = '清空对话历史,开始新会话';

  execute(_args: string, ctx: CommandContext): CommandOutput {
    ctx.clearHistory();
    return CommandOutput.text('对话历史已清空');
  }
}

session.registerCommand(new CostCommand());
session.registerCommand(new ClearCommand());

4.7 完整产品组装

把所有部分组合起来:

import { Agent } from '@a3s-lab/code';
import * as readline from 'readline';
import * as path from 'path';

async function main() {
  const agent = await Agent.create('agent.hcl');

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal: true,
  });

  // 处理 Ctrl+C
  rl.on('close', () => {
    console.log('\n再见!');
    process.exit(0);
  });

  const projectId = Buffer.from(process.cwd()).toString('base64url');

  const session = agent.session(process.cwd(), {
    sessionId: projectId,
    sessionStore: new FileSessionStore(
      path.join(process.env.HOME!, '.a3s/sessions')
    ),
    permissionChecker: new InteractivePermissionChecker(rl),
  });

  // 注册命令
  session.registerCommand(new CostCommand());
  session.registerCommand(new ClearCommand());

  // 按需加载 MCP 服务器
  await loadProjectMcpServers(session, process.cwd());

  // 显示欢迎信息
  const isResumed = await session.hasHistory();
  if (isResumed) {
    console.log('✓ 已恢复上次会话。输入 /clear 开始新对话。\n');
  } else {
    console.log('A3S Code — 输入你的问题,/help 查看命令,Ctrl+C 退出\n');
  }

  // 主循环
  while (true) {
    const input = await new Promise<string>((resolve) => {
      rl.question('> ', resolve);
    });

    if (!input.trim()) continue;

    // 斜杠命令
    if (input.startsWith('/')) {
      const output = await session.executeCommand(input);
      console.log(output.text);
      continue;
    }

    // Agent 流式响应
    try {
      const events = await session.stream(input);
      for await (const event of events) {
        if (event.type === 'text_delta') {
          process.stdout.write(event.text);
        } else if (event.type === 'tool_use') {
          process.stdout.write(`\n[${event.tool}] `);
        } else if (event.type === 'end') {
          console.log('\n');
        }
      }
    } catch (err) {
      console.error(`\n错误:${err instanceof Error ? err.message : err}\n`);
    }
  }
}

main().catch(console.error);

这个产品已经具备了 Claude Code 的核心能力:多轮对话、流式输出、工具执行、权限控制、MCP 支持、会话持久化、斜杠命令。代码量不到 200 行。


五、用编码智能体构建 Agentic 金融应用

编码智能体不只是为开发者服务的工具——它是构建任何领域 Agentic 应用的基础设施。真正的 Agentic 应用和普通聊天机器人的区别在于:它能自主规划、并行执行、协调多个专业 Agent 协作,而不只是被动响应单条指令。

下面用 A3S Code TypeScript SDK 构建一个金融研究系统,展示四个核心 Agentic 特性:技能系统自动规划Agent Team并行研究分析

5.1 技能系统:定义专业行为规范

技能(Skill)是 Markdown 格式的行为规范文件,告诉 Agent 在特定场景下应该遵循什么流程。它不是代码,而是结构化的专业知识。

<!-- skills/portfolio_analyst.md -->
# 投资组合分析师

## 分析流程

收到投资组合分析请求时,**必须**按以下顺序执行,不得跳过任何步骤:

1. **数据收集**:调用 get_portfolio 获取所有持仓,调用 get_quote 获取实时报价
2. **并行研究**:对每只持仓股票同时启动独立分析任务(使用 submit_batch)
3. **风险评估**:计算组合整体波动率、集中度风险、相关性
4. **生成报告**:输出结构化报告,包含持仓概览、风险评级、调仓建议

## 报告格式

\`\`\`
## 投资组合分析报告
**分析时间**: {timestamp}
**总市值**: ${total_value}  **总盈亏**: ${total_pnl} ({pnl_pct}%)

### 持仓明细
| 股票 | 持仓 | 成本 | 现价 | 盈亏 | 风险 |
...

### 风险评估
- 组合集中度: {concentration}
- 最高风险持仓: {symbol}
- 建议: {recommendation}
\`\`\`

## 注意事项
- 所有建议必须基于数据,不得主观臆断
- 高风险持仓必须在报告中明确标注
- 调仓建议需说明理由

在 HCL 配置中加载技能:

# agent.hcl
default_model = "anthropic/claude-sonnet-4-20250514"

providers {
  name    = "anthropic"
  api_key = env("ANTHROPIC_API_KEY")
}

# 加载技能文件目录
skills_dir = "./skills"

技能系统的价值在于可复用的专业知识:同一套分析流程可以被不同的 Agent 实例加载,确保行为一致性,也方便团队协作维护。

5.2 自动规划:一句话触发完整分析流程

当用户说「帮我做一份完整的投资组合分析」时,Agent 不会直接回答——它会先规划,再执行

import { Agent, SessionLane } from '@a3s-lab/code';

const agent = await Agent.create('agent.hcl');

// 加载投资组合分析师技能
const session = agent.session('.', {
  tools: financeTools,
  skills: ['portfolio_analyst'],  // 注入专业行为规范
});

// 用户只需一句话,Agent 自动规划并执行完整流程:
// 1. 调用 get_portfolio 获取持仓
// 2. 调用 get_quote 批量获取报价
// 3. 启动并行研究任务(每只股票独立分析)
// 4. 汇总结果,生成结构化报告
const events = await session.stream(
  '帮我做一份完整的投资组合分析,重点关注风险敞口和调仓建议'
);

for await (const event of events) {
  if (event.type === 'text_delta') process.stdout.write(event.text);
  else if (event.type === 'tool_use') console.log(`\n→ [${event.tool}]`);
  else if (event.type === 'end') console.log('\n');
}

这里的关键是:技能文件定义了规划逻辑,Agent 自主决定调用顺序和工具组合。你不需要写任何编排代码。

5.3 并行研究:同时分析多只股票

对多只股票做深度研究时,串行执行会很慢。submitBatch 让多个分析任务并行运行,并支持进度追踪和部分失败处理:

import { Agent, SessionLane, BatchResult } from '@a3s-lab/code';

async function parallelStockResearch(symbols: string[]) {
  const agent = await Agent.create('agent.hcl');
  const session = agent.session('.', { tools: financeTools });

  // 为每只股票创建独立的深度研究任务
  const researchTasks = symbols.map((sym) => ({
    id: sym, // 任务 ID,用于追踪进度
    prompt: `对 ${sym} 进行深度分析:
      1. 获取实时报价和成交量
      2. 评估当前风险等级(低/中/高)
      3. 基于数据给出买入/持有/卖出建议
      输出结构化 JSON:{ symbol, price, volume, risk, recommendation, rationale }`,
    lane: SessionLane.Generate,
  }));

  console.log(`启动 ${symbols.length} 个并行研究任务...\n`);

  // 进度回调:每个任务完成时实时输出
  const results = await session.submitBatch(researchTasks, {
    onProgress: (completed, total, result: BatchResult) => {
      const icon = result.error ? '✗' : '✓';
      const summary = result.error
        ? result.error.message
        : JSON.parse(result.output).recommendation ?? 'done';
      console.log(`[${completed}/${total}] ${icon} ${result.id}: ${summary}`);
    },
    // 部分失败不中断:收集所有结果后统一处理
    continueOnError: true,
  });

  // 分离成功和失败的任务
  const succeeded = results.filter((r) => !r.error);
  const failed = results.filter((r) => r.error);

  if (failed.length > 0) {
    console.warn(`\n⚠ ${failed.length} 个任务失败:${failed.map((r) => r.id).join(', ')}`);
  }

  // 把成功的结果交给汇总 Agent
  const summarySession = agent.session('.', { tools: financeTools });
  const summaryEvents = await summarySession.stream(
    `以下是对各股票的独立研究结果(${succeeded.length}/${symbols.length} 成功):\n` +
    `${JSON.stringify(succeeded.map((r) => JSON.parse(r.output)), null, 2)}\n\n` +
    `请综合以上分析,生成投资组合优化建议,包含风险分散建议和仓位调整方案。` +
    (failed.length > 0 ? `\n注意:${failed.map((r) => r.id).join(', ')} 数据缺失,建议保守处理。` : '')
  );

  for await (const event of summaryEvents) {
    if (event.type === 'text_delta') process.stdout.write(event.text);
    else if (event.type === 'end') console.log('\n');
  }
}

// 并行研究 4 只股票,耗时约等于单只股票的分析时间
await parallelStockResearch(['AAPL', 'MSFT', 'NVDA', 'TSLA']);

5.4 Agent Team:专业分工协作

复杂的金融分析需要不同专业能力的协作。Agent Team 让你把任务分配给专门的 Worker Agent,由 Lead Agent 统一协调。

import { Agent, AgentTeam } from '@a3s-lab/code';

async function buildFinanceTeam() {
  // Lead Agent:接收用户请求,规划任务,分配给 Worker,汇总结果
  const lead = await Agent.create('agent.hcl');
  const leadSession = lead.session('.', {
    tools: financeTools,
    skills: ['portfolio_analyst'],
    role: 'lead',
  });

  // Worker 1:市场分析师,专注行情数据和技术指标
  const marketAnalyst = await Agent.create('agent.hcl');
  const marketSession = marketAnalyst.session('.', {
    tools: [financeTools.find((t) => t.name === 'get_quote')!],
    systemPrompt: '你是市场分析师,专注于股票行情数据、成交量分析和价格趋势。',
    role: 'worker',
    workerId: 'market_analyst',
  });

  // Worker 2:风险分析师,专注风险评估和压力测试
  const riskAnalyst = await Agent.create('agent.hcl');
  const riskSession = riskAnalyst.session('.', {
    tools: [financeTools.find((t) => t.name === 'risk_assessment')!],
    systemPrompt: '你是风险分析师,专注于波动率计算、风险敞口评估和压力测试。',
    role: 'worker',
    workerId: 'risk_analyst',
  });

  // 组建 Team,Lead 可以把子任务委派给 Worker
  const team = AgentTeam.create({
    lead: leadSession,
    workers: [marketSession, riskSession],
  });

  // Lead 接收用户请求,自动决定哪些子任务交给哪个 Worker
  // 例如:行情数据 → market_analyst,风险计算 → risk_analyst
  // 两个 Worker 并行工作,Lead 汇总结果后回复用户
  const events = await team.stream(
    '分析我的持仓,市场分析师负责行情,风险分析师负责风险评估,最后给我综合建议'
  );

  for await (const event of events) {
    if (event.type === 'text_delta') process.stdout.write(event.text);
    else if (event.type === 'worker_started') {
      console.log(`\n[Team] ${event.workerId} 开始工作...`);
    } else if (event.type === 'worker_completed') {
      console.log(`\n[Team] ${event.workerId} 完成`);
    } else if (event.type === 'end') {
      console.log('\n');
    }
  }
}

buildFinanceTeam().catch(console.error);

5.5 完整系统:四个特性协同工作

把以上特性组合成一个完整的金融研究终端:

import { Agent, AgentTeam, SessionLane } from '@a3s-lab/code';
import * as readline from 'readline';

async function main() {
  const agent = await Agent.create('agent.hcl');
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
  rl.on('close', () => process.exit(0));

  // 主会话:加载技能,具备自动规划能力
  const session = agent.session('.', {
    tools: financeTools,
    skills: ['portfolio_analyst'],
    role: 'lead',
    queueConfig: { queryMaxConcurrency: 4 },  // Query 通道最多 4 个并行
  });

  // 注册斜杠命令
  session.registerCommand({
    name: 'research',
    description: '并行研究多只股票,用法: /research AAPL MSFT NVDA',
    execute: async (args) => {
      const symbols = args.trim().split(/\s+/).filter(Boolean);
      if (symbols.length === 0) return { text: '用法: /research AAPL MSFT NVDA' };

      console.log(`\n启动 ${symbols.length} 个并行研究任务...\n`);
      const tasks = symbols.map((sym) => ({
        prompt: `分析 ${sym}:报价、风险等级、投资建议`,
        lane: SessionLane.Generate,
      }));

      const results = await session.submitBatch(tasks);
      return { text: JSON.stringify(results, null, 2) };
    },
  });

  console.log('金融研究系统就绪。\n');
  console.log('  > 帮我做一份完整的投资组合分析        (自动规划 + 技能系统)');
  console.log('  > /research AAPL MSFT NVDA TSLA       (并行研究)');
  console.log('  > 组建分析团队,深度研究科技股板块     (Agent Team)\n');

  while (true) {
    const input = await new Promise<string>((resolve) => rl.question('> ', resolve));
    if (!input.trim()) continue;

    if (input.startsWith('/')) {
      const output = await session.executeCommand(input);
      console.log(output.text + '\n');
      continue;
    }

    const events = await session.stream(input);
    for await (const event of events) {
      if (event.type === 'text_delta') process.stdout.write(event.text);
      else if (event.type === 'tool_use') process.stdout.write(`\n→ [${event.tool}] `);
      else if (event.type === 'end') console.log('\n');
    }
  }
}

main().catch(console.error);

这个系统和普通聊天机器人的本质区别:用户说一句「做完整分析」,系统会自主规划步骤并行执行研究协调多个专业 Agent,最后汇总成结构化报告——整个过程不需要用户逐步指导。这才是 Agentic 应用的核心价值。


六、从单机到多机:Lane 队列的价值

上面构建的是单机版本。当你的产品需要处理更复杂的场景时——比如同时服务多个用户、或者把计算密集型任务分发到远程机器——Lane 队列提供了解决方案。

Lane 队列把工具调用按优先级分为四个通道:

Control (P0) ← 控制指令,最高优先级,顺序执行
Query   (P1) ← 读文件、搜索,并行执行
Execute (P2) ← 写文件、运行命令,顺序执行
Generate(P3) ← LLM 调用,最低优先级

Query 通道的并行执行是关键优化:当 LLM 在一个轮次里返回多个读文件请求时,它们会并行执行,而不是串行等待。

import { SessionQueueConfig } from '@a3s-lab/code';

const session = agent.session(process.cwd(), {
  queueConfig: {
    enableAllFeatures: true,
    queryMaxConcurrency: 8,  // 最多 8 个读操作并行
  },
});

当你需要把执行任务分发到远程机器时:

// 把 Execute 通道切换为外部模式
await session.setLaneHandler('execute', {
  mode: 'external',
  timeoutMs: 120_000,
});

// 监听外部任务,分发给 Worker
const events = await session.stream('运行完整的测试套件并修复所有失败');
for await (const event of events) {
  if (event.type === 'external_task_pending') {
    const tasks = await session.pendingExternalTasks();
    for (const task of tasks) {
      // 发送给远程 Worker(你的传输层:gRPC、HTTP、消息队列等)
      const result = await dispatchToWorker(task);
      await session.completeExternalTask(task.task_id, result);
    }
  }
}

这个模式让你可以在不修改 Agent 逻辑的前提下,把计算密集型任务透明地分发到任意数量的远程机器。

七、为什么 A3S Code 是构建 Agentic 应用的最佳选择?

构建真正具备 Agentic 特性的应用,需要三个条件同时满足。

第一:自主执行循环。 Agent 必须能够感知、决策、行动、验证,形成闭环,不依赖人类逐步指导。这要求底层框架提供稳定的 AgentLoop 驱动机制,以及可靠的工具执行和并发控制。A3S Code 的极简核心(5 个组件)专门为此设计——Lane 队列保证执行顺序,Query 通道并行读取,Execute 通道顺序写入,Generate 通道管理 LLM 调用。

第二:完整的上下文工程能力。 Agent 在每个轮次都需要恰好足够的信息——不多也不少。这不是一个单点问题,而是需要多个机制协同:

  • ContextProvider 实现渐进式披露,按需检索,不需要预先向量化整个知识库
  • MemoryStore 保留跨会话的关键发现,避免重复探索
  • ContextCompactor 在 token 超限时自动压缩,保留语义关键信息

三者共同构成完整的上下文工程体系。没有任何一个单独的 RAG 库或记忆系统能替代这套协同机制。

第三:可嵌入、可扩展、生产可用。 Agentic 能力必须能作为基础设施嵌入你的产品,而不是锁定在某个 CLI 工具里。A3S Code 是 Rust 核心库,提供 Node.js 和 Python 原生绑定:

  • 19 个 trait 扩展点,任何部分都可以替换,核心保持稳定
  • 多租户支持,同一个 Agent 实例可以服务多个用户
  • 多机器任务分发,Execute Lane 可以透明地路由到远程 Worker
  • A3S Box 集成,代码执行天然隔离在 MicroVM 沙箱

这三个条件,A3S Code 是目前唯一同时满足的开源框架。从文章开头的 20 行代码,到多机器分布式执行系统,用的是同一套 API。


八、结论

Agentic AI 的核心是感知—决策—行动的闭环,编码任务是这个闭环的最高密度测试场。

构建可靠的 Agentic AI 系统,需要遵循两个核心原则:

极简核心——系统的不可替换部分应该尽可能小,只包含驱动 LLM 轮次所必需的组件。

工具自举——所有扩展能力通过工具实现,LLM 是最好的工具路由器,核心代码保持不变。

从文章开头的 20 行代码,到多机器分布式执行系统,A3S Code 的 API 始终如一。这就是极简核心的价值:核心稳定,能力无限扩展。


A3S Code 是开源的 Rust 编码 Agent 框架,提供 Rust、Node.js、Python SDK。查看文档 · GitHub