kimi-code 深度掌握系列文章-关键架构决策(三)

一个大型 AI Agent 项目的架构不是凭空产生的------它是对约束的回应。kimi-code 在三年多的迭代中沉淀了一系列关键架构决策,这些决策今天仍然在塑造着每一行代码。本文逐个分析五个影响最深远的架构选择:它们面临什么问题、有哪些替代方案、以及为什么最终选择了这条路。

1. DI 容器模式(借鉴 VS Code)

面临的问题

kimi-code 不是一个小脚本。它有数十个服务(配置管理、LLM 请求、工具执行、权限控制、会话状态......),这些服务之间存在复杂的依赖关系。如果每个模块都手动 import 依赖并 new 实例:

  • 替换一个服务实现需要改数十处 import
  • 测试时需要侵入式 mock 模块系统
  • 不同作用域(应用 / 会话 / 智能体)的实例无法隔离
  • 生命周期管理分散在各处,容易泄漏

核心矛盾:需要一种既支持服务组合、又支持作用域隔离、同时不引入第三方依赖的模式。

可选方案

方案 优点 缺点
直接 import 零学习成本 紧耦合,不可替换,无法隔离
Service Locator(全局单例) 简单解耦 隐式依赖,难追踪,无法作用域化
tsyringe / inversify 成熟的 DI 框架 引入第三方依赖,签名不匹配 VS Code 习惯
VS Code 风格 DI(选定) 零依赖,团队熟悉,实例隔离 需要手动实现容器逻辑

最终选择:自研 VS Code 风格 DI

项目选择了借鉴 VS Code 的 DI 容器设计。DI README 中明确写道:「Two reasons: Zero runtime dependencies --- the container is ~600 LoC of plain TypeScript; Familiar shape --- most kimi-code contributors have seen VSCode's service pattern.」

核心设计细节

createDecorator 模式

createDecorator 是 DI 容器的入口。调用它传递一个字符串名称,得到一个兼具三种身份的值:

less 复制代码
// 1. 服务标识符(ServiceIdentifier):作为 Map 的 key
// 2. 参数装饰器(Parameter Decorator):用于构造函数注入
// 3. 诊断名称:toString() 返回构造函数名

const ILogger = createDecorator<ILogger>('logger');

// 使用:作为参数装饰器声明依赖
class SomeService {
  constructor(
    @ILogger private readonly logger: ILogger,
    @IClock private readonly clock: IClock,
  ) {}
}

关键实现细节:​singleton-per-name ​------两个 createDecorator('logger') 返回完全相同的标识符引用。这确保了跨模块引用的一致性。

IInstantiationService:作用域化服务解析

IInstantiationService 是运行时的服务容器契约:

php 复制代码
interface IInstantiationService {
  readonly _serviceBrand: undefined;

  invokeFunction<R>(fn: (accessor: ServicesAccessor) => R): R;
  createInstance<T>(descriptor: SyncDescriptor0<T>): T;
  createInstance<Ctor>(ctor: Ctor, ...args: GetLeadingNonServiceArgs): InstanceType<Ctor>;
  createChild(services: ServiceCollection, store?: DisposableStore): IInstantiationService;
  dispose(): void;
}

核心行为:

  • singleton-per-container :同一个容器内多次 get 返回同一实例
  • createChild:创建子容器,子容器继承父容器的注册,但可以覆盖
  • auto-injection:通过 TypeScript 参数装饰器元数据自动解析
  • cycle detection:基于 Graph 子树遍历,在构造函数执行前发现循环依赖

延迟实例化 (Proxy)

当服务标记 supportsDelayedInstantiation: true 时,容器返回一个 Proxy,真正的构造函数在第一次非事件属性访问时才执行:

javascript 复制代码
const proxy = ix.invokeFunction((a) => a.get(IFoo));
// Foo 的构造函数尚未执行
proxy.ping();
// 构造函数在 ping() 访问时首次执行,后续调用命中缓存

延迟实例化还支持早期监听器(early-listener contract):在 Proxy 上订阅 onDidChange 事件会暂存监听器,当真实实例创建后自动重绑定。

DisposableStore:生命周期管理

与 VS Code 的 dispose 模式一致,项目实现了完整的生命周期体系:

typescript 复制代码
// 基础契约
interface IDisposable { dispose(): void; }

// 持有子 disposables 的基础类
abstract class Disposable implements IDisposable {
  protected readonly _store = new DisposableStore();
  protected _register<T extends IDisposable>(d: T): T {
    return this._store.add(d);
  }
  dispose(): void { this._store.dispose(); }
}

