Sema Code: Decoupling AI Coding Agents into Programmable, Embeddable Infrastructure
Paper: arXiv:2604.11045 Code: midea-ai/sema-code-core Code reference:
main@69f7dcc6(2026-05-26)
1. Motivation (研究动机)
现有 AI coding agent 已经能完成代码搜索、编辑、测试、工具调用和多步推理,但大多以一个具体产品形态交付:CLI、IDE 插件、Web app 或托管聊天界面。论文认为这带来一个系统性瓶颈:能力被锁在产品壳里,企业或第三方系统很难把同一套 agent reasoning kernel 嵌入到自己的 IDE、消息机器人、CI/CD、内部平台或跨语言服务中,也很难替换底层模型、统一权限策略、复用上下文管理和工具生态。

Figure 1 解读:左侧代表传统 monolithic AI 系统,核心推理、UI、工具权限和运行时状态都绑定在同一个产品内;右侧代表 Sema Code 的目标,把“AI coding 能力”拆成可被任意客户端驱动的透明引擎。这个图不是在比较某个模型指标,而是在说明论文的主要问题定义:AI coding agent 应该像 SQLite 或 Chromium 一样成为可嵌入基础设施,而不是只能被用户手动打开的应用。
具体来说,论文要解决的是 agent engine 的产品形态解耦:同一个核心引擎既要能在 VSCode Extension Host 里运行,也要能作为服务器端 Node.js 进程支撑 Telegram、Feishu 等多渠道 agent 平台;客户端只负责渲染、通道转发和交互 UI,核心 agent loop、工具调度、权限控制、上下文压缩和多 agent 运行时都由 Sema Core 提供。
这个问题值得研究的原因是,一旦 AI coding agent 被设计成“可编程引擎”,上层系统就能像接数据库一样接入它:后端服务可以直接 import npm package,非 TypeScript 系统可以通过 WebSocket / gRPC 桥接,企业可以在同一套权限和审计策略下服务 IDE、Web、机器人和自动化工作流。论文的关注点因此不是提出新的 SWE-bench solver,而是把复杂 agent 产品中隐藏的基础设施能力抽象成可复用 runtime。
2. Idea (核心思想)
核心 insight 很直接:把 AI coding agent 从“端到端应用”改造成“可嵌入、可插拔、framework-first 的核心引擎”。Sema Code 将核心推理、工具调用、状态管理、权限和生态接入封装成无 UI 的 sema-core npm package;所有客户端只通过事件流和公开 API 与引擎通信。
关键创新不在单个算法,而在一组工程机制的组合:三层分离架构、多租户隔离、FIFO 输入队列与会话重建、自适应上下文压缩、多 agent 协作调度、ID-matched Todo 状态机、异步后台任务、四层权限决策,以及 MCP / Skills / Plugins 三层生态。它们共同回答一个问题:当 agent 不再只服务一个本地 CLI 用户,而要成为多客户端共享基础设施时,状态、上下文、权限和长任务如何仍然可控。
与 Claude Code、Cursor、GitHub Copilot 这类强产品化 agent 相比,Sema Code 的差异是交付边界:前者把能力封装在特定 CLI/IDE/Web 体验中,第三方只能“使用产品”;Sema Code 则暴露 engine API,第三方可以“嵌入能力”。与 AutoGen / LangChain 这类通用 LLM orchestration 框架相比,Sema Code 更贴近 coding agent runtime:它内置代码编辑、shell、权限、Todo、background task、context lifecycle,而不是只提供抽象 conversation graph。
3. Method (方法)
3.1 Overall framework: 三层分离架构

