第 10 章 更多业务模块扩展

📌 本章目标:了解工作台的更多业务模块,学习模块化设计思路

⭐⭐⭐ 难度:进阶 | ⏱️ 预计时间:2 小时


10.1 工作台不止聊天

前面我们重点讲了聊天、执行面板和审批,但一个完整的 Agent 工作台远不止这些。

一个企业级的 Agent 工作台通常还包括:

模块 功能 重要程度
定时任务 让 Agent 定时自动干活 ⭐⭐⭐⭐⭐
记忆管理 Agent 的知识和记忆 ⭐⭐⭐⭐
设置面板 Agent 配置、个人设置 ⭐⭐⭐⭐⭐
技能市场 给 Agent 安装新技能 ⭐⭐⭐
文件管理 Agent 可访问的文件 ⭐⭐⭐
嵌入模式 把对话嵌到其他系统里 ⭐⭐⭐

本章我们挑几个重要的模块讲一讲,了解它们的设计思路。不用每个都实现得很完整,重点是理解「为什么这么设计」。


10.2 定时任务(Cron)

什么是定时任务?

让 Agent 按照设定的时间自动执行任务,比如:

  • 每天早上 9 点巡检服务器
  • 每周一早上生成周报
  • 每小时检查一次数据备份

Cron 表达式基础

Cron 表达式是用来描述定时规则的标准格式,由 6-7 个字段组成:

bash 复制代码
秒 分 时 日 月 周 (年)

例:
0 0 9 * * *    → 每天早上 9 点
0 30 8 * * 1-5 → 周一到周五早上 8:30
0 0 * / 2 * *  → 每 2 小时

💡 小贴士:Cron 表达式对新手不友好,所以我们通常用可视化的 Cron 编辑器,让用户通过点选来设置,自动生成表达式。

定时任务的数据结构

typescript 复制代码
interface CronTask {
  id: string;
  name: string;           // 任务名称
  description: string;    // 任务描述
  agentId: number;        // 属于哪个 Agent
  cronExpression: string; // Cron 表达式
  prompt: string;         // 执行时发送给 Agent 的 prompt
  enabled: boolean;       // 是否启用
  createdAt: string;
  updatedAt: string;
  lastRunAt?: string;     // 上次执行时间
  nextRunAt?: string;     // 下次执行时间
  lastRunStatus?: 'success' | 'failed' | 'running';
}

功能模块划分

bash 复制代码
定时任务模块
├── 任务列表(侧边栏展示)
├── 创建/编辑弹窗
│   ├── Cron 可视化编辑器
│   └── Prompt 输入
├── 任务详情页
│   ├── 任务信息
│   └── 执行历史
└── 手动触发(立即执行一次)

Cron 编辑器的实现

推荐用现成的库,不用自己写:

库 说明
react-js-cron 可视化 Cron 编辑器,轻量好用
cronstrue 把 Cron 表达式转成人类可读的文字(如「每天上午 9 点」)
bash 复制代码
npm install react-js-cron cronstrue

基本用法:

tsx 复制代码
import { Cron } from 'react-js-cron';
import cronstrue from 'cronstrue/i18n/zh_CN';
import 'react-js-cron/dist/styles.css';

function CronEditor() {
  const [value, setValue] = useState('0 0 9 * * *');

  return (
    <div>
      <Cron value={value} onChange={setValue} />
      <p>执行频率:{cronstrue.toString(value)}</p>
    </div>
  );
}

CronStore 设计

typescript 复制代码
class CronStore {
  tasks: CronTask[] = [];
  loading = false;
  keyword = '';
  pendingEditTask: CronTask | null = null;

  constructor() {
    makeAutoObservable(this);
  }

  get filteredTasks(): CronTask[] {
    if (!this.keyword) return this.tasks;
    const kw = this.keyword.toLowerCase();
    return this.tasks.filter(
      t => t.name.toLowerCase().includes(kw) || t.description.toLowerCase().includes(kw)
    );
  }

  async fetchTasks(agentId: number) { /* ... */ }
  async createTask(agentId: number, data: CreateCronInput) { /* ... */ }
  async updateTask(taskId: string, data: UpdateCronInput) { /* ... */ }
  async deleteTask(taskId: string) { /* ... */ }
  async toggleTask(taskId: string, enabled: boolean) { /* ... */ }
  async triggerTask(taskId: string) { /* 立即执行一次 */ }
}

10.3 记忆管理(Memory)

什么是 Agent 记忆?

Agent 的记忆就是它「知道的事情」。有了记忆,Agent 就能:

  • 记住你的偏好(比如「我喜欢用 Markdown 格式输出」)
  • 记住你是谁、做什么工作
  • 从过去的对话中学习和积累知识