// 可变 disposables:动态替换
class MutableDisposable<T extends IDisposable> implements IDisposable {
  get value(): T | undefined { ... }
  set value(value: T | undefined) { ... }  // 自动 dispose 旧值
}

容器 dispose 时按 LIFO 顺序(反向构造顺序)销毁所有服务,子容器先于父容器销毁。循环依赖在构造时就被 Graph 算法拦截,dispose 时不会出现死锁。

在 agent-core 和 agent-core-v2 中的应用

V1 使用 registerSingleton 在模块加载时注册所有服务描述符,启动时通过 getSingletonServiceDescriptors() 收集并构建根容器。V2 则在此基础上引入了 registerScopedService 机制,按 LifecycleScope(App / Session / Agent)三层分级注册。

V2 中 DI x Scope 架构的演进

V2 的 Scope 类是 DI 容器和作用域的融合:

arduino 复制代码
enum LifecycleScope {
  App = 0,      // 应用级:配置、遥测、持久化引擎
  Session = 1,  // 会话级:LLM Provider、会话上下文
  Agent = 2,    // 智能体级:循环、工具注册表、提示词
}

// Scope 树:
//   App Scope
//     ├── Session Scope (session-1)
//     │   ├── Agent Scope (agent-1)
//     │   └── Agent Scope (agent-2)
//     └── Session Scope (session-2)

关键特性:

  • 子 Scope 只能向更深层级创建kind <= this.kind 时抛出异常,防止架构退化为扁平化
  • Dispose 级联:父 Scope dispose 自动销毁所有子 Scope
  • 服务注册按 Scope 隔离Agent 级服务只对当前智能体可见

这个设计使 kimi-code 从单体 Agent 演进为可以同时运行多个隔离会话、每个会话又能运行多个子智能体的多租户系统------而容器隔离是这一切的基石。

2. LLM Provider 抽象设计(kosong)

面临的问题

kimi-code 需要支持多种 LLM 后端:Kimi 自家的 API、OpenAI(Chat Completions 和 Responses 两种风格)、Anthropic(Messages API)、Google GenAI 等。直接调用各 SDK 会导致:

  • 每个提供商的 API 语义差异(工具调用格式、流式事件、错误码)泄漏到业务层
  • 更换模型需要修改业务代码
  • 无法统一处理重试、取消、流水线

核心设计:统一的 ChatProvider 接口

php 复制代码
interface ChatProvider {
  readonly name: string;                     // 后端标识,如 "kimi", "anthropic"
  readonly modelName: string;                // 上游 API 使用的模型名
  readonly thinkingEffort: ThinkingEffort | null;
  readonly maxCompletionTokens?: number;

  generate(
    systemPrompt: string,
    tools: Tool[],
    history: Message[],
    options?: GenerateOptions,
  ): Promise<StreamedMessage>;

  withThinking(effort: ThinkingEffort): ChatProvider;
  withMaxCompletionTokens?(max: number, opts?: MaxCompletionTokensOptions): ChatProvider;
}

不可变配置模式

withThinking()withMaxCompletionTokens() 不修改当前实例,而是返回一个​浅拷贝​ 新实例。这个设计的意图是:

  • 请求安全:创建 provider 实例的基配置是一个稳定的 baseline,每次调用衍生一个临时配置,不会污染下一条请求
  • 共享传输层:拷贝实例共享 HTTP client(实现中明确禁止替换或变更),避免重复建立连接
  • immutable-like:在异步并发的场景下避免了状态竞争

generate() 函数的编排逻辑

generate() 不是一个简单的方法调用,而是一个精细的编排器:

  1. Pre-flight abort 检查:在发出请求前验证 signal 是否已中止
  2. Deferred tools 剥离 :标记为延迟的工具不在请求的 tools[] 中发送,只通过消息级 tools 声明传递------保持 prompt caching 稳定性
  3. 流式合并 :consecutive compatible parts 使用 mergeInPlace 合并在内存中,避免内存膨胀
  4. 并行工具调用索引路由 :通过 _streamIndex + toolCallIndexMap 正确路由交错到达的工具调用参数片段
  5. 解码阶段记账 :精确分开 serverDecodeMs(等待下一个 part 的时间)和 clientConsumeMs(处理每个 part 的时间),让性能诊断有据可循
  6. Tail abort 检查:流结束时再次检查中止信号

多供应商适配矩阵

providers 目录下每个文件对应一个后端:

