You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

4.9 KiB

会话级系统提示词覆盖

背景

当前系统提示词仅支持 Agent 级别配置(agents.systemPrompt 字段),由管理员在后台 /admin/agent-config 页面设置。所有用户使用同一 Agent 时共享相同的系统提示词,无法按会话自定义。

用户希望能在每个会话中自行传入系统提示词,无需管理员后台配置。

目标

  • 用户可在会话级别覆盖 Agent 默认系统提示词
  • 不传时回退到 Agent 默认值
  • 管理员配置的 Agent 默认提示词保留作为兜底

范围

  • 数据库:agentSessions 表新增 systemPrompt 字段
  • 后端:创建会话接口支持传入、配置接口支持更新、chat-engine 优先级调整
  • 前端:会话设置入口(编辑系统提示词)、展示当前生效的提示词
  • 匿名用户:同样支持(通过 tempToken 关联会话)

非目标

  • 用户级偏好(跨会话持久化)—— 后续迭代
  • 提示词模板库 —— 后续迭代
  • 提示词版本历史 —— 后续迭代

架构

优先级规则

会话级 systemPrompt(trim 后非空)> Agent 默认 systemPrompt

会话级为 null 或空字符串/纯空白时,回退到 Agent 默认。前端保存空内容时传 null,不区分"清空覆盖"和"未设置"——两者行为相同,都使用 Agent 默认。

数据层

agentSessions 表新增字段:

字段 类型 默认值 说明
systemPrompt text null 会话级系统提示词,null 表示用 Agent 默认

迁移命令:bun run db:generate && bun run db:migrate

后端改动

1. 创建会话接口 POST /api/agents/:agentSlug/sessions

  • index.post.ts:从 body 读取可选 systemPrompt 参数
  • createSession service:新增 systemPrompt 参数,写入数据库
  • 字符长度限制:5000 字符(与管理员配置一致)

2. 会话配置接口 PUT /api/agents/:agentSlug/sessions/:id/config

  • config.put.ts:支持 systemPrompt 字段更新
  • updateSession service:data 参数类型新增 systemPrompt?: string | null
  • 传 null 表示清除覆盖,回退 Agent 默认
  • 鉴权:现有 getSessionByIdAndUser(id, userId, tempToken) 已处理匿名用户通过 tempToken 鉴权,无需额外改动

3. Chat Engine executeChat

  • chat-engine.ts:251:修改优先级逻辑
    const systemPrompt = session.systemPrompt?.trim() || agent.systemPrompt || undefined;
    

4. 会话详情接口 GET /api/agents/:agentSlug/sessions/:id

  • index.get.ts 直接返回整个 session 对象(R.success({ session, messages })),新增 systemPrompt 字段后自动返回,无需改动该接口

前端改动

1. AgentSessionItem 类型

app/composables/useAgentSessions.ts:新增 systemPrompt: string | null 字段

2. updateSessionConfig 方法

扩展 config 参数,支持 systemPrompt?: string | null

3. 系统提示词弹窗改造

AgentSystemPromptModal.vue:从只读展示改为可编辑

  • 展示当前生效的提示词(会话级或 Agent 默认)
  • 提供编辑 textarea
  • 保存按钮调用 updateSessionConfig
  • 显示"使用 Agent 默认"提示,区分覆盖状态

4. AgentToolbar.vue

系统提示词按钮图标从 lucide:info(只读)改为 lucide:settings(可编辑),title 改为"系统提示词设置"

5. 页面层 chat/[agentSlug]/index.vue

  • systemPromptText 改为 computed:sessions.currentSession.value?.systemPrompt ?? agentSystemPrompt(会话级优先,回退 Agent 默认)
  • loadSystemPrompt 保留,用于加载 Agent 默认提示词作为兜底展示
  • 弹窗保存后更新会话数据,systemPromptText 自动响应

数据流

用户点击工具栏"系统提示词"按钮
  → 弹窗展示当前生效提示词(session.systemPrompt ?? agent.systemPrompt)
  → 用户编辑并保存
  → PUT /api/agents/:slug/sessions/:id/config { systemPrompt: "..." }
  → updateSession 写入 agentSessions.systemPrompt
  → 弹窗关闭,前端更新本地 session 数据

用户发送消息
  → POST /api/agents/:slug/sessions/:id/chat
  → executeChat 读取 session.systemPrompt
  → 优先级:session.systemPrompt?.trim() || agent.systemPrompt
  → streamText({ system: resolvedPrompt, ... })

错误处理

  • 系统提示词超过 5000 字符:返回 400 "系统提示词不能超过5000字符"(注:agents.systemPrompt 字段本身无长度限制,5000 为业务限制)
  • 未登录用户修改非自己会话:返回 403(现有 getSessionByIdAndUser 已通过 tempToken 鉴权处理)
  • 保存失败:toast 提示"保存失败"

测试

  • E2E:创建会话时传入自定义提示词 → 发送消息 → 验证回复受自定义提示词影响
  • E2E:会话中修改提示词 → 后续消息使用新提示词
  • E2E:清空提示词 → 回退到 Agent 默认
  • 单元:executeChat 优先级逻辑