CogitoAgent 技术演进之路:从终端到桌面,从工具到生态
------CogitoAgent开发实战(最终篇)
📖 本文是专栏的最终篇。从第一篇的状态机到第十一篇的桌面应用,我们共同走过了一条完整的AI Agent构建之路。这一篇,我们不写新代码,不展开新功能------而是回望来路,审视项目从v1.0到v2.3的每一次关键跃迁,复盘那些影响深远的设计决策,坦诚地聊聊踩过的坑与犯过的错,并邀请你一起加入这场开源共建。
开源地址
Gitee(国内主站): https://gitee.com/cnt-code/cogito-agent
GitHub(国际镜像): https://github.com/SnowLeopard-io/CogitoAgent
欢迎⭐Star、🍴Fork、📥下载体验、🐛提Issue、✨提交PR。
一、从一份README说起
如果你现在打开 CogitoAgent 的 README,你会看到这样的描述:
CogitoAgent 是一款运行于本地的自主 AI 智能体,融合了文件管理、知识挖掘、系统操作、代码执行与联网能力。它直接在用户配置的工作目录下运行,无需上传任何文件至第三方服务器,在保障数据隐私安全的同时,提供持续运转的智能助理服务。
这段简洁的文字背后,是19个工具模块、14个分类、103+测试用例、v2.3.0版本的积累,是几十个夜晚的代码与思考。
但最早的时候,它只是一个念头------一个让AI真正"活"在电脑里的念头。
这个念头源于一个简单的观察:我们每天都在电脑里产生海量的文件------代码、文档、笔记、图片、设计稿------但AI却看不见它们。每次使用ChatGPT,你都得手动上传文件;每次想让它帮你整理文件夹,它无能为力;每次对话结束,它什么都不记得。
于是我想:能不能做一个AI,让它主动走进我的文件世界,而不是等着我把文件塞给它?
这就是CogitoAgent的起点。
从那个念头到现在,项目走过了四个大版本,经历了从"终端工具"到"桌面应用"、从"个人项目"到"开源生态"的完整演进。这一篇,我们不讲代码细节------那些已经在前面十一篇文章里讲透了。我们讲历程、讲决策、讲教训、讲未来。
二、版本演进:从v1.0到v2.3的四个里程碑
v1.0:从零到一
时间:项目启动初期
核心能力:
- 状态机(THINKING / AWAITING_INPUT)
- 5个文件工具(ls/read/copy/mkdir/create)
- 联网搜索
- 终端UI(彩色输出)
标志性事件:第一个可运行的版本诞生,AI能在终端里持续思考,每隔3秒自动触发一轮思考循环。
当时的状态:这是一个纯粹的终端工具,用户通过命令行交互,AI能做的事情有限------看看目录、读读文件、搜搜网页。但它证明了"持续思考"这个想法是可行的。
局限:
- 只有终端界面,普通用户无从下手
- 工具调用用switch-case硬编码,每加一个工具都要改核心代码
- 没有记忆系统,每次重启都是"初次见面"
- 没有会话管理,所有对话挤在同一条时间线上