文件 后端 适配要点
kimi.ts Kimi / KFC 原生 Kimi 协议,x-trace-id 链路追踪
openai-legacy.ts OpenAI Chat Completions SSE 流式解析,tool_choice 映射
openai-responses.ts OpenAI Responses API 新协议,tool_calls finish reason 变为 completed
anthropic.ts Anthropic Messages required max_tokens,pause_turn 语义
google-genai.ts Google GenAI REST 直接调用,tool_calls finish reason 变为 completed

每个适配器负责将统一的 Message / Tool 类型转换为上游 API 的 wire format,再将流式响应映射回统一的 StreamedMessagePart

FinishReason 归一化

不同提供商的停止原因被归一化为统一的枚举:

go 复制代码
type FinishReason =
  | 'completed'     // 正常完成
  | 'tool_calls'    // 暂停等待工具调派(Chat Completions / Anthropic 专有)
  | 'truncated'     // token 预算耗尽
  | 'filtered'      // 内容过滤器拦截
  | 'paused'        // Anthropic pause_turn
  | 'other';        // 其他已知但未归类的信号

ModelCapability 声明矩阵

每个模型的能力通过 ModelCapability 字典预先声明:

typescript 复制代码
interface ModelCapability {
  readonly image_in: boolean;
  readonly video_in: boolean;
  readonly audio_in: boolean;
  readonly thinking: boolean;
  readonly tool_use: boolean;
  readonly max_context_tokens: number;
  readonly max_input_tokens?: number;
  readonly dynamically_loaded_tools?: boolean;
}

业务代码在构建请求前通过 getModelCapability(provider, model) 查询能力矩阵,对不支持图像或音频的模型提前拦截,而不是把请求发出去再等上游报错。未知模型返回冻结的 UNKNOWN_CAPABILITY 哨兵值(全 falsemax_context_tokens: 0)。

错误分类体系

错误不是简单的 Error------它们有恢复策略的含义:

arduino 复制代码
ChatProviderError               // 基础类型
  ├── APIConnectionError         // 网络故障 → 可重试(退避后)
  ├── APITimeoutError            // 超时 → 可重试
  ├── APIStatusError             // HTTP 错误
  │   ├── APIContextOverflowError    // 413 → 需要 compact 后重试
  │   ├── APIRequestTooLargeError    // 413 → 不可重试(需要缩小媒体)
  │   └── APIProviderRateLimitError  // 429 → 等待 Retry-After 后重试
  └── APIEmptyResponseError      // 空响应 → 不可重试

每个错误都携带 retryAfterMs(从 HTTP Retry-After 头解析)和 traceId(从 Kimi/KFC 的 x-trace-id 头解析),重试循环可以基于错误类型和退避时间做出智能决策。

kosong 让 kimi-code 的 Agent 逻辑与具体 LLM 提供商完全解耦。无论是内部 Kimi 模型还是第三方 API,Agent 看到的都是同一个 ChatProvider.generate() 契约。

3. Transcript 四层数据模型

面临的问题

智能体的对话过程不是简单的「用户问了什么、AI 回了什么」。一个真实的 Agent 对话包含:

  • 多轮 turn(每轮有多个 step,每个 step 包含多个 frame)
  • 工具调用的增量文本流(逐字到达的 bash 输出)
  • 后台任务、审批交互、计划状态、todo 列表
  • 多个订阅者需要不同粒度的更新(UI 需要「逐字增量」,日志需要「完整 turn」)

如果用一个 JSON 对象序列化整个对话状态,每次更新都需要全量传输和渲染,性能无法接受。

四层架构

┌─────────────────────────────────────────────────────┐ │ L4 Views --- 渲染器注册表(框架无关) │ │ ViewRegistry: toolRenderers, inputRenderers, │ │ markerRenderers --- key → component lookup │ ├─────────────────────────────────────────────────────┤ │ L3 Subscriptions --- 粒度过滤器 │ │ off / turn / block / delta --- 按需订阅 │ ├─────────────────────────────────────────────────────┤ │ L2 Ops --- 传输词汇 (idempotent upsert + append) │ │ turn.upsert / step.upsert / frame.upsert / │ │ append / marker.upsert / interaction.upsert / ... │ ├────────────────────────────────────────────────────┤ │ L1 Store --- 内存状态容器(AgentTranscript) │ │ items\[\] + tasks/meta/todos/prompts 映射表 │ └─────────────────────────────────────────────────────┘

L1 Store:AgentTranscript

