jcode · 文档
运行时 · 状态机 · 流程
深入 jcode 的运行时行为——从单轮对话的完整状态机,到 Swarm 多智能体并行协作时序,再到向量记忆的写入与检索闭环,以及自我修改源码的热重载循环。
■ Agent 对话循环状态机
每一轮用户输入触发一次完整的状态转换。状态机在 agent/conversation.rs 中实现,通过 Rust enum 精确建模每个阶段。
INIT
加载 config · 初始化 memory engine · 扫描 skills
▼load & scan
SKILL_INJECT
语义匹配 skills → 注入 system prompt
▼
READY
TUI 就绪 · 等待用户输入
▼user input
MEMORY_RETRIEVAL
cosine similarity → prepend 相关记忆
▼
LLM_CALL (streaming)
发送请求 · 流式解析 tokens
▼parse response
TOOL_PARSE
tool_calls 存在?
Tool Parse 分支
YES
有 tool_calls
TOOL_DISPATCH (并行)
browser / shell / file / grep / git / mcp...
TOOL_RESULTS
append results → 回到 LLM_CALL ↩
NO
最终 assistant 响应
RENDER (Handterm TUI)
MEMORY_EXTRACT (background)
PERSIST_SESSION (SQLite)
→ 回到 READY ↩
状态转换说明
| 状态 | 触发条件 | 主要操作 | 下一状态 |
|---|---|---|---|
| INIT | 进程启动 | 读取 config.toml、初始化 vector DB、扫描 skills 目录 | SKILL_INJECT |
| SKILL_INJECT | INIT 完成 | 语义匹配当前上下文,将匹配 Skill 注入 system prompt | READY |
| READY | 循环起点 | 渲染 TUI,等待用户输入。接受键盘/语音/管道输入 | MEMORY_RETRIEVAL |
| MEMORY_RETRIEVAL | 收到用户输入 | 将输入向量化,cosine similarity 查找 top-k 记忆,prepend 到 context | LLM_CALL |
| LLM_CALL | context 构建完毕 | 流式调用 LLM Provider,实时渲染 token 到 TUI | TOOL_PARSE |
| TOOL_DISPATCH | 发现 tool_calls | 并行执行各工具,收集结果 append 到 messages | LLM_CALL(再次) |
| RENDER | 最终 assistant 响应 | Handterm 渲染完整输出,含 Mermaid、diff、代码块 | MEMORY_EXTRACT |
| MEMORY_EXTRACT | 渲染完成(后台) | 将当前轮次向量化并存储,若到 consolidation 时间则触发 ambient | PERSIST_SESSION |
| PERSIST_SESSION | 记忆处理完成 | 写入 SQLite 会话记录,更新 session metadata | READY(循环) |
■ Swarm 多智能体协作流程
Swarm 模式由 swarm_coordinator 驱动。Primary Agent 负责任务分解和结果整合,Worker Agent 并行处理独立子任务,文件冲突通过 conflict.rs 实时通知并解决。
① Primary Agent 启动
用户运行 jcode --swarm primary,swarm_coordinator 初始化消息总线,注册 Primary 为协调者。
② 任务分析与子任务识别
Primary Agent 调用 LLM 分析任务,识别可并行化的独立子任务(无数据依赖的任务可并行)。生成任务分配计划。
③ Spawn Worker Agents
swarm_coordinator.spawn_worker() 为每个子任务启动独立 jcode 进程(最多 max_agents 个),每个 Worker 获得独立 context 和工具权限。
Worker A
feature implementation
Worker B
test writing
Worker C
documentation update
④ 并发执行 + 文件冲突检测
Workers 并行运行各自的 Agent 循环。conflict.rs 监控文件系统变更,当两个 Agent 同时修改同一文件时,向所有相关 Agent 发送冲突通知,触发协商队列。
⑤ 跨 Agent 消息通信
通过 messenger.rs 实现三种通信模式:
DM (点对点)
Primary → Worker B: "focus on auth tests"
Broadcast (广播)
Primary → All: "API schema changed"
Channel (主题)
#repo/main: 仓库级公共频道
⑥ 结果收集与整合
所有 Worker 完成后,Primary Agent 收集各自输出,调用 LLM 进行最终整合——解决潜在的代码风格不一致、确保接口兼容,生成统一的最终结果。
■ 语义记忆系统流程
jcode 的记忆系统分为三个子流程:写入(每轮向量化存储)、检索(余弦相似度查询)、整理(ambient 后台合并)。全部由 jcode-memory crate 实现。
写入路径 · Write Path
对话轮次 t
→
embedding_engine
→
1536-dim vector
→
vector DB (SQLite + index)
每轮 user + assistant 消息对生成一个独立向量,metadata 包含 timestamp、session_id、importance_score
检索路径 · Retrieval Path
用户输入 "X"
→
query_engine: "X" → 查询向量
→
cosine_similarity(query, stored)
→
top-k 匹配记忆
→
prepend 到 context window
默认返回 top-5 相关记忆,相似度阈值可配置,低于阈值的结果被过滤
Ambient 整理 · Background Consolidation(每 5 分钟)
定时器触发
→
review 最近记忆
→
检测陈旧 / 冲突
→
合并重复 · 删除陈旧
→
提升重要记忆权重
consolidation_interval 默认 "5m",可在 config.toml [memory] 段配置。整理在后台线程运行,不阻塞主循环
三阶段记忆生命周期
✍️
写入阶段
每轮对话结束后,memory_engine 将对话内容向量化(1536维),连同元数据一起写入 SQLite 向量索引。
engine.rs · write()
⇄
🔍
检索阶段
用户输入到来时,query_engine 生成查询向量,扫描存储索引,余弦相似度排序后返回最相关的 top-k 记忆片段。
engine.rs · query()
⇄
🔄
整理阶段
ambient.rs 后台定期运行,合并语义重复的记忆条目,标记并删除过时信息,更新重要记忆的优先级权重。
ambient.rs · consolidate()
■ 自我开发循环
self_dev 模式下,Agent 将自己的 Rust 源码视为可编辑的工作区。修改 → 构建 → 热重载形成闭环,失败时 Agent 自动分析错误并修正。
🔧 自我开发流程
1
用户触发自我开发任务
用户在 TUI 中输入类似 "improve your own grep performance",Agent 识别出这是一个 self_dev 任务,激活 self_dev 模块。
2
Agent 读取并分析源码
使用标准 file_read 工具读取目标源文件(如 src/tools/grep.rs),分析当前实现,规划优化方案。
3
修改 Rust 源文件
Agent 通过 file_write 工具写入修改后的代码。self_dev 模块拦截对 src/ 目录的写入操作,标记需要重新构建。
4
builder.rs 触发 cargo build
后台执行 cargo build --release,实时将构建日志流式输出到 TUI 的专用面板,不阻塞主对话流。
5
构建结果分支
根据构建结果走不同路径:
✓ 构建成功 → reloader.rs 热重载
✗ 构建失败 → 错误输出回 Agent → 自我修正
6
reloader.rs 热重载二进制
新二进制替换当前进程,通过进程内存序列化保存当前会话状态(对话历史、记忆引用、配置),在新进程中无缝恢复——用户感知不到重启。
💡
安全边界:self_dev 模式有明确的文件系统沙箱——Agent 只能修改 src/ 目录下的 Rust 文件。对 Cargo.toml 的修改需要额外确认,对系统文件的访问被完全拒绝。详见 docs/SAFETY_SYSTEM.md。
■ System Prompt 构造管线
每次 LLM_CALL 前,jcode 动态组装 System Prompt。各层内容按优先级叠加,后层覆盖前层的冲突指令。
基础系统指令
jcode 内置的安全规则与 Agent 行为准则
+
~/.jcode/INSTRUCTIONS.md
用户全局自定义指令(所有项目生效)
+
.jcode/AGENTS.md
项目级指令,覆盖全局(本项目专属行为)
+
Skills(语义匹配注入)
skill_injector.rs 在会话启动时语义匹配并注入
+
Memory Context(余弦检索)
每轮对话实时检索,top-k 相关记忆注入
▼
✨
最终 System Prompt → LLM
动态组装,每轮对话均可不同(memory context 随查询变化)
优先级与覆盖规则
| 来源 | 优先级 | 动态性 | 说明 |
|---|---|---|---|
| 基础系统指令 | 最低 | 静态 | jcode 内置,用户无法修改 |
| ~/.jcode/INSTRUCTIONS.md | 低 | 静态 | 全局用户偏好,所有项目共享 |
| .jcode/AGENTS.md | 中 | 静态 | 项目级,覆盖全局冲突指令 |
| Skills(语义注入) | 高 | 会话启动时确定 | 根据任务语义动态选择,每次会话可不同 |
| Memory Context | 最高(上下文) | 每轮动态 | 每轮对话实时检索,最贴近当前查询 |
■ 启动时序分解
jcode 的 14ms 首帧目标通过严格的延迟初始化实现——只有渲染 TUI 必须的最小集合在主线程同步初始化,其余全部异步后台加载。
| 阶段 | 时机 | 耗时 | 说明 |
|---|---|---|---|
| 进程启动 + 基础配置读取 | 同步,主线程 | ~3ms | 解析 CLI args,读 config.toml |
| Handterm TUI 初始化 | 同步,主线程 | ~8ms | 分配终端缓冲区,注册信号处理 |
| 首帧渲染 | — | 14ms ✓ | 用户看到 TUI 界面 |
| Memory engine 初始化 | 异步后台 | ~20ms | 打开 SQLite,加载向量索引 |
| Skills 扫描 + 语义匹配 | 异步后台 | ~15ms | 读取 ~/.jcode/skills/,向量匹配 |
| 首次可输入 | — | 48.7ms ✓ | memory + skills 就绪,完整功能可用 |
| Provider 连接预热 | 懒加载(首次 LLM_CALL 时) | 按需 | 建立 TLS 连接,不影响启动时序 |