v2.0:功能爆发
时间:第一次大版本迭代
新增功能:
- 代码执行引擎(JavaScript/Python)
- Git版本控制集成
- 任务管理系统
- 记忆系统
- 数据处理工具(CSV/JSON)
- SQLite数据库操作
- 邮件功能
- 系统监控
- 定时任务调度
- 多模型支持(OpenAI/Moark/Anthropic/Google)
架构变化:工具数量从5个跃升至12+模块,Agent.js开始膨胀到几百行。
用户价值:从一个"文件助手"变成了"全能工具平台"。AI不仅能看文件,还能帮你写代码、提交Git、管理任务、记住信息、处理数据。
这个阶段的核心思考:AI Agent的能力边界在哪里?答案是------只要你能定义清楚一个操作(文件、代码、Git、数据库),AI就能学会调用它。所以工具的数量会持续增长,架构必须在第一天就为扩展做好准备。
v2.1:安全加固
时间:发现安全漏洞后的紧急迭代
关键决策:移除存在安全漏洞的vm2依赖,改用Node.js原生vm模块。
背景:vm2是一个流行的JavaScript沙箱库,但被发现存在原型链逃逸漏洞,且已停止维护。继续使用意味着用户的系统可能暴露在风险中。
跨平台改进 :工作区路径从硬编码的D:\\改为默认使用用户主目录(os.homedir()),移除了Windows路径的硬编码。
教训:安全不能妥协。一个沙箱逃逸漏洞就可能让用户的整个系统暴露在风险中。定期审计依赖库的安全状态是必须的。同时,跨平台意识应该从第一天就建立,而不是后期补救。
v2.2:架构重构
时间:项目规模膨胀后的必要调整
核心变化:Agent.js拆分为独立模块
state.js:状态机管理registry.js:工具注册表commands.js:命令处理
新增 :logger.js分级日志系统(DEBUG/INFO/WARN/ERROR)
测试:测试用例从43增至103+
本质:从"功能堆积"走向"工程化设计"。当Agent.js超过800行时,继续堆功能只会让代码难以维护。拆分不是"重构完成",而是"为未来扩展腾出空间"。
v2.3:桌面化与生态化
时间:当前最新版本
桌面革命:
- Electron桌面应用(悬浮窗 + Dashboard仪表盘)
- WebSocket桥接(Electron ↔ Agent独立进程)
- 双模式切换(桌面模式 / 仪表盘模式)
- 毛玻璃UI + 虚拟人物视频
会话管理:
- 多会话系统(创建/切换/删除/重命名)
- 自动压缩归档(150轮 / 100K token)
- 会话持久化存储
新工具:
- OCR图像文字识别(基于视觉大模型)
- Office文档生成(PPT/Word/Excel)
架构升级:
isolated-vm进程级沙箱(替代原生vm)- 插件系统(动态加载自定义工具)
- MCP协议兼容(Model Context Protocol)
tracing.js追踪模块retry.js熔断与重试机制
意义:这是项目的一次质变------从"开发者工具"进化为"人人可用的桌面应用"。普通用户不再需要打开命令行,双击图标就能和AI对话。