AgentTranscript 是单智能体粒度的内存状态容器,持有:

  • items[]:有序的时间线条目(turn / marker / taskRef)
  • tasks:TaskId → TranscriptTask 映射
  • interactions:InteractionId → TranscriptInteraction 映射
  • attachments / todos / prompts / meta:其他实体集合

状态是​复制即写(copy-on-write)​ 的:每次 apply() 产生新的 state 引用,已返回的 snapshot 不被后续操作污染。

L2 Ops:幂等操作词汇

这是传输层的词汇表。关键设计原则:

  • **唯一非幂等操作是 append**(必须携带 offset 累积位置)
  • 所有 upsert 都是幂等的:重复接收不会产生副作用
  • 按 producer 因果顺序执行:单代理的序列化通道保证收敛
bash 复制代码
type TranscriptOperation =
  | ResetOp           // op: 'reset'        --- 全量快照(首次加载或 gap 修复)
  | TurnUpsertOp      // op: 'turn.upsert'  --- turn 头信息
  | StepUpsertOp      // op: 'step.upsert'  --- step 头信息
  | FrameUpsertOp     // op: 'frame.upsert' --- 框架(工具调用/结果)
  | AppendOp          // op: 'append'       --- 增量文本块(唯一的 non-idempotent)
  | MarkerUpsertOp    // op: 'marker.upsert'
  | TaskUpsertOp      // op: 'task.upsert'
  | InteractionUpsertOp
  | AttachmentUpsertOp
  | TodoUpsertOp
  | PromptUpsertOp
  | TaskRefUpsertOp;

wire.jsonl 作为单一真相源

所有 L2 ops 以 append-only JSONL 格式写入磁盘。这是可审计、可重放、可跨会话恢复的持久化层。

L3 Subscriptions:按粒度过滤

订阅者可以选择关注的粒度级别:

  • off:不订阅
  • turn:仅在 turn 级别变化时通知
  • block:文本块级别
  • delta:逐字增量(用于 UI 流式渲染)

L4 Views:框架无关的渲染器注册表

ViewRegistry<C> 是一个 key-based 的渲染器查找器,完全不依赖任何 UI 框架。C 是泛型参数,可以是 Vue 组件、React 组件或 Ink 渲染器:

php 复制代码
class ViewRegistry<C> {
  registerTool(key: string, renderer: C): this;
  registerInput(originKind: string, renderer: C): this;
  registerMarker(marker: string, renderer: C): this;

  resolveTool(frame: ToolCallFrame): C | undefined;    // frame.view ?? frame.name
  resolveInput(origin: TurnOrigin): C | undefined;      // origin.kind
  resolveMarker(marker: string): C | undefined;         // marker key
}

操作批处理序列合约

ops 信道需要保证单调递增的 seq 值。消费者通过 since_seq 发起 catch-up 请求获取错过的 ops。这是服务端推送和客户端拉取的边界------服务端负责维护 seq 递增,客户端负责检测 gap 并发起重置。

历史重建:groupTurns + foldFacts

从 L2 ops 重建可读的对话历史需要两个步骤:

  • groupTurns:将 flat ops 序列重组为 turn → step → frame 的层级结构
  • foldFacts:将分散的工具调用和工具结果折叠为可渲染的对话块

Transcript 的四层模型使 kimi-code 能够在服务端以 ops 粒度推送更新、在客户端按需重建视图------既不丢失流式渲染的实时性,又保持了数据的完整性和可审计性。

4. 执行环境抽象(kaos)

面临的问题

kimi-code Agent 需要在多种环境中运行:本地开发机、SSH 远程服务器、容器(通过 ACP 协议连接)。每个环境有不同的文件系统语义、进程管理方式和路径规范。如果 Agent 代码直接调用 fs.readFileSyncchild_process.exec

  • 不可切换:本地写死的调用无法重定向到远程环境
  • 不可测试:单元测试需要真实的文件系统
  • 不可组合:无法在同一进程中同时操作多个环境

核心设计:Kaos 接口

Kaos(Kimi Agent Operating System)是一套统一的文件系统和进程操作抽象:

scss 复制代码
interface Kaos {
  readonly name: string;       // 环境标识:"local", "ssh:host"
  readonly osEnv: Environment; // OS/Shell 探测结果

  // 路径操作
  pathClass(): 'posix' | 'win32';
  normpath(path: string): string;
  gethome(): string;
  getcwd(): string;