记忆的分类

类型 说明 存储位置 生命周期
短期记忆 当前对话的上下文 会话内 对话结束就没了
用户画像 关于用户的长期认知 用户级 长期保存
Agent 记忆 Agent 自身的知识和经验 Agent 级 长期保存
全局知识库 所有 Agent 共享的知识 全局 长期保存

记忆的可视化展示

记忆不只是列个表,可以做得很「科幻」:

视图 效果 适用场景
表格视图 普通的列表/表格 查看全部、管理操作
时间线视图 按时间顺序展示记忆的形成 了解记忆的演变
星座图视图 2D Canvas 上的节点和连线 展示记忆之间的关联,很有科技感

🎯 设计理念:记忆模块不仅是功能,也是产品的「科技感」来源。用户看到密密麻麻的记忆节点和连线,会觉得「这个 Agent 真的在学习和积累」。

记忆 Store 设计

typescript 复制代码
interface MemoryItem {
  id: string;
  content: string;        // 记忆内容
  source: string;        // 来源:user_input / agent_generated / imported
  category?: string;     // 分类
  tags: string[];        // 标签
  importance: number;    // 重要程度 0-1
  createdAt: string;
  updatedAt: string;
}

class MemoryStore {
  memories: MemoryItem[] = [];
  loading = false;
  viewMode: 'table' | 'timeline' | 'constellation' = 'table';
  selectedCategory: string | null = null;

  constructor() {
    makeAutoObservable(this);
  }

  async fetchMemories(agentId: number) { /* ... */ }
  async addMemory(agentId: number, content: string) { /* ... */ }
  async updateMemory(id: string, content: string) { /* ... */ }
  async deleteMemory(id: string) { /* ... */ }
}

10.4 设置面板

设置面板有什么?

设置面板是所有配置的入口,通常用 Tab 切换不同的设置分类:

bash 复制代码
设置面板
├── 个人资料
│   ├── 用户信息
│   ├── 显示设置(主题、语言)
│   └── 通知设置
├── Agent 设置
│   ├── 基本信息(名称、描述、头像)
│   ├── 忙时策略(忙的时候怎么处理新请求)
│   ├── 安全模式(权限等级)
│   ├── 技能管理(安装/卸载/启用/停用)
│   ├── 工具集配置
│   └── 文件权限
├── Token 管理
│   ├── Token 列表
│   ├── 创建新 Token
│   └── 删除 Token
└── 关于
    ├── 版本信息
    └── 更新日志

Token 管理是什么?

Token 是其他系统调用你的 Agent 时的「钥匙」。

bash 复制代码
其他系统  ──Token──▶  你的 Agent
(比如工单系统)         (验证身份)

Token 管理的典型功能:

  • 生成新 Token(给它起个名字,知道是给谁用的)
  • 查看 Token 列表
  • 删除 Token(吊销权限)
  • Token 显示用掩码,只在创建时显示一次明文

忙时策略

当 Agent 正在处理一个任务,又来新任务了怎么办?

策略 说明
排队 新任务排队等,一个一个来
并行 同时处理多个任务(消耗更多资源)
拒绝 忙的时候直接拒绝新任务
转交 转交给另一个空闲的 Agent

10.5 技能(Skill)

什么是技能?

技能是 Agent 能力的扩展包。就像手机的 App 一样,安装不同的技能,Agent 就能干不同的事。

比如:

  • 「数据库查询」技能:让 Agent 能查数据库
  • 「邮件发送」技能:让 Agent 能发邮件
  • 「Excel 处理」技能:让 Agent 能操作 Excel 文件

技能和工具的区别

概念 说明 粒度
工具(Tool) 单个可调用的能力,如 exec 执行命令 小
技能(Skill) 一组相关工具 + 使用说明 + 配置,如「数据库技能」 大

一个技能可以包含多个工具和一组使用说明(告诉 Agent 什么时候用、怎么用)。

技能市场

用户可以从「技能市场」浏览和安装新技能:

bash 复制代码
技能市场
├── 分类浏览(办公/运维/开发/...)
├── 搜索
├── 技能详情页
│   ├── 介绍
│   ├── 功能说明
│   └── 安装按钮
└── 已安装管理
    ├── 启用/停用
    └── 卸载

10.6 嵌入模式(Chat Embed)

什么是嵌入模式?

把 Agent 对话能力作为一个组件,嵌入到其他系统里。比如:

  • 工单系统里,每个工单旁边有个 AI 助手
  • 运维平台里,嵌一个 AI 运维助手
  • 办公系统里,嵌一个 AI 办公助手

