内核内部
⚫ 本文档面向编写或修改内核代码本身的人。完整规范见 SPEC.md(英文,事实来源);这里是一张简略地图。语义来自 agent_os_core 源码。
14.1 模型
内核是一个单一的 async 运行时(Tokio),带有事件循环,它:
- 维护进程表(
DashMap<Pid, AgentProcess>); - 每个 tick 调用调度器(
schedule() → ScheduleDecision); - 分发回合(
run_turn(pid)),调用提供者并执行 tool-call 循环; - 在分发前限制资源(预算、组、并发上限);
- 路由 IPC;
- 中介每一次 tool 调用;
- 向监听者发出事件;
- 管理会话(
SessionRegistry)。
内核持有可选的服务句柄,由宿主在加载时一次性接入(message_store、state_store、provider、pricing 等)——如果句柄未接入,相应的 syscall 会回应“未配置”。
模块化。 功能(cron、workflow、connectors、memory、model_router、通道等)已从内核中移出到模块,并作为 host 端口接入。
Kernel不再有类型化字段cron_service/workflow_service/connector_service,而是有一个中性的接缝kernel::KernelServices,由宿主从端口agent_os.Cron/agent_os.Workflow/agent_os.Connectors填充(kernel.services().set_*)。内核不依赖任何功能;详情见docs/27-core-modularization.md§5 和 32-building-a-module。
加载循环:
loop {
decision = schedule()
match decision {
Run(pid) → run_turn(pid)
Idle → sleep(50ms)
AtConcurrencyLimit → sleep(50ms)
Shutdown → break
}
}
14.2 基本抽象
| 操作系统概念 | 等价物 | 模块 |
|---|---|---|
| 进程 | AgentProcess — PID、状态机、上下文、工具、预算 |
process.rs |
| 内核 | Kernel — 事件循环 |
kernel.rs |
| CPU | InferenceProvider — 可插拔 LLM |
provider.rs |
| RAM | ContextWindow — 带驱逐的内存 |
context.rs |
| I/O 设备 | Tool |
tool.rs |
| cgroups/ulimits | TokenBudget / BudgetGroup |
budget.rs |
| 系统调用 | Syscall |
syscall.rs |
| 信号 | Signal |
ipc.rs |
| fork() | fork() — COW 上下文,组继承 |
process.rs |
| 进程表 | DashMap<Pid, AgentProcess> |
kernel.rs |
| 驱动 | ToolHandler |
tool.rs |
进程状态机
spawn → Created → (init) → Ready ⇄ Running → (exit) → Terminated
│
└→ Blocked{reason} → (unblock) → Ready
- Created — 已分配,未初始化。
- Ready — 等待调度器(
is_runnable())。 - Running — 消耗推理。
- Blocked { reason } — 等待外部事件(tool 结果、IPC、输入)。
- Terminated { exit_code } — 已完成(0)或被杀死(≠0)。
回合与 tool-call 循环
- 内核选择进程 P。
- 将 P 的上下文 + 最近的 tool 结果发送给提供者。
- 提供者流式输出 token。
- 如果 LLM 请求 tool-call,内核暂停流,校验调用,执行处理程序(带截止时间),将结果作为
tool消息添加,并恢复推理。 - 当 agent yield、阻塞、时间片耗尽或预算用尽时,回合结束。
并发仅在 provider.stream 周围以 Semaphore 计量——tool 调用和钩子无需许可即可进行,因此慢工具不会让其他会话“饥饿”。
上下文窗口
ContextWindow { max_tokens, messages, eviction, summary }。驱逐策略:
Fifo(丢弃旧的)、SummaryFirst { keep }(将旧的折叠为摘要,默认 keep=8)、SlidingWindow { n }。驱逐还会清理那些父 assistant 消息已被删除的孤立 tool 结果。
预算
TokenBudget { max_per_turn, bucket: TokenBucket, max_total, … }。
TokenBucket — 经典漏桶(capacity + refill_rate)。组 BudgetGroup 增加两个可选层:per-user(user_id 上的子桶)和 per-session。分发前检查:组 → per-user → per-session(can_consume_for);耗尽的层 — BudgetLevel::{Group,User,Session}。
IPC 与 syscall
MessagePayload:Text、Json、Signal(Terminate/Pause/Resume/Interrupt)、SpawnRequest、SpawnResult。
Syscall:Spawn、Fork、Kill、Yield、Send/Recv、ToolCall、SetState/GetState/DeleteState、Checkpoint/Restore。
钩子
HookHandler 带以下点位:before_user_message(transform/inject/suppress/reply/notice)、before_tool_call(rewrite args / deny / short-circuit)、after_tool_result(redact/transform)、before_inference(请求变更;deny → 阻止,response → 合成响应)、before_retry(允许/禁止重试 + backoff)、before_syscall(syscall/IPC 过滤,deny)、after_turn、after_assistant_message(output-guardrail)、on_token(流式审核)、before_context_evict(自定义压缩)、after_loop、on_spawn/on_terminate/on_error、on_session_created/on_session_closed、on_budget_threshold。另有 merge_user(身份合并)、memory_inspect(检查)、apply_feedback(like/dislike)。
组合:Hook.priority(越高越早)、enabled、激活条件 when { templates, agents, users, sessions }、global(目录 config/hooks/*.yaml)。每次调用都经过 Kernel::run_hook(catch_unwind + 超时 hook_secs),并在 (hook, point) 对的 HookMetric 中计入(GET /v1/hooks/metrics)。HookOutcome { inject, replace_message, reply, notice, suppress }。
14.3 调度器
SchedulingPolicy:RoundRobin(默认)、PriorityPreemptive、FairShare、DeadlineDriven。Scheduler { policy, time_slice, max_concurrent }。
ScheduleDecision:Run(pid) | Idle | AtConcurrencyLimit | Shutdown。
14.4 推理提供者
trait InferenceProvider {
fn provider_type(&self) -> &str;
async fn stream(&self, request) -> Result<Box<dyn Stream<Item=Result<InferenceEvent, InferenceError>>>>;
}
enum InferenceEvent { Token(String), ToolCall(ToolCallRequest), Done(InferenceStats) }
具体实现 — OpenAiProvider(reqwest + SSE)。Pricing 根据统计估算成本。
14.5 存储子系统
| 层 | 位置 | 事实来源用于 |
|---|---|---|
| 文本日志(tracing) | stdout → agent_os.log |
运维查看 |
Event store(EventDb) |
logs/events.db |
审计(每个事件一行) |
| Message store | logs/messages.db |
转录 + FAQ 缓存,全文搜索 |
| JSONL 追踪 | logs/process-{pid}.jsonl |
进程事件的原始流 |
| State store | logs/state.db |
作用域键值(session/user/agent/team) |
| Checkpoints | CheckpointStore |
恢复/迁移 |
14.6 事件与监听者
内核通过总线发出类型化的 ProcessEvent:TurnStart、Token、ToolCall、ToolResult、ToolProgress、TurnEnd、StateChange、Error、Spawned、Terminated、BudgetConsumed、BudgetExhausted、RateLimited、ScheduleBlocked、会话生命周期事件、Cost、工作流步骤。监听者实现 ProcessListener(所有方法默认 no-op)。
14.7 加载
- 宿主加载配置并构建
Kernel。 ToolRegistry注册内置工具和用户工具;HookRegistry— 钩子。InferenceProvider连接到 LLM。- 连接服务句柄(
message_store、state_store、cron_service、workflow_service、pricing)。 - 加载代理模板(内置 + YAML)。
- 生成 Bootstrap 代理(或在会话首次请求时惰性生成)。
- 调度器循环启动。
- 宿主监听外部请求(HTTP + SSE)。
14.8 设计决策
- 默认采用协作式多任务;抢占为可选项。
spawn和fork— 两者均受支持;fork始终继承预算组。- 工具级成本核算 — 每个
ToolResult携带ToolCost。 - I/O 经由内核 — 代理从不直接调用工具。
- 子系统为选择性加入 — 未连接时返回“未配置”,而非崩溃。
14.9 非目标
多租户(一个实例 = 一个租户)、分布式调度器、 微调、内核中的图工作流(这属于服务端层)、实时保证。
14.10 源码地图
| 关注点 | 模块 |
|---|---|
| 内核、回合循环 | crates/kernel/src/kernel.rs |
| 进程、spec、fork | crates/kernel/src/process.rs |
| 状态机 | crates/kernel/src/state.rs |
| 上下文、抢占 | crates/kernel/src/context.rs |
| 预算、组、成本 | crates/kernel/src/budget.rs |
| 调度器 | crates/kernel/src/scheduler.rs |
| 提供者(trait) | crates/kernel/src/provider.rs |
| OpenAI 提供者 | crates/kernel/src/openai_provider.rs |
| 工具 | crates/kernel/src/tool.rs |
| 钩子 | crates/kernel/src/hook.rs、hooks/ |
| IPC、信号 | crates/kernel/src/ipc.rs |
| Syscall | crates/kernel/src/syscall.rs |
| State store | crates/kernel/src/state_store.rs |
| Message store | crates/kernel/src/message_store.rs |
| 事件、监听器 | crates/kernel/src/event.rs、listener.rs |
| Event DB | crates/kernel/src/event_db.rs |
| 检查点 | crates/kernel/src/checkpoint.rs |
| JSONL 日志记录器 | crates/kernel/src/jsonl_logger.rs |
| 子代理 | crates/kernel/src/subagent.rs |
| Cron | crates/kernel/src/cron.rs |
| 工作流 | crates/kernel/src/workflow.rs |
| 定价 | crates/kernel/src/pricing.rs |
指标(Prometheus /metrics) |
crates/kernel/src/metrics.rs |
| 副作用幂等性 | crates/kernel/src/side_effect.rs |
| Durable 会话(选择性加入持久化) | crates/kernel/src/durable.rs |
| Durable pending(approvals/输入/await_event) | crates/kernel/src/pending.rs |
| 配置加载器 | crates/kernel/src/config.rs |
| 脚本运行时 | crates/kernel/src/script_engine/、js_runtime/ |
14.11 构建与测试
由三个 crate 组成的 Cargo 工作区:
| Crate | 用途 |
|---|---|
agent_os_core |
内核:进程、调度器、预算、事件、提供者抽象、钩子、message store。不含 HTTP 和具体提供者 |
agent_os_tools |
工具实现(抓取器、归档、RSS、PDF、JSON、脚本)及内置工具 |
agent_web_bot |
HTTP 服务器(axum)、OpenAI 提供者、组件、管理 UI、代理、Telegram 机器人、配置加载器。二进制文件 — 统一 CLI agent-os |
cargo build # debug-сборка всех бинарников
cargo run --bin agent-os -- serve # запуск сервера (грузит config/server.yaml)
cargo test -p agent_os_core # юнит-тесты ядра/инструментов/хуков
cargo test -p agent_web_bot # тесты сервера, auth, proxy, login, sessions
cargo test -p agent_web_bot --lib # HTTP-слой (роутинг, auth, login, access-лог)
widget/ 中的组件在 agent_web_bot 处通过
npm 自动构建 build.rs — 无需单独的 npm run build。集成测试
crates/host/tests/ 需要有效的 LLM 密钥,默认不运行。