  // 文件操作
  readBytes(path: string, n?: number): Promise<Buffer>;
  readText(path: string, opts?: { encoding?, errors? }): Promise<string>;
  writeBytes(path: string, data: Buffer): Promise<number>;
  writeText(path: string, data: string, opts?): Promise<number>;

  // 目录操作
  stat(path: string, opts?): Promise<StatResult>;
  iterdir(path: string): AsyncGenerator<string>;
  mkdir(path: string, opts?): Promise<void>

  // 进程执行
  exec(...args: string[]): Promise<KaosProcess>;
  execWithEnv(args: string[], env?: Record<string, string>): Promise<KaosProcess>;

  // 不可变派生
  withCwd(cwd: string): Kaos;
  withEnv(env: Record<string, string>): Kaos;
}

三种实现

实现 环境 底层机制
LocalKaos 本地开发机 Node.js fs + child_process
SSHKaos SSH 远程服务器 SSH2 客户端 + SFTP 协议
ACPKaos (acp-adapter) ACP 客户端环境 Agent Client Protocol(通过 kaos-acp.ts)

AsyncLocalStorage 上下文传递

这是实现「同一份 Agent 代码在不同环境可运行」的关键:

javascript 复制代码
// 底层:AsyncLocalStorage 绑定当前 kaos 实例
const kaosStorage = new AsyncLocalStorage<Kaos>();

export function getCurrentKaos(): Kaos {
  const store = kaosStorage.getStore();
  if (store === undefined) throw new KaosError('No Kaos is bound...');
  return store;
}

export function runWithKaos<T>(kaos: Kaos, fn: () => T): T {
  return kaosStorage.run(kaos, fn);
}

// 上层:模块级的便捷函数(自动从当前上下文获取 kaos)
export function readText(path: string, opts?): Promise<string> {
  return getCurrentKaos().readText(path, opts);
}

export function exec(...args: string[]): Promise<KaosProcess> {
  return getCurrentKaos().exec(...args);
}

Agent 代码调用 import { readText, exec } from '@moonshot-ai/kaos' ------完全不需要知道当前是在本地还是远程。环境切换通过外层 runWithKaos(localKaos, () => agent.run())runWithKaos(sshKaos, () => agent.run()) 完成。同一进程可以有多个并发上下文,每个使用不同的 Kaos 实例,互相隔离。

不可变派生模式

类似 kosong provider,withCwd()withEnv() 返回新实例。这让工具的沙箱化变得简单:给某个工具调用创建一个 /tmp/workspace 子目录的 kaos 视图,它只在这个请求的上下文中有效。

Kaos 抽象让 kimi-code 的 Agent 代码实现了「编写一次,处处运行」------本地开发、SSH 远程、ACP 客户端三种环境共用同一套 Agent 逻辑,只在初始化时注入不同的 Kaos 实例。

5. V1 → V2 架构演进

V1 的问题

agent-core V1 的根基是一个巨大的 Agent 类------它是所有逻辑的中心,集成了配置、LLM 调用、工具执行、权重管理、会话状态、对话循环、context 构建等数十种职责。

这导致了几个根本性问题:

  • 紧耦合 :Agent 直接 import 所有依赖模块的实例,替换任何一个实现都需要侵入 Agent 内部
  • 难以测试:单元测试需要构造完整的 Agent 实例,Mock 依赖需要 mock 模块导入
  • 难以多租户:同时运行两个 Agent 实例时,全局单例会互相干扰
  • 用户代码侵入:面向用户的 CLI 代码和核心 Agent 逻辑混杂在同一个类中

V2 的目标

V2 重新设计了整个架构,核心原则是:

  1. DI x Scope:所有服务通过 DI 容器接入,按生命周期 Scope 隔离
  2. 服务化:每个职责成为一个独立服务,通过接口契约定义边界
  3. 可测试:通过容器 stub 可以在单元测试中注入 mock 依赖
  4. 多租户隔离:Session 和 Agent 级别的 Scope 天然隔离不同实例的状态

V2 的域划分

V2 按业务域组织代码,每个域有清晰的职责边界:

路径 职责 示例服务
_base _base/ 基础设施(DI 容器、日志) InstantiationService, LogService
agent agent/ 智能体核心行为 LoopService, ToolExecutor, ContextMemory
app app/ 应用层(配置、遥测、插件、auth) ConfigService, PluginService, TelemetryService
session session/ 会话管理(生命周期、状态) AgentLifecycleService, SessionMcpService
kosong kosong/ LLM 供应商抽象 ProviderService, ModelService, Generate
os os/ 操作系统接口 HostEnvironmentService, HostFsService
persistence persistence/ 持久化层 FileStorageService, AppendLogStore
tool tool/ 工具注册和执行 ToolRegistryService, ToolContributions
wire wire/ 记录和回放 WireService, WireMigration