和主工作台的区别

对比项 主工作台 嵌入模式
布局 三栏完整布局 只有聊天窗口
Agent 列表 有 没有(通常固定一个 Agent)
侧边栏 有 没有
执行面板 有 可选
数据来源 普通 WS 通道 工单/业务 WS 通道
通信方式 直接和后端通信 通过宿主页面 postMessage

嵌入模式的通信

嵌入页面和宿主页面通过 postMessage 通信:

typescript 复制代码
// 嵌入页面发给宿主
window.parent.postMessage({
  type: 'action_result',
  data: { actionId: 'xxx', result: 'approved' }
}, '*');

// 接收宿主的消息
window.addEventListener('message', (event) => {
  if (event.data.type === 'init_work_order') {
    // 初始化工单上下文
  }
});

10.7 模块化设计的心得

学了这么多模块,你可能会问:怎么保证这么多模块不混乱?

分享几个关键原则:

原则一:每个模块自己管自己

bash 复制代码
好的结构:                    不好的结构:
workbench/                    workbench/
├── components/               ├── components/
│   ├── Sidebar/              │   ├── Sidebar.tsx
│   ├── Conversation/         │   ├── Conversation.tsx
│   ├── ExecPanel/            │   ├── ExecPanel.tsx
│   └── Settings/             │   └── Settings.tsx
├── store/                    ├── store/
│   ├── AgentStore.ts         │   └── index.ts  (什么都往里塞)
│   ├── ConversationStore.ts
│   └── ...
└── services/
    ├── gateway/
    └── ...

每个模块有自己的组件、自己的样式、自己的逻辑,想删就删、想改就改,不会牵连其他模块。

原则二:跨模块的事放根 Store

模块之间需要协调怎么办?比如「切换 Agent」会影响:

  • AgentStore(选中状态)
  • ConversationStore(会话列表)
  • SessionStore(消息列表)
  • ExecutionStore(执行日志)

这种跨模块的逻辑,放在根 Store 里统一处理。

原则三:数据流从上往下

bash 复制代码
根 Store → 子 Store → 组件 → 子组件

数据和方法的调用方向永远是从上往下。子模块不要直接调用根 Store 的方法,根 Store 来协调子模块。

💡 类比:就像公司管理,CEO 协调各部门经理,部门经理管自己部门的人。部门经理不直接指挥别的部门的人,有事找 CEO 协调。


10.8 本章小结

你学到了什么?

  1. ✅ 了解了定时任务模块的设计(Cron 表达式、编辑器、任务管理)
  2. ✅ 了解了记忆管理模块(记忆分类、多种可视化视图)
  3. ✅ 了解了设置面板的结构(个人设置、Agent 设置、Token 管理)
  4. ✅ 了解了技能的概念(Agent 能力的扩展包)
  5. ✅ 了解了嵌入模式(把对话能力嵌入其他系统)
  6. ✅ 学到了模块化设计的三个核心原则

模块全景图

bash 复制代码
AI Agent 工作台
├── 聊天会话(核心)
│   ├── 消息列表
│   ├── 输入框
│   └── 审批
├── 执行面板
│   ├── 输出
│   ├── 文件
│   └── 变更
├── 定时任务
├── 记忆管理
├── 设置面板
├── 技能管理
└── 嵌入模式

✏️ 动手练习

  1. 选一个你最感兴趣的模块(定时任务 / 记忆管理 / 设置面板),把它的 Store 和基础 UI 实现一下
  2. 给你的项目加一个设置页面,用 Tabs 切换不同的设置分类
  3. 思考一下:如果要加一个「消息搜索」功能,你会怎么设计?放在哪个模块?数据从哪来?
  4. 挑战:实现一个简单的 Cron 编辑器(可以用 react-js-cron)

相关推荐
superj1 分钟前
答题卡智能批改系统:选择题 OMR 秒出,主观题交给一次大模型调用
人工智能
海螺_AIHCC2 分钟前
AGENTS.md 别手写,让它自己从仓库里长出来
人工智能
用户24101505702085 分钟前
给 100 块的 AI 玩具写了一套英语启蒙 App:100 个词、看图选词、开口打分
人工智能
修炼的dance6 分钟前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M12 分钟前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写14 分钟前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李16 分钟前
一个复杂的动态表单是如何实现的
前端·设计模式
黄啊码19 分钟前
从 0 到 1 做 FDE:如何获客、成交、交付?百万级 AI 项目实战复盘
人工智能
玩美数据29 分钟前
海外市场数据服务常用术语与名词解释权威指南
大数据·人工智能
陈随易30 分钟前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员