21 KiB
前端项目任务拆分文档 (TASK)
任务名称
frontend-vue3
任务依赖图
graph TD
T1[T1: 初始化项目脚手架] --> T2[T2: 配置Axios客户端]
T2 --> T3[T3: 封装模型管理API]
T2 --> T4[T4: 封装知识库API]
T2 --> T5[T5: 封装对话API]
T2 --> T6[T6: 封装Agent API]
T1 --> T7[T7: 配置路由]
T7 --> T8[T8: 创建主布局]
T3 --> T9[T9: 实现模型管理页]
T4 --> T10[T10: 实现知识库管理页]
T5 --> T11[T11: 实现对话列表页]
T5 --> T12[T12: 实现聊天页面]
T6 --> T13[T13: 实现Agent执行页]
T8 --> T9
T8 --> T10
T8 --> T11
T8 --> T12
T8 --> T13
T9 --> T14[T14: 集成测试]
T10 --> T14
T11 --> T14
T12 --> T14
T13 --> T14
T14 --> T15[T15: 文档编写]
style T1 fill:#e1f5fe
style T2 fill:#fff3e0
style T7 fill:#f3e5f5
style T8 fill:#e8f5e9
style T14 fill:#ffebee
style T15 fill:#fff9c4
原子任务列表
T1: 初始化项目脚手架
优先级: P0(阻塞) 复杂度: 低 预估工时: 30分钟
输入契约:
- 前置依赖: 无
- 输入数据: 项目根目录路径
- 环境依赖: Node.js 18+, npm/pnpm
实现内容:
- 创建
frontend/文件夹 - 使用 Vite 初始化 Vue3 项目
- 安装核心依赖:
npm create vite@latest frontend -- --template vue cd frontend npm install npm install vue-router axios element-plus @element-plus/icons-vue - 配置
vite.config.js(别名 @、端口 5173) - 创建目录结构:
src/ ├── api/ ├── components/ ├── views/ ├── router/ ├── utils/ ├── assets/ └── styles/
输出契约:
- 交付物: 可运行的 Vue3 项目骨架
- 验收标准:
npm run dev启动成功,访问 localhost:5173 显示默认页面 - 质量要求: 目录结构清晰,依赖版本锁定
后置任务: T2, T7
T2: 配置Axios客户端
优先级: P0(阻塞) 复杂度: 中 预估工时: 1小时
输入契约:
- 前置依赖: T1
- 输入数据: API Base URL (环境变量)
- 环境依赖: Axios 已安装
实现内容:
- 创建
.env.development:VITE_API_BASE_URL=http://localhost:8000/api/v1 - 创建
src/api/client.js:import axios from 'axios' import { ElMessage } from 'element-plus' const client = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, timeout: 30000 }) // 请求拦截器 client.interceptors.request.use(config => { return config }) // 响应拦截器 client.interceptors.response.use( response => response.data, error => { // 错误处理逻辑(详见设计文档) return Promise.reject(error) } ) export default client - 创建
src/utils/message.js(封装 ElMessage)
输出契约:
- 交付物: 配置完成的 Axios 实例
- 验收标准:
- 拦截器正确处理 4xx/5xx 错误
- 环境变量正确读取
- 网络错误显示提示
- 质量要求: 错误提示用户友好,支持详细错误信息
后置任务: T3, T4, T5, T6
T3: 封装模型管理API
优先级: P1 复杂度: 低 预估工时: 30分钟
输入契约:
- 前置依赖: T2
- 接口文档:
/models相关接口 - 环境依赖: Axios client
实现内容:
创建 src/api/models.js:
import client from './client'
export const modelAPI = {
list(type) {
return client.get('/models', { params: { type } })
},
create(data) {
return client.post('/models', data)
},
getById(id) {
return client.get(`/models/${id}`)
},
update(id, data) {
return client.patch(`/models/${id}`, data)
},
delete(id) {
return client.delete(`/models/${id}`)
}
}
输出契约:
- 交付物: 模型 API 封装模块
- 验收标准: 所有方法签名与设计文档一致
- 质量要求: 参数类型明确,返回 Promise
后置任务: T9
T4: 封装知识库API
优先级: P1 复杂度: 低 预估工时: 30分钟
输入契约:
- 前置依赖: T2
- 接口文档:
/kb相关接口
实现内容:
创建 src/api/kb.js:
import client from './client'
export const kbAPI = {
list() {
return client.get('/kb')
},
create(data) {
return client.post('/kb', data)
},
getById(id) {
return client.get(`/kb/${id}`)
},
delete(id) {
return client.delete(`/kb/${id}`)
},
ingest(id, data) {
return client.post(`/kb/${id}/ingest`, {
...data,
background: true // 固定为异步
})
},
query(id, data) {
return client.post(`/kb/${id}/query`, data)
},
getStatus(id) {
return client.get(`/kb/${id}/status`)
}
}
输出契约:
- 交付物: 知识库 API 封装模块
- 验收标准: 所有方法可正常调用
- 质量要求: ingest 方法固定 background=true
后置任务: T10
T5: 封装对话API
优先级: P1 复杂度: 低 预估工时: 30分钟
输入契约:
- 前置依赖: T2
- 接口文档:
/conversations相关接口
实现内容:
创建 src/api/conversations.js:
import client from './client'
export const conversationAPI = {
create(data) {
return client.post('/conversations', data)
},
getById(id) {
return client.get(`/conversations/${id}`)
},
delete(id) {
return client.delete(`/conversations/${id}`)
},
getMessages(id, params) {
return client.get(`/conversations/${id}/messages`, { params })
},
chat(id, data) {
return client.post(`/conversations/${id}/chat`, data)
}
}
输出契约:
- 交付物: 对话 API 封装模块
- 验收标准: 支持分页参数传递
- 质量要求: getMessages 方法正确处理 limit/offset
后置任务: T11, T12
T6: 封装Agent API
优先级: P1 复杂度: 低 预估工时: 20分钟
输入契约:
- 前置依赖: T2
- 接口文档:
/agent相关接口
实现内容:
创建 src/api/agent.js:
import client from './client'
export const agentAPI = {
execute(data) {
return client.post('/agent/execute', data)
},
getLogs(agentId, params) {
return client.get(`/agent/logs/${agentId}`, { params })
}
}
输出契约:
- 交付物: Agent API 封装模块
- 验收标准: 方法可正常调用
- 质量要求: 参数传递正确
后置任务: T13
T7: 配置路由
优先级: P0(阻塞) 复杂度: 低 预估工时: 30分钟
输入契约:
- 前置依赖: T1
- 路由设计: 参考设计文档
实现内容:
- 创建
src/router/index.js:import { createRouter, createWebHistory } from 'vue-router' const routes = [ { path: '/', redirect: '/models' }, { path: '/models', name: 'Models', component: () => import('@/views/Models.vue') }, { path: '/knowledge-base', name: 'KnowledgeBase', component: () => import('@/views/KnowledgeBase.vue') }, { path: '/conversations', name: 'Conversations', component: () => import('@/views/Conversations.vue') }, { path: '/conversations/:id/chat', name: 'Chat', component: () => import('@/views/Chat.vue'), props: true }, { path: '/agent', name: 'Agent', component: () => import('@/views/Agent.vue') } ] export default createRouter({ history: createWebHistory(), routes }) - 在
main.js中注册路由 - 在
App.vue中添加<router-view />
输出契约:
- 交付物: 路由配置文件
- 验收标准: 路由可正常跳转(临时创建空白页面组件)
- 质量要求: 懒加载配置正确,props 传递配置正确
后置任务: T8
T8: 创建主布局
优先级: P0(阻塞) 复杂度: 中 预估工时: 1小时
输入契约:
- 前置依赖: T7
- 设计稿: 参考设计文档布局
实现内容:
- 修改
App.vue:<template> <el-container style="height: 100vh"> <el-aside width="200px"> <el-menu :default-active="$route.path" router> <el-menu-item index="/models"> <el-icon><Setting /></el-icon> <span>模型管理</span> </el-menu-item> <el-menu-item index="/knowledge-base"> <el-icon><Document /></el-icon> <span>知识库</span> </el-menu-item> <el-menu-item index="/conversations"> <el-icon><ChatDotRound /></el-icon> <span>对话</span> </el-menu-item> <el-menu-item index="/agent"> <el-icon><Tools /></el-icon> <span>Agent</span> </el-menu-item> </el-menu> </el-aside> <el-main> <router-view /> </el-main> </el-container> </template> - 在
main.js中引入 Element Plus 样式 - 创建全局样式
src/styles/global.css
输出契约:
- 交付物: 主布局组件
- 验收标准:
- 左侧菜单可正常导航
- 当前路由高亮显示
- 响应式布局正常
- 质量要求: 样式简洁,图标清晰
后置任务: T9, T10, T11, T12, T13
T9: 实现模型管理页
优先级: P1 复杂度: 中 预估工时: 2小时
输入契约:
- 前置依赖: T3, T8
- API: modelAPI
- UI 组件: Element Plus
实现内容:
创建 src/views/Models.vue:
- 模型列表表格(ID, 名称, 类型, 状态, 默认, 操作)
- 类型筛选(Select: 全部/LLM/Embedding)
- 创建模型弹窗(表单:name, type, config, is_default)
- 编辑功能(复用表单,PATCH 更新)
- 删除确认(ElMessageBox)
- 加载状态(ElLoading)
核心逻辑:
const modelList = ref([])
const loading = ref(false)
const dialogVisible = ref(false)
const formData = ref({})
const typeFilter = ref('')
const fetchModels = async () => {
loading.value = true
try {
modelList.value = await modelAPI.list(typeFilter.value)
} finally {
loading.value = false
}
}
const handleCreate = async () => {
await formRef.value.validate()
await modelAPI.create(formData.value)
ElMessage.success('创建成功')
dialogVisible.value = false
fetchModels()
}
const handleDelete = async (id) => {
await ElMessageBox.confirm('确认删除?')
await modelAPI.delete(id)
ElMessage.success('删除成功')
fetchModels()
}
输出契约:
- 交付物: 模型管理页面组件
- 验收标准:
- CRUD 操作全部可用
- 表单验证正确
- 错误提示显示
- 质量要求: 用户体验流畅,代码结构清晰
后置任务: T14
T10: 实现知识库管理页
优先级: P1 复杂度: 高 预估工时: 3小时
输入契约:
- 前置依赖: T4, T8
- API: kbAPI, modelAPI(获取 embedding 列表)
实现内容:
创建 src/views/KnowledgeBase.vue:
- 知识库列表(ID, 名称, 描述, 文档数, 操作)
- 创建知识库表单
- 文档摄取弹窗:
- 动态添加/删除文档行
- 每行:title, content (textarea), source, metadata (JSON)
- Embedding 模型选择(从模型列表获取 type=embedding)
- 提交后显示成功提示(不追踪状态)
- 查询弹窗:
- 查询文本输入
- k 值选择(1-10)
- Embedding 模型选择
- 结果展示(卡片形式,显示 content + score)
- 状态查看(显示文档数、索引状态)
- 删除知识库
核心逻辑:
const kbList = ref([])
const documents = ref([{ title: '', content: '', source: '', metadata: {} }])
const embeddingModels = ref([])
const queryResults = ref([])
const addDocument = () => {
documents.value.push({ title: '', content: '', source: '', metadata: {} })
}
const handleIngest = async () => {
await kbAPI.ingest(currentKbId.value, {
documents: documents.value,
embedding_name: selectedEmbedding.value
})
ElMessage.success('文档摄取任务已提交')
ingestDialogVisible.value = false
}
const handleQuery = async () => {
queryResults.value = await kbAPI.query(currentKbId.value, {
query: queryForm.value.query,
k: queryForm.value.k,
embedding_name: selectedEmbedding.value
})
}
输出契约:
- 交付物: 知识库管理页面组件
- 验收标准:
- 可动态添加多个文档
- 摄取提交成功显示提示
- 查询返回结果正确展示
- 状态信息准确显示
- 质量要求: 表单复杂但易用,查询结果清晰
后置任务: T14
T11: 实现对话列表页
优先级: P1 复杂度: 低 预估工时: 1小时
输入契约:
- 前置依赖: T5, T8
- API: conversationAPI
实现内容:
创建 src/views/Conversations.vue:
- 会话列表表格(ID, 标题, 用户ID, 创建时间, 操作)
- 创建会话表单(user_id, title)
- "进入聊天"按钮(跳转到
/conversations/:id/chat) - 删除会话(确认弹窗)
核心逻辑:
const conversationList = ref([])
const fetchConversations = async () => {
conversationList.value = await conversationAPI.list()
}
const handleCreate = async () => {
const newConv = await conversationAPI.create(formData.value)
ElMessage.success('创建成功')
fetchConversations()
// 可选:自动跳转到聊天页
router.push(`/conversations/${newConv.id}/chat`)
}
const enterChat = (id) => {
router.push(`/conversations/${id}/chat`)
}
输出契约:
- 交付物: 对话列表页面组件
- 验收标准:
- 列表正确展示
- 创建会话成功
- 跳转聊天页正常
- 质量要求: 交互简洁明了
后置任务: T14
T12: 实现聊天页面
优先级: P1 复杂度: 高 预估工时: 3小时
输入契约:
- 前置依赖: T5, T8
- API: conversationAPI, kbAPI, modelAPI
- 路由参数: conversation_id
实现内容:
创建 src/views/Chat.vue:
- 顶部配置栏:
- RAG 开关(Switch)
- 知识库选择(显示在 RAG 启用时)
- LLM 选择
- 消息区域:
- 消息列表(用户/助手气泡)
- 显示来源信息(sources)
- "加载更多"按钮(分页)
- 自动滚动到底部
- 输入区域:
- 文本输入框(支持 Enter 发送)
- 发送按钮
- 分页加载逻辑:
- 初始 limit=50, offset=0
- 点击"加载更多" offset+=50
核心逻辑:
const conversationId = ref(route.params.id)
const messages = ref([])
const inputText = ref('')
const useRag = ref(true)
const selectedKbId = ref(null)
const selectedLlm = ref(null)
const pagination = ref({ limit: 50, offset: 0, hasMore: true })
const loadMessages = async (loadMore = false) => {
const params = {
limit: pagination.value.limit,
offset: loadMore ? pagination.value.offset : 0
}
const newMessages = await conversationAPI.getMessages(conversationId.value, params)
if (loadMore) {
messages.value = [...newMessages, ...messages.value]
pagination.value.offset += pagination.value.limit
} else {
messages.value = newMessages
}
pagination.value.hasMore = newMessages.length === pagination.value.limit
}
const sendMessage = async () => {
const userMessage = { role: 'user', content: inputText.value }
messages.value.push(userMessage)
const response = await conversationAPI.chat(conversationId.value, {
user_input: inputText.value,
kb_id: useRag.value ? selectedKbId.value : null,
llm_name: selectedLlm.value,
use_rag: useRag.value
})
messages.value.push(response)
inputText.value = ''
scrollToBottom()
}
const scrollToBottom = () => {
nextTick(() => {
messageArea.value.scrollTop = messageArea.value.scrollHeight
})
}
输出契约:
- 交付物: 聊天页面组件
- 验收标准:
- 消息正确展示(用户/助手区分)
- 分页加载正常
- RAG 切换生效
- 来源信息显示
- 自动滚动到底部
- 质量要求: 聊天体验流畅,UI 友好
后置任务: T14
T13: 实现Agent执行页
优先级: P1 复杂度: 中 预估工时: 2小时
输入契约:
- 前置依赖: T6, T8
- API: agentAPI, kbAPI, modelAPI
实现内容:
创建 src/views/Agent.vue:
- 任务输入区:
- 任务描述(Textarea)
- 知识库选择(可选)
- LLM 选择
- 执行按钮
- 结果展示区:
- 执行状态(成功/失败)
- 输出结果(Card 显示)
- Agent ID 展示
- 日志展示区(自动加载):
- 工具调用日志表格
- 列:工具名称、输入、输出、时间
- 支持展开查看详细 JSON
核心逻辑:
const taskInput = ref('')
const selectedKbId = ref(null)
const selectedLlm = ref(null)
const executionResult = ref(null)
const toolCallLogs = ref([])
const executing = ref(false)
const handleExecute = async () => {
executing.value = true
try {
const result = await agentAPI.execute({
task: taskInput.value,
kb_id: selectedKbId.value,
llm_name: selectedLlm.value
})
executionResult.value = result
// 自动加载日志
if (result.agent_id) {
const logs = await agentAPI.getLogs(result.agent_id)
toolCallLogs.value = logs.tool_calls
}
} finally {
executing.value = false
}
}
输出契约:
- 交付物: Agent 执行页面组件
- 验收标准:
- 任务执行成功
- 结果正确展示
- 日志自动加载并显示
- 加载状态显示
- 质量要求: 日志信息清晰,JSON 展示友好
后置任务: T14
T14: 集成测试
优先级: P0 复杂度: 中 预估工时: 2小时
输入契约:
- 前置依赖: T9, T10, T11, T12, T13
- 环境依赖: 后端服务运行在 localhost:8000
实现内容:
-
功能测试:
- 创建 LLM 模型配置
- 创建 Embedding 模型配置
- 创建知识库
- 摄取测试文档
- 查询知识库
- 创建会话
- 发送消息(启用/禁用 RAG)
- 执行 Agent 任务
- 查看 Agent 日志
-
边界测试:
- 表单验证(空值、格式错误)
- 网络错误处理(关闭后端)
- 404 错误(不存在的 ID)
- 分页边界(offset 超出范围)
-
用户体验测试:
- Loading 状态显示
- 成功/失败提示
- 路由跳转流畅
- 响应式布局
测试清单:
- 模型管理所有操作
- 知识库所有操作
- 对话所有操作
- Agent 执行和日志
- 错误场景处理
- 用户体验验证
输出契约:
- 交付物: 测试报告(记录在 ACCEPTANCE 文档)
- 验收标准: 所有核心流程通过
- 质量要求: 发现的问题及时修复
后置任务: T15
T15: 文档编写
优先级: P1 复杂度: 低 预估工时: 1小时
输入契约:
- 前置依赖: T14
- 项目信息: package.json, 环境配置
实现内容:
-
创建
frontend/README.md:# LangChain Learning Kit - 前端 ## 技术栈 - Vue 3 + Vite - Element Plus - Axios + Vue Router ## 环境要求 - Node.js 18+ - npm 9+ ## 快速开始 \`\`\`bash # 安装依赖 npm install # 启动开发服务器 npm run dev # 构建生产包 npm run build \`\`\` ## 环境配置 创建 `.env.development`: \`\`\` VITE_API_BASE_URL=http://localhost:8000/api/v1 \`\`\` ## 功能说明 - 模型管理:/models - 知识库:/knowledge-base - 对话:/conversations - Agent:/agent ## 注意事项 - 确保后端服务运行在 localhost:8000 - 浏览器访问 http://localhost:5173 -
创建
.env.example:VITE_API_BASE_URL=http://localhost:8000/api/v1 -
更新
.gitignore:.env.local dist/ node_modules/
输出契约:
- 交付物: README.md, .env.example
- 验收标准: 文档清晰,新用户可按文档启动项目
- 质量要求: 说明完整,格式规范
后置任务: 无(最后任务)
任务执行顺序
第一批(并行)
- T1: 初始化项目脚手架
第二批(并行)
- T2: 配置 Axios 客户端
- T7: 配置路由
第三批(并行)
- T3: 封装模型管理 API
- T4: 封装知识库 API
- T5: 封装对话 API
- T6: 封装 Agent API
- T8: 创建主布局
第四批(并行)
- T9: 实现模型管理页
- T10: 实现知识库管理页
- T11: 实现对话列表页
- T12: 实现聊天页面
- T13: 实现 Agent 执行页
第五批(串行)
- T14: 集成测试
- T15: 文档编写
风险控制
任务风险
-
T10 复杂度高: 文档摄取多字段,可能需要更多时间
- 缓解:预留缓冲时间,优先实现核心功能
-
T12 分页逻辑: offset/limit 边界处理
- 缓解:参考设计文档,做好边界检查
-
T14 后端依赖: 需要后端服务正常运行
- 缓解:提前验证后端 API 可用性
时间风险
- 总预估工时: 约 16 小时
- 建议工期: 2-3 个工作日
- 缓冲时间: 预留 20% 用于调试和优化
任务拆分完成,等待审批。