kap-server:V2 引擎的对外接口

kap-server 是 V2 架构的 HTTP/WebSocket 网关。它启动 V2 Scope 树,将外部请求映射到 V2 服务调用:

  • REST API → SessionLifecycleService(创建/恢复会话)
  • WebSocket → SessionScope(维持会话级别的状态和订阅)
  • ACP Bridge → 通过 kaos ACP 适配器在远程环境执行

klient:传输无关的类型化切面

klient 提供客户端侧的类型安全 API。它抽象了底层传输层(HTTP / WebSocket),只暴露领域概念:Session, Message, AgentRun 等。上层 UI(如 kimi-web、vscode 插件、终端 TUI)全部依赖 klient 而不是直接打 HTTP 请求。

演进策略:双引擎共存

V1 和 V2 不是一夜之间切换的。项目通过以下策略平滑过渡:

  • 双引擎共存:V1 和 V2 的 Agent 在同一个进程中并行运行,通过路由层分流
  • 逐步迁移:工具注册、权限管理、会话管理等功能逐个迁移到 V2 域
  • 兼容层migration-legacy 包提供 V1 ↔ V2 的数据格式转换
  • Session Legacy Service:V2 可以读取和恢复 V1 创建的历史会话

V1 → V2 不仅是代码重构,更是一次架构哲学上的演变:从「一个大类包办一切」变为「通过 DI 容器组合服务,通过 Scope 隔离实例,通过接口契约定义边界」。这个转变让 kimi-code 从单一 CLI 工具成长为可以支撑 Web、VSCode 插件、SSH 远程等多形态产品的平台级引擎。

总结

这五个架构决策不是孤立存在的------它们形成了一个相互支撑的网络:

┌──────────────┐ 注入 ┌──────────────┐ │ DI 容器 │ ◄───────── │ Kaos 抽象 │ │ + Scope 树 │ │ (执行环境) │ └──────┬───────┘ └──────────────┘ │ │ 管理生命周期 提供执行能力 │ │ ┌──────────┴──────────┐ ┌─────────┴──────────┐ │ │ │ │ ▼ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ LLM Provider │ │ Agent V2 │ │ Transcript │ │ (kosong) │ │ 引擎 │ │ 四层模型 │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ 统一 LLM 服务化编排 状态快照 供应商接口 多租户隔离 增量同步

  • DI 容器提供了服务组合和生命周期管理的骨架
  • kosong 让 Agent 逻辑与具体 LLM 提供商解耦
  • Transcript解决了对话状态的流式同步和历史重建问题
  • Kaos 让同一份 Agent 代码在不同执行环境中无缝运行
  • V2 架构将所有组件整合为一个可测试、可扩展、可多租户的平台

理解这些架构决策,就理解了 kimi-code 如何从一个实验性的 AI CLI 工具,演化为支撑 Kimi 全线产品的 Agent 引擎平台。下一篇将深入 Agent 类的内部------这个引擎的编排者如何协调所有服务完成一轮对话。

相关推荐
Loveyourself1 小时前
你知道吗?详细揭秘cc中api层微压缩-microcompact
面试·agent
云原生melo荣2 小时前
Multi-Agent 系统(一):问题域与架构选型——为什么这次"固定流程"编排不动
agent·ai编程
码农胖大海2 小时前
AI 响应慢自查清单
agent·ai编程
苏灿烤鱼3 小时前
GitHub Trending 日报|Agent 记忆登顶,老牌项目集体返场
安全·agent·资讯
苏灿烤鱼3 小时前
GitHub Trending 榜首|腾讯 Agent 记忆库技术拆解:分层记忆 vs 向量堆,让 AI 不再反复问
typescript·开源·agent
孙启超3 小时前
【AI应用开发】ReAct 原理是什么?和普通直接提问 LLM 差别在哪?
前端·人工智能·llm·agent·react·rag·ai应用开发
小七-七牛开发者5 小时前
“打透” Harness:用 GitHub Copilot 跑通从原型、规划到实现与评审的 AI Coding 工作流
ai·大模型·agent·token·工作流·claudecode·ai coding
Vuji5 小时前
ReAct 与 Plan-Execute:两种 Agent 范式的实战对比
前端·agent
玉鸯5 小时前
多 Agent 并行时如何保证状态一致性?
分布式·python·agent