三、架构演进的五个关键决策
3.1 状态机:从"双状态"到"三状态"
最初:THINKING + AWAITING_INPUT
AI要么在思考,要么在等用户输入。用户按Enter可以打断思考。这个设计解决了"AI自顾自说话,用户插不上嘴"的问题。
现在:增加了AWAITING_CONFIRMATION(危险操作确认)
javascript
const STATE = {
THINKING: 'THINKING', // AI自主思考
AWAITING_INPUT: 'AWAITING_INPUT', // 等待用户输入
AWAITING_CONFIRMATION: 'AWAITING_CONFIRMATION' // 等待用户确认危险操作
};
为什么需要确认态?
危险操作(如gitPush、executeCode、deleteData)如果自动执行,用户可能不小心触发删除文件、覆盖远程仓库等不可逆操作。确认态让用户对高风险操作有最终决定权。
javascript
if (isDangerousOperation(toolName)) {
const confirmed = await requestConfirmation(toolName, args);
if (!confirmed) return { success: false, error: '用户拒绝' };
}
核心原则:AI可以建议,但用户决定。这个原则贯穿了整个项目的安全设计。
3.2 工具系统:从"switch-case"到"注册表"
这是架构演进中最能体现"预见性"的决策。
第一阶段:switch-case
javascript
async function executeTool(tool, args) {
switch (tool) {
case 'ls': return await ls(args[0]);
case 'read': return await read(args[0]);
case 'copy': return await copy(args[0], args[1]);
// ... 100+ 个 case
}
}
问题很明显:每加一个工具,就要改一次核心文件。100个工具意味着100个case分支。而且每个工具的参数处理方式不同------create需要把后面的参数拼成内容,search需要把所有参数用逗号连接------这些特殊逻辑散落在各个case里,维护成本极高。
第二阶段:注册表模式
javascript
const TOOL_REGISTRY = {
ls: { fn: tools.ls, argCount: 1, category: 'file' },
read: { fn: tools.read, argCount: 1, category: 'file' },
create: { fn: tools.create, argCount: 2, customArgs: true, category: 'file' },
// ...
};
加工具只需要写函数 + 在注册表里加一条配置,核心代码(executeTool)完全不用动。参数处理的特殊逻辑也集中在注册表里声明,而不是散落在各个分支。
进阶:甚至支持自动扫描生成注册表,加工具只需要写函数 + 导出两步。
核心启示:工具数量会迅速膨胀。架构必须在第一天就为扩展做好准备。这就是开闭原则(对扩展开放,对修改关闭)在实践中的体现。
3.3 工具调用协议:为什么不用Function Calling?
我们没有使用OpenAI的Function Calling,而是设计了纯文本标记协议:
[TOOL] toolName("参数1", "参数2") [/TOOL]
为什么?
| 对比项 | Function Calling | 纯文本标记 |
|---|---|---|
| API兼容性 | 仅OpenAI格式 | 任何LLM都支持 |
| 参数schema | 需要JSON定义 | 自然语言/简单字符串 |
| 多工具调用 | 需要特殊处理 | 正则匹配即可 |
| 调试难度 | 黑盒 | 纯文本,一目了然 |
核心启示:不要被特定厂商的"标准"绑定。跨模型兼容性比"标准化"更重要。一个你完全掌控的简单协议,比一个依赖外部SDK的复杂协议更可靠。
3.4 API客户端:从"SDK依赖"到"原生fetch"
最初:使用OpenAI官方SDK。
现在 :完全移除SDK依赖,改用原生fetch直接调用API并解析SSE流。
javascript
// 直接读取SSE流
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
// 逐行解析 data: {...}
}
理由:
- SDK体积大,增加了项目依赖和安装时间
- SDK的SSE解析在某些网络环境下有bug(连接提前关闭)
- 原生
fetch更可控,支持精细化的重试和错误处理 - 减少了一层抽象,调试更容易
启示:不要因为"官方SDK"就默认它是最佳选择。有时候,手写一个轻量级客户端更可靠、更可控。
3.5 桌面化:从"终端"到"Electron"
这是v2.3最大的变化------让AI从"命令行工具"变成"桌面应用"。
架构:Electron主进程 + 独立Agent进程 + WebSocket桥接
#mermaid-svg-tqECSGvrAYGakLb0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tqECSGvrAYGakLb0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tqECSGvrAYGakLb0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tqECSGvrAYGakLb0 .error-icon{fill:#552222;}#mermaid-svg-tqECSGvrAYGakLb0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tqECSGvrAYGakLb0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tqECSGvrAYGakLb0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tqECSGvrAYGakLb0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tqECSGvrAYGakLb0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tqECSGvrAYGakLb0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tqECSGvrAYGakLb0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tqECSGvrAYGakLb0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tqECSGvrAYGakLb0 .marker.cross{stroke:#333333;}#mermaid-svg-tqECSGvrAYGakLb0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tqECSGvrAYGakLb0 p{margin:0;}#mermaid-svg-tqECSGvrAYGakLb0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tqECSGvrAYGakLb0 .cluster-label text{fill:#333;}#mermaid-svg-tqECSGvrAYGakLb0 .cluster-label span{color:#333;}#mermaid-svg-tqECSGvrAYGakLb0 .cluster-label span p{background-color:transparent;}#mermaid-svg-tqECSGvrAYGakLb0 .label text,#mermaid-svg-tqECSGvrAYGakLb0 span{fill:#333;color:#333;}#mermaid-svg-tqECSGvrAYGakLb0 .node rect,#mermaid-svg-tqECSGvrAYGakLb0 .node circle,#mermaid-svg-tqECSGvrAYGakLb0 .node ellipse,#mermaid-svg-tqECSGvrAYGakLb0 .node polygon,#mermaid-svg-tqECSGvrAYGakLb0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tqECSGvrAYGakLb0 .rough-node .label text,#mermaid-svg-tqECSGvrAYGakLb0 .node .label text,#mermaid-svg-tqECSGvrAYGakLb0 .image-shape .label,#mermaid-svg-tqECSGvrAYGakLb0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-tqECSGvrAYGakLb0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tqECSGvrAYGakLb0 .rough-node .label,#mermaid-svg-tqECSGvrAYGakLb0 .node .label,#mermaid-svg-tqECSGvrAYGakLb0 .image-shape .label,#mermaid-svg-tqECSGvrAYGakLb0 .icon-shape .label{text-align:center;}#mermaid-svg-tqECSGvrAYGakLb0 .node.clickable{cursor:pointer;}#mermaid-svg-tqECSGvrAYGakLb0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tqECSGvrAYGakLb0 .arrowheadPath{fill:#333333;}#mermaid-svg-tqECSGvrAYGakLb0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tqECSGvrAYGakLb0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tqECSGvrAYGakLb0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tqECSGvrAYGakLb0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tqECSGvrAYGakLb0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tqECSGvrAYGakLb0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tqECSGvrAYGakLb0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tqECSGvrAYGakLb0 .cluster text{fill:#333;}#mermaid-svg-tqECSGvrAYGakLb0 .cluster span{color:#333;}#mermaid-svg-tqECSGvrAYGakLb0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tqECSGvrAYGakLb0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tqECSGvrAYGakLb0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-tqECSGvrAYGakLb0 .icon-shape,#mermaid-svg-tqECSGvrAYGakLb0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tqECSGvrAYGakLb0 .icon-shape p,#mermaid-svg-tqECSGvrAYGakLb0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tqECSGvrAYGakLb0 .icon-shape .label rect,#mermaid-svg-tqECSGvrAYGakLb0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tqECSGvrAYGakLb0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tqECSGvrAYGakLb0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tqECSGvrAYGakLb0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Agent 独立进程
Electron 桌面应用
WebSocket
spawn 启动
main.js
主进程
UI 渲染进程
桌面/仪表盘
agent-bridge.js
WebSocket 桥接
ws-server.js
WebSocket 服务
端口 9527
agent/Agent.js
思考循环 + 工具执行
session.js
会话管理
为什么选择独立进程?
| 方案 | 优点 | 缺点 |
|---|---|---|
| 嵌入Electron | 通信简单 | Agent崩溃会拖垮整个界面 |
| 独立进程 | 隔离性好,可独立重启 | 需要进程间通信 |
独立进程让界面和推理分离,即使Agent出现异常,界面也不会卡死。WebSocket作为通信桥梁,支持双向实时消息传递,正好适配流式输出的场景。
双模式设计:
| 模式 | 命令 | 定位 |
|---|---|---|
| 桌面模式(悬浮窗) | npm run electron:desktop |
轻量级,桌面伴侣 |
| 仪表盘模式 | npm run electron:dashboard |
全功能工作台 |
四、踩过的坑与修正
4.1 "完全本地"的表述错误(已修正)
问题:早期宣传中用了"完全本地运行"的表述,但CogitoAgent需要调用云端API进行推理。这个表述会让用户误以为"完全不联网",产生错误的预期。
修正:改为"云端推理、本地执行",明确区分"推理在云端、文件数据在本地"。
正确的架构说明:
| 能力 | 运行位置 | 说明 |
|---|---|---|
| AI推理 | ☁️ 云端API | 调用大模型处理指令和上下文 |
| 工具执行 | 💻 本地 | 文件操作、代码执行、Git、数据库等 |
| 数据存储 | 💻 本地 | 对话历史、记忆、任务等存储在本地JSON/SQLite |
教训:技术宣传必须精准。一个模糊的表述会误导用户,损害信任。与其用"完全本地"这种绝对化的词,不如用"云端驱动、本地执行"这样准确的描述。
4.2 路径安全:至今未完全解决
问题 :file.js中所有工具函数使用path.isAbsolute(targetPath) ? targetPath : path.join(basePath, targetPath)。用户可传入C:\Windows或/etc/passwd逃逸工作区。
javascript
// ❌ 危险:用户可传入工作区外的绝对路径
const fullPath = path.isAbsolute(targetPath) ? targetPath : path.join(basePath, targetPath);
应该怎么做:
javascript
// ✅ 安全:严格限制在工作区内
function secureResolvePath(targetPath) {
const base = path.resolve(getBasePath());
const full = path.resolve(base, targetPath);
if (!full.startsWith(base)) {
throw new Error(`路径越权: ${targetPath} 不在工作区内`);
}
return full;
}
为什么至今没修?
这是一个已知的技术债务。原因不是"不知道怎么修",而是"修了之后需要全面测试所有文件操作,确保不影响正常使用"。在功能快速迭代的阶段,这个优先级被排在了后面。
但这不应该是借口。文件操作的权限控制是本地AI Agent最核心的安全防线。应该在第一天就实现严格的路径验证函数,而不是事后补救。
4.3 上下文管理:从"激进压缩"到"智能压缩"
最初:压缩过于激进,简单粗暴地截断历史,导致AI丢失关键上下文。
问题表现:用户和AI聊了100轮后,AI突然"失忆",不记得之前讨论过的重要文件或决策。
现在:混合策略------保留最近10轮对话,将更早的内容生成摘要归档,摘要里包含"已发现的重要文件""已执行的关键操作""当前工作状态"等结构化信息。
javascript
function compressHistory() {
// 1. 保留最近10轮
const recentMessages = nonSystemMessages.slice(-10);
// 2. 生成摘要
const summary = generateSummary(recentMessages);
// 3. 重建历史(系统提示 + 摘要 + 最近对话)
conversationHistory = [
{ role: 'system', content: buildSystemPrompt() },
{ role: 'user', content: `[上下文摘要] ${summary}` },
...recentMessages
];
}
启示:上下文管理是AI Agent的"记忆系统"。既要控制token成本,又要保留足够的信息让AI理解全局。压缩不是"丢弃",而是"提炼"。
4.4 沙箱选择:从vm2到原生vm到isolated-vm
第一阶段 :使用vm2。它是当时最流行的JavaScript沙箱库。
第二阶段 :发现vm2存在原型链逃逸漏洞,且已停止维护。紧急切换到Node.js原生vm模块。
第三阶段 :发现原生vm虽然比vm2安全,但仍有已知的逃逸路径。进一步升级到isolated-vm------它使用独立的V8 Isolate,真正的进程级隔离,内存限制128MB,CPU超时控制。
javascript
// sandbox.js - 优先使用isolated-vm
async function getIvm() {
try {
const mod = await import('isolated-vm');
return mod.default || mod;
} catch {
console.warn('[sandbox] isolated-vm 不可用,使用原生 vm');
return null;
}
}
教训:安全领域没有"一劳永逸"。依赖库会过时,漏洞会不断被发现。定期审计、及时升级是必须的。
4.5 多会话:从"单线程"到"多线程"
问题:早期所有对话挤在同一条时间线上。用户想讨论项目A,就得清空之前关于项目B的对话;想切换话题,AI会用旧话题的背景来回答新问题。
现在:多会话系统,每个会话独立存储、独立上下文,支持切换、创建、删除、重命名。
会话存储结构:
data/sessions/
├── meta.json # 会话列表 + 当前激活ID
├── sess_abc123.json # 会话A的完整历史
├── sess_def456.json # 会话B的完整历史
└── sess_abc123_archive.json # 会话A的归档文件
启示:用户的需求是多样化的。一个"万能对话"永远满足不了所有场景。提供组织和分类的能力,是产品从"可用"到"好用"的关键一步。
五、项目现状全景
5.1 功能全景
| 类别 | 工具 | 状态 |
|---|---|---|
| 文件操作 | ls, read, copy, mkdir, create, delete, move | ✅ |
| 网页工具 | search, browse, fetchPage, searchOnEngine | ✅ |
| 浏览器自动化 | initBrowser, clickElement, fillField, takeScreenshot, getText, waitForElement, closeBrowser | ✅ |
| 系统操作 | listApps, openApp, closeApp | ✅ (Windows为主) |
| 代码执行 | executeCode, runJavaScript, runPython | ✅ |
| Git | gitStatus, gitCommit, gitPush, gitPull, gitDiff, gitLog | ✅ |
| 任务管理 | createTask, getTasks, completeTask, splitTask | ✅ |
| 记忆系统 | addMemory, searchMemory, getRelatedMemories, deleteMemory | ✅ |
| 数据处理 | readCSV, writeJSON, csvToJSON, queryData | ✅ |
| 数据库 | executeSQL, query, insert, update, createTable, getTables | ✅ |
| 邮件 | sendEmail, sendTextEmail, sendHtmlEmail | ✅ |
| 系统监控 | getCPUInfo, getMemoryInfo, monitorSystem | ✅ |
| 定时任务 | addScheduleTask, getScheduleTasks, toggleScheduleTask | ✅ |
| OCR | ocr, ocrBatch | ✅ |
| Office文档 | createPpt, createWord, createExcel, readExcel | ✅ |
共计:19个工具模块,14个分类,约50+工具函数。
5.2 桌面与终端双轨制
| 模式 | 命令 | 适用场景 |
|---|---|---|
| 桌面模式(悬浮窗) | npm run electron:desktop |
日常快速问答,桌面伴侣 |
| Dashboard模式 | npm run electron:dashboard |
复杂任务,多会话管理,工具可视化 |
| CLI模式 | npm run cli |
服务器环境,远程连接,资源受限 |
| 设置向导 | npm start |
首次配置 |
5.3 多会话管理
命令:
| 命令 | 功能 |
|---|---|
/sessions |
列出所有会话 |
/new |
创建新会话 |
/switch <id> |
切换到指定会话 |
/delete <id> |
删除会话 |
/rename <name> |
重命名当前会话 |
压缩策略:
- 触发条件:150轮 或 100K token
- 保留最近10轮,之前的生成摘要归档
- 归档文件保留最近3个
5.4 安全机制全景
| 安全层 | 实现 | 状态 |
|---|---|---|
| 代码沙箱 | isolated-vm进程级隔离 + 原生vm降级 | ✅ |
| Git安全 | execFile + 子命令白名单 + 参数验证 + cwd验证 | ✅ |
| 危险操作确认 | AWAITING_CONFIRMATION状态 + 用户手动确认 | ✅ |
| 配置安全 | 敏感信息存.env,config.json自动过滤 | ✅ |
| 工作区隔离 | 路径验证(path.isAbsolute直接拼接) | ⚠️ 待修复 |
| 跨平台路径 | os.homedir() + path.sep | ✅ |
5.5 可观测性
| 模块 | 功能 |
|---|---|
tracing.js |
LLM调用追踪、工具执行追踪、状态转换追踪、错误追踪 |
logger.js |
DEBUG/INFO/WARN/ERROR分级日志 |
retry.js |
熔断器(5次失败触发,60秒恢复)+ 指数退避重试 |
六、核心技术决策清单
| 决策点 | 选择 | 替代方案 | 选择理由 |
|---|---|---|---|
| 编程语言 | Node.js | Python/Go | 适合文件操作和命令行工具,生态成熟 |
| 工具调用协议 | 纯文本标记 | Function Calling | 跨模型兼容,调试方便 |
| 沙箱方案 | isolated-vm | vm2/原生vm | 更强隔离,进程级安全 |
| 桌面框架 | Electron | Tauri/React Native | 成熟稳定,Web技术栈 |
| 进程通信 | WebSocket | IPC/HTTP | 双向实时通信,适合流式输出 |
| 配置存储 | JSON + .env | 纯JSON/纯环境变量 | 兼顾可读性和安全性 |
| 会话存储 | JSON文件 | SQLite/内存 | 简单够用,无需额外依赖 |
| 日志系统 | 自定义分级日志 | winston/pino | 轻量,满足需求 |
| 测试框架 | Jest | Mocha/Vitest | ES Module支持好,生态成熟 |
七、未来方向
短期(v2.4)
| 方向 | 描述 | 优先级 |
|---|---|---|
| 路径安全加固 | 实现secureResolvePath防止越权 | P0 |
| 跨平台系统工具 | system.js和monitor.js补充Linux/macOS支持 | P1 |
| 搜索API抽象 | 解除对Moark格式的强依赖 | P1 |
中期(v3.0)
| 方向 | 描述 |
|---|---|
| 多智能体协作 | 多个Agent分工协作,完成复杂任务 |
| 插件市场 | 社区贡献独立工具包,按需安装 |
| 向量记忆 | 引入向量数据库(如Chroma),实现语义搜索 |
| RAG增强 | 结合本地文档,实现知识库问答 |
长期
| 方向 | 描述 |
|---|---|
| 语音交互 | 集成语音识别和合成,实现对话式交互 |
| 多模态理解 | 支持图像、音频、视频等多模态输入 |
| 跨设备同步 | 多台设备之间的会话和记忆同步 |
八、开源共建:邀请你一起参与
CogitoAgent采用 Apache 2.0 许可证开源。它的成长离不开社区的参与。
你可以做什么?
| 角色 | 行动 |
|---|---|
| 用户 | ⭐ Star收藏,下载体验,提Issue反馈 |
| 开发者 | 🍴 Fork仓库,提交PR修复bug或新增功能 |
| 技术博主 | 📝 写文章分享,引用本项目 |
| 产品经理 | 💡 提建议,讨论产品方向 |
| 设计师 | 🎨 为桌面界面提供设计改进 |
如何开始贡献?
- 阅读文档 :
README.md和src/agent/tools/TOOL_DEVELOPMENT.md - 找一个方向 :
- 修复已知问题(路径安全、跨平台)
- 添加新工具(按照TOOL_DEVELOPMENT.md的流程)
- 改进界面(Electron桌面/仪表盘)
- 补充测试用例
- 提交PR:Fork → 开发 → 测试 → Pull Request
不需要会写代码也能参与
- 写一篇使用体验文章
- 翻译文档
- 在社区推荐项目
- 提Issue反馈使用中的问题
九、结语
从v1.0到v2.3,CogitoAgent走过了一条从"功能堆积"到"工程化设计"、从"终端工具"到"桌面应用"、从"个人项目"到"开源生态"的演进之路。
它不是一个完美的项目------有已知的安全隐患,有平台限制,有未覆盖的测试。但它用一次次迭代证明了一件事:
一个由个人开发者构建的本地AI智能体,可以做到功能完备、架构清晰、可扩展、可维护。
这个专栏的十一篇文章,记录了这条路上的每一个关键节点。希望它们能为你构建自己的AI Agent提供参考和启发。
一个人可以起头,但一群人能把它推得更远。欢迎你加入。
开源仓库:
⭐ 你的 Star 是项目前进的动力