Figure 2 解读:Sema Code 被拆为 Client Layer、Core Engine Layer 和 Service Layer。Client Layer 可以是 VSCode extension、CLI、Web、Telegram/Feishu bot 或 gRPC client;Core Engine Layer 是 UI-free 的 sema-core,负责 agent loop、tool orchestration、session state、permission、memory/context;Service Layer 则对接模型 API、MCP server、Skills、Plugins、filesystem、shell、history 等外部能力。图中的关键点是所有客户端都只通过 event-driven public APIs 驱动同一核心引擎,客户端差异不应渗入 agent reasoning kernel。
直觉上,Sema Code 的架构把“agent 能力”和“产品体验”放在不同变化速率的层里:上层 UI/通道经常变化,底层模型和工具生态也会替换,但中间的 agent runtime 应稳定、可测、可嵌入。如果不这样拆分,任何新增客户端都要复制一套上下文压缩、权限、工具调度和任务管理逻辑;如果拆分成功,同一 engine binary 就能服务多个产品形态。
3.1.1 Client Layer
Client Layer 不执行核心 reasoning,而是订阅事件流并把事件渲染为本地 UI:例如 VSCode 中的 diff preview、Todo board、background task panel、permission dialog;在消息机器人中则对应 inline button、消息线程和 Web 管理后台。论文强调客户端通过事件而非内部状态访问引擎,这让前端可以换形态而不改变 engine。
3.1.2 Core Engine Layer
Core Engine Layer 包含 Sema Core:agent loop、工具调用、状态管理、权限检查、context lifecycle、multi-agent runtime、Todo 和 background task。released code 中 src/core/SemaCore.ts 暴露进程级 API(session、models、marketplace、MCP、skills、plugins、cron 等),src/core/SemaSession.ts 暴露单会话交互 API,src/core/SemaEngine.ts 处理输入队列、消息构建和 query lifecycle。
3.1.3 Service Layer
Service Layer 对接模型、MCP、Skills、Plugins、shell、filesystem、history 和 marketplace。它让 Core Engine 不绑定某个 provider 或某个工具源:Anthropic 和 OpenAI-compatible adapters 被统一成 streaming protocol;MCP 是外部服务工具层,Skills 是行为/提示策略层,Plugins 是命令与 hook workflow 层。
3.2 Core engine mechanisms
3.2.1 Multi-tenant isolation
论文设定多租户场景:一个 Sema Core 进程可能同时服务 VSCode 单用户会话和 50-person team 的消息机器人。若所有 agent 实例共享全局 singleton state,则任意实例 写入共享状态 后可能被另一个实例 读到,导致 conversation history 泄露、权限信号串扰或 abort collision。
论文方案是给每个 engine instance 绑定独立 resource bundle:event bus、state manager、tool orchestrator、tenant config。论文称使用 Node.js AsyncLocalStorage 跨 async boundary 传播这些资源引用,从而避免每个函数都显式传参。
论文公式与 released code 实现差异:论文在 §3.2.1 明确写到 AsyncLocalStorage (ALS),但 main@69f7dcc6 的 src/ 下没有 AsyncLocalStorage 字符串;released code 当前以 SemaCore + SessionPool + StateManager.session(sessionId) 管理会话,SemaCore.createSession() 委托 getSessionPool().createSession(opts),而非直接可见的 ALS resource bundle。笔记中的伪代码因此按论文机制解释 ALS,代码映射则按当前 repo 的实际文件锚定。
3.2.2 Hierarchical state partitioning
单个 session 内又可能有 main agent 和多个 sub-agent。论文把 session state 分成 agent-local 与 session-global 两层:
对任意 agent ,本地状态为:
其中 表示执行状态, 是独立 conversation history, 是该 agent 的 Todos, 是局部 file-read timestamps。S_{global} 则保存跨 agent 必须共享的控制量,例如全局 edit permission flag 和 centralized abort controller 。这样 sub-agent 的工具结果和中间推理不会污染 main agent context,但用户点击一次 cancel 仍能终止整棵 agent tree。
released code 中 StateManager.forAgent(agentId) 返回按 agentId 隔离的 accessor;clearAgentState(agentId) 会删除该 agent 的 states、messageHistory、readFileTimestamps、todos、todoTasks 和 fileLineEndings。src/tools/SubAgent.ts 在 foreground 子代理结束时调用 runtime.forAgent(taskId).clearAllState() 并移除 foreground agent,和论文的 agent-local 生命周期相符。
3.2.3 FIFO input queue and safe session reconstruction
当主 agent 正在处理请求时,用户可能继续发消息或输入 slash command。论文定义状态感知 dispatch:
普通文本消息在 dequeue 时会被 semantic batching 合并,减少 LLM round;slash command 则逐个执行,避免操作语义被混合。released code 中 SemaEngine.processUserInput() 若发现 main agent state 为 processing,会把输入按 trimmedInput.startsWith('/') 标成 command 或 inject 加入 pendingUserInputs;src/util/inputQueue.ts 提供 takeNextBatch,StateManager.consumeInjectInputsBeforeNextCommand() 优先消费连续 inject 消息。
安全会话重建的目标是避免 mid-execution 切换项目或 session 时留下残余状态。论文写法是把新 session id 放入 pendingSession,向 发送 abort;当前任务的 finally 检测 pending flag 后清理 并初始化新 session。released code 没有显式 pendingSession 字段,但 SemaEngine.interruptSession()、StateManager.clearPendingUserInputs()、clearAgentState() 和 session pool API 构成了相近的中断/清理路径。
3.2.4 Adaptive context compression
长时间 coding session 会持续积累消息、工具结果和文件片段。论文不用每轮重新计算整段上下文,而是从最近 assistant message 的 usage metadata(如 Anthropic input_tokens)读取累计输入 token,形成 监控。论文还声称在累计 usage 上加 8,000-token forward buffer,用于吸收下一轮 system prompt、user query、tool result 等开销;当 effective context 超过模型最大上下文 的 75% 时触发压缩。
压缩时先找最近真实 user message 作为 pivot ,把历史切成可压缩段 和当前轮保留段 ,避免破坏 tool_use / tool_result 配对。主路径让 LLM 生成摘要,可写成信息保留目标:
若摘要失败或超时,则降级为 deterministic truncation:扫描 usage metadata,截断到上下文上限的 50%,并只在 assistant message 边界截断以保持 API role alternation 合法。released code 的 src/util/compact.ts 与论文基本一致:AUTO_COMPACT_THRESHOLD_RATIO = 0.75,autoCompact() 找最后一条非 tool_result 的真实 user message,executeAutoCompact() 用主模型生成摘要,失败时 truncateMessages(messages, contextLimit * 0.5)。
论文公式与 released code 实现差异:论文描述了额外的 8,000-token forward buffer;main@69f7dcc6 的 needsAutoCompact() 实际是 countTokens(messages).inputTokens >= getContextLimit() * 0.75,没有单独把 8,000 token 加到阈值判断中。代码确实支持 Anthropic input_tokens + cache_creation_input_tokens + cache_read_input_tokens 与 OpenAI prompt_tokens,但 buffer 机制在 released code 中不可见。
3.3 Agent runtime

Figure 3 解读:该图把 runtime 拆成三块:(a) background task execution,把长时间 Bash/Agent 任务移入后台并保留 timeout recovery;(b) multi-agent coordination,为 sub-agent 提供隔离 state space、生命周期管理和 shared abort signal;(c) adaptive context compression,在高压阈值触发 token reduction。它对应论文 §4 的三个运行时目标:并发分工、可观测进度、长任务不阻塞主对话。
3.3.1 Multi-agent collaborative scheduling
复杂代码任务通常需要不同能力:例如先搜索代码、再设计修改、再运行测试、最后 review。把所有子任务塞进 main agent 会出现两个问题:一是某个 Skill 的系统提示污染后续任务;二是 subtask history 和工具结果堆进主上下文,导致更早触发压缩。Sema Code 采用隔离 state spaces + shared interrupt control:sub-agent 与 main agent 不共享 conversation history 或 tool result,只共享 abort controller。
released code 中 src/tools/SubAgent.ts 会根据 agent config 构造独立 system prompt 和工具集;默认排除嵌套 agent/task 相关工具,避免递归失控;sub-agent 的 run_shell 不暴露 background 字段。foreground sub-agent 会注册到 TaskManager,用独立 AbortController 执行 ReAct,结束后清理本地状态;background sub-agent 则通过 spawnAgentTask 注册为后台任务。
3.3.2 Interrupt propagation and read-write-aware scheduling
论文把 interrupt boundary 分成多个阶段:post-inference dispatch、pre-execution verification、active execution monitoring、recursion termination。核心思想是中断不能只 kill 当前进程,还要保证 API message 结构仍合法:尚未执行的 tool_use 要有 cancellation placeholder,正在运行且支持 interrupt 的工具可以返回部分结果,不支持 interrupt 的工具要返回取消上下文。
released code 中 src/core/RunTools.ts 体现了这一点:工具开始前若 abort,直接返回 CANCEL_MSG;工具执行期间若 abort 且 reason 是 refuse,保留拒绝消息;若工具支持 supportsInterrupt()(如 RunShell),保留工具内部返回的部分结果;不支持中断的工具则返回取消 tool_result。调度方面,论文说 read-only 操作可并行,含写操作的 batch 必须串行,以避免 file edit / shell 带来的 race condition。
3.3.3 Intelligent Todo-based process management
Todo 的目标不是“让 LLM 写一个列表”,而是让长任务进度可观测且稳定。LLM 常把同一个任务从 “Refactoring auth module” 改写成 “Refactor authentication module”,如果 UI 逐字替换会闪烁。Sema Code 给每个 task item 分配唯一 id、描述和 lifecycle state(pending / active / completed 等),并强制同一时刻最多一个 active subtask。
released code 中 StateManager.updateTodosIntelligently() 检查新 Todo 是否都是已知 id:如果是 subset update,只更新对应 id 的条目并保留原描述;如果出现未知 id,则全量替换注册新任务。这与论文“ID-matched Todo process management”一致,也解释了为什么 Todo 工具需要 id 而不仅是自然语言列表。
3.3.4 Background task execution
长时间 build/test 会阻塞同步 agent loop;普通 timeout 又会杀掉进程、丢失部分输出,并可能让 shell singleton 卡死。Sema Core 把 execution 与 observation 分离:长任务由 background manager 维护,主对话立刻恢复;后台任务有 running / completed / failed / stopped 等状态,输出被持续写入文件和内存缓冲,用户或 agent 可 later peek/stop。
released code 中 RunShell 有两个路径:background=true 时主 agent 直接调用 TaskManager.spawnRunShellTask(),返回 task id 和 output file;同步命令超时且不是 sub-agent 时,通过 onTimeout 调用 TaskManager.takeoverTask(),把 timed-out persistent shell 转交给后台。代码中默认 timeout 是 120,000 ms,最大 600,000 ms;TaskManager 每个 session 最多 5 个 running background tasks,保留 50 个 finished tasks。
3.4 Security and ecosystem
3.4.1 Four-layer permission decision
论文把权限按操作类型分成四层,而不是一个统一 allow/deny gate:
| Layer | Operation Type | Fast-Pass | Approval Trigger | Granularity |
|---|---|---|---|---|
| L1 | File editing | Edit flag on | First edit request | Session |
| L2 | Shell commands | Prefix in whitelist | Not whitelisted / injection | Project |
| L3 | Skill invocation | Skill authorized | First invocation | Project |
| L4 | MCP operations | Name authorized | First invocation | Project |
形式化地,权限函数为 。对 shell 命令,论文给出白名单规则:
其中 ,每个 sub-command head 都必须命中白名单 。若不命中,系统进入 request;若检测到 backtick、$(...)、破坏性 chain 等注入风险,则升级警告或 deny。
released code 中 PermissionManager.checkToolPermission() 分别处理 file edit、RunShell、Skill、MCP 和 FetchUrl。checkRunShellPermission() 先 splitCommand() 并用 hasCommandInjection() 做 fail-closed 检测,再查 exact/prefix authorization;AutoRun 档位会调用 classifyActionSafety(),风险不明则转人工。与论文相比,released code 更偏 deterministic regex + optional LLM safety classification,而不是所有非白名单命令都先做 LLM-assisted static analysis。
3.4.2 Asynchronous approval protocol
当工具需要用户授权时,engine 不直接阻塞在某个 UI 模态框,而是向 event bus 发 authorization request,暂停当前 execution context。客户端可以用 VSCode dialog、Web UI 或 Feishu/Telegram inline button 处理;engine 只等待 concrete decision 或 global abort。返回路径包括 transient approval、persistent authorization、explicit rejection、user-guided correction。sub-agent 继承 parent permission boundary,避免多 agent 任务中重复弹窗。
3.4.3 Three-tier ecosystem: MCP / Skills / Plugins
Sema Code 把生态扩展分成三种粒度:MCP 是 infrastructure granularity,包装数据库、浏览器、API gateway 等外部服务;Skills 是 behavior granularity,用 Markdown + YAML frontmatter 改变 agent 的推理方式、约束和模型偏好;Plugins 是 workflow granularity,扩展 slash command 或 lifecycle hook,例如 /review、/deploy、审计日志和自定义验证。论文认为三者不能合并,否则会让轻量提示策略拿到过高工具权限,或让基础设施集成失去持久连接和认证管理能力。
3.4.4 Multi-model adaptation layer
Sema Core 内置 Anthropic native 与 OpenAI-compatible adapters,把 Extended Thinking、Prompt Caching、tool-use schema 和 streaming events 归一到统一协议。released code 中 src/services/api/adapt/anthropic.ts 与 src/services/api/adapt/openai.ts 分别处理 provider-specific streaming;SemaCore.getModelAdapter() 通过 inferAdapter() 暴露适配能力。论文还列出可经 customBaseUrl 接入 Code Llama、DeepSeek-Coder、DeepSeek V3/R1、GLM-5、Qwen3-235B、Gemini 2.5 Pro 等模型。
3.5 Pseudocode based on released code
Code reference:
main@69f7dcc6(2026-05-26) — pseudocode and mapping based on this commit
3.5.1 FIFO dispatch and batched query start
from collections import deque
from uuid import uuid4
class SessionRuntime:
def __init__(self):
self.state = "idle"
self.pending_inputs = deque()
self.abort_controller = None
def process_user_input(self, text: str, silent: bool = False):
input_id = str(uuid4())
text = text.strip()
if self.state == "processing":
kind = "command" if text.startswith("/") else "inject"
self.pending_inputs.append({"id": input_id, "text": text, "type": kind, "silent": silent})
emit("input:received", queued=True, inject=(kind == "inject"))
return
self.start_query([{"id": input_id, "text": text, "silent": silent}])
def start_query(self, inputs: list[dict]):
self.state = "processing"
self.abort_controller = AbortController()
ctx = AgentContext(agent_id="main", abort=self.abort_controller, tools=get_available_tools())
try:
process_query(inputs, ctx)
finally:
self.state = "idle"
next_batch = take_next_batch(self.pending_inputs)
if next_batch:
self.start_query(next_batch)3.5.2 Adaptive context compression
AUTO_COMPACT_THRESHOLD_RATIO = 0.75
def needs_auto_compact(messages: list[Message], context_limit: int) -> bool:
if len(messages) < 3:
return False
input_tokens = count_tokens(messages).input_tokens
return input_tokens >= context_limit * AUTO_COMPACT_THRESHOLD_RATIO
def auto_compact(messages: list[Message], llm: LLM, context_limit: int) -> list[Message]:
pivot = find_last_real_user_message(messages) # skip user tool_result messages
if pivot is None:
return messages
history, current_turn = messages[:pivot], messages[pivot:]
if len(history) < 2:
return messages
try:
summary = llm.summarize(history, prompt=COMPRESSION_PROMPT, tools=[NULL_TOOL])
compacted_history = [compression_notice(), assistant_summary(summary)]
except Exception:
compacted_history = truncate_at_assistant_boundary(history, target_tokens=context_limit * 0.5)
return compacted_history + current_turn3.5.3 ID-matched Todo update
def update_todos_intelligently(current: list[Todo], new: list[Todo]) -> list[Todo]:
if not new:
emit("todos:update", [])
return []
known_ids = {todo.id for todo in current}
subset_update = all(todo.id and todo.id in known_ids for todo in new)
if subset_update and current:
by_id = {todo.id: todo for todo in new}
updated = [by_id.get(todo.id, todo) for todo in current]
emit("todos:update", new) # UI receives changed states; text remains stable
return updated
emit("todos:update", new)
return new3.5.4 Shell permission check
def check_run_shell_permission(command: str, allowed_tools: list[str], autorun: bool) -> Permission:
command = strip_initial_cwd_prefix(command)
subcommands = split_command(command)
if any(has_command_injection(cmd) for cmd in subcommands):
return request_permission(command, show_persistent_allow=False, severe=True)
if exact_match(command, allowed_tools) or saved_prefix_match(command, allowed_tools):
return Permission.allow()
if autorun:
if classify_action_safety(command) == "safe":
return Permission.allow()
prefix = infer_command_prefix(command)
return request_permission(command, suggested_prefix=prefix)3.5.5 Background shell execution and timeout takeover
def run_shell(command: str, timeout_ms: int = 120_000, background: bool = False, is_subagent: bool = False):
timeout_ms = min(timeout_ms, 600_000)
if background and not is_subagent:
task_id, output_path = task_manager.spawn_run_shell_task(command)
return f"Command running in background. Task ID: {task_id}. Output: {output_path}"
transfer = {"task_id": None, "path": None}
def on_timeout(ctx: TimeoutTransferContext):
if is_subagent:
return None
transfer["task_id"], transfer["path"] = task_manager.takeover_task(ctx, command)
result = persistent_shell.exec(command, timeout_ms=timeout_ms, on_timeout=on_timeout)
if result.code == -1 and transfer["task_id"]:
return f"Command timed out after {timeout_ms}ms, moved to background: {transfer['task_id']}"
return format_stdout_stderr(result)3.6 Code-to-paper mapping
Code reference:
main@69f7dcc6(2026-05-26) — pseudocode and mapping based on this commit
| Paper Concept | Source File | Key Class/Function |
|---|---|---|
| UI-free embeddable core API | src/core/SemaCore.ts | SemaCore, createSession, model / MCP / Skill / Plugin APIs |
| Per-session public interface | src/core/SemaSession.ts | SemaSession.create, processUserInput, interrupt, event methods |
| Session lifecycle and FIFO input queue | src/core/SemaEngine.ts, src/util/inputQueue.ts | processUserInput, startQuery, takeNextBatch |
| Session and agent-local state | src/manager/StateManager.ts | SessionRuntime, forAgent, clearAgentState, pendingUserInputs |
| Context compression | src/util/compact.ts, src/prompt/compact.ts | needsAutoCompact, autoCompact, compactMessages, COMPRESSION_PROMPT |
| Multi-agent scheduling | src/tools/SubAgent.ts, src/tools/PlanToAgent.ts | SubAgent, PlanToAgent, foreground/background agent task paths |
| Todo process management | src/manager/StateManager.ts, src/tools/CreateTodo.ts, src/tools/UpdateTodo.ts, src/tools/ListTodos.ts | updateTodosIntelligently, Todo CRUD tools |
| Background task execution | src/tools/RunShell.ts, src/manager/TaskManager.ts, src/tools/PeekBgJob.ts, src/tools/StopBgJob.ts | spawnRunShellTask, takeoverTask, waitForTask, stopTask |
| Permission decision layers | src/manager/PermissionManager.ts, src/util/commands.ts | checkToolPermission, checkRunShellPermission, hasCommandInjection |
| MCP / Skills / Plugins ecosystem | src/services/mcp/MCPManager.ts, src/services/skills/skillsManager.ts, src/services/plugins/pluginsManager.ts | MCP server config, Skill config loading, marketplace plugin APIs |
| Multi-model adapters | src/services/api/adapt/anthropic.ts, src/services/api/adapt/openai.ts, src/util/adapter.ts | Anthropic/OpenAI-compatible streaming adapters, inferAdapter |
4. Experimental Setup (实验设置)
这篇论文不是模型训练或 benchmark paper;它的“实验设置”是 deployment validation:用同一个 Sema Core engine 支撑两个不同产品形态,验证 decoupled engine 是否真的能跨客户端复用。因此没有训练集、学习率、batch size、GPU 数或 supervised/RL training steps。论文未详细说明任何 SWE-bench / HumanEval / pass@k 实验。
Datasets / deployments
- VSCode Extension:单用户、in-process 部署,运行在 VSCode Extension Host;覆盖长 session 的 adaptive context compression、四层权限系统、background task execution、MCP/Skill/Plugin marketplace。
- SemaClaw multi-channel agent platform:服务器端 Node.js 进程,多用户、多渠道部署;接入 Telegram、Feishu 等 messaging channels 和 Web UI 管理界面;覆盖 multi-tenant isolation、FIFO input queue 和 asynchronous approval protocol。
- 规模说明:论文用“50-person team”作为多租户动机场景,但 deployment validation 没有给出真实并发用户数、请求量、延迟、吞吐或故障率数据。
Baselines / compared systems
论文没有做数值 baseline comparison,而是在 Related Work 中按系统类型对比:
| Group | Systems | Contrast |
|---|---|---|
| End-user coding products | Claude Code, Cursor, GitHub Copilot | 能力强但绑定 CLI / IDE / plugin form factor,核心能力难以作为第三方 engine 复用 |
| Agentic coding frameworks | SWE-agent, OpenHands, Agent-Computer Interface, Agentless | 更关注 solve GitHub issue 或 repository repair 流程,通常仍绑定特定 execution harness |
| Multi-agent / orchestration | AutoGen, LangChain, MetaGPT, ChatDev | 通用或流程化协作框架,不内置 coding-agent-specific 权限、Todo、background shell、context lifecycle |
| Memory / context systems | MemGPT, YaRN | 解决长上下文或 paging,但不是 embeddable coding agent runtime |
Evaluation metrics
论文的评价指标是架构性而非统计性:
- Engine modification count:两个产品是否需要修改 Sema Core;论文报告为 zero engine modifications。
- Mechanism coverage:两个部署合起来是否覆盖八个核心机制;论文报告 VSCode 与 SemaClaw 互补,together cover all eight mechanisms。
- Client-side integration effort:客户端是否只需 event stream rendering、channel adapter、permission UI 或 multi-session manager,而不需要理解内部 state/compression/permission 机制。
- Delivery-agnostic behavior:同一 engine binary 是否在不同 UI、通道和拓扑下运行,无 feature flags 或 conditional code paths。
Implementation / training config
- Released package:
package.json中 npm package 为sema-core,version2.0.3,main entrydist/index.js,typesdist/index.d.ts,licenseMIT。 - Build scripts:
npm run build调用tsc;npm run lint调用eslint src/**/*.ts;prepublishOnly会先 build。 - Runtime config from code:
RunShell默认 timeout120000ms,最大600000ms;TaskManager每 session 最多5个 running background tasks,保留50个 finished tasks;compact.ts自动压缩阈值为 context limit 的0.75,失败降级截断到0.5context limit。 - Model/provider config:repo 依赖
@anthropic-ai/sdk与openai,并通过 Anthropic native / OpenAI-compatible adapters 支持 Prompt Caching、Extended Thinking 与 tool-use schema 的差异归一。
5. Experimental Results (实验结果)
Main deployment findings
| Claim | Evidence reported in paper | Exact status |
|---|---|---|
| Same engine supports different product forms | VSCode Extension and SemaClaw both import the same Sema Core npm package | 2 deployments |
| Client-specific behavior stays outside engine | UI rendering, channel routing, permission dialogs, deployment topology live in client layer | zero engine modifications |
| Mechanisms compose without interference | VSCode stresses context compression/background tasks; SemaClaw stresses multi-tenant isolation/FIFO/async approval | together cover all 8 mechanisms |
| Integration boundary is clean | VSCode implements event stream rendering and UI components; SemaClaw implements Telegram/Feishu adapters and multi-session manager | clients use public API + typed event stream |
Key findings
- Decoupling is feasible at product level:论文报告两个不同交互模型的产品共用同一个 engine binary,没有 feature flags 或 per-product conditional path。这支持“engine-first”架构主张。
- 机制覆盖互补:VSCode 单用户场景主要验证长上下文、权限和后台任务;SemaClaw 多用户消息场景主要验证多租户隔离、输入队列和异步 approval。两者合起来覆盖论文列出的八个 mechanisms。
- 代码实现支持主要机制,但与论文描述存在差异:repo 确实包含 session API、permission manager、context compression、sub-agent、Todo、background task 和 MCP/Skill/Plugin manager;但当前 commit 没有可见
AsyncLocalStorage,也没有论文中 8,000-token forward buffer 的实现。
Ablation studies
论文未提供传统 ablation table,也没有逐项移除机制后的数值退化。可从系统设计推断每个组件的 failure mode,但这不是实验测量:移除 FIFO 会导致 message burst 丢失或命令混合;移除 Todo id matching 会导致 UI flicker;移除 background takeover 会让长 build/test 阻塞主对话;移除四层权限会在 shell/MCP/Skill 之间混淆风险边界。
Limitations
作者明确列出五类限制:
- 只验证了两种产品形态;CI/CD pipeline、Jupyter notebook embedding 等其他 form factor 尚未证明。
- 当前部署没有做大规模 stress testing;数百并发用户的生产负载可能暴露性能瓶颈。
- context compression 质量依赖底层 LLM 的 summarization 能力;高密度代码上下文可能在摘要中丢失关键细节,而 truncation fallback 会牺牲连贯性换可用性。
- WebSocket / gRPC 跨语言接口虽然功能完整,但没有 benchmark streaming throughput 或 adversarial network 下的 error recovery。
- 当前部署使用单个 Sema Core 进程;横向扩展到多个 engine instance 会引入 state synchronization 问题,当前架构未解决。
Overall conclusion
Sema Code 的主要贡献是把 AI coding agent 从“产品功能”提升为“可编程基础设施”。它没有证明自己在 SWE-bench 上超过某个 agent,而是证明一套 coding-agent runtime 可以被拆成可嵌入核心:同一 Sema Core engine 通过事件流服务 VSCode extension 和多渠道 SemaClaw,同时保留上下文压缩、多 agent、权限、Todo、后台任务与生态扩展能力。对读者最重要的 takeaway 是:如果要在企业内部构建多个 agent 入口,不应复制多个 monolithic agent,而应先定义一个 delivery-agnostic engine boundary。