939 lines
21 KiB
Markdown
939 lines
21 KiB
Markdown
# 前端项目任务拆分文档 (TASK)
|
||
|
||
## 任务名称
|
||
frontend-vue3
|
||
|
||
## 任务依赖图
|
||
|
||
```mermaid
|
||
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
|
||
|
||
**实现内容**:
|
||
1. 创建 `frontend/` 文件夹
|
||
2. 使用 Vite 初始化 Vue3 项目
|
||
3. 安装核心依赖:
|
||
```bash
|
||
npm create vite@latest frontend -- --template vue
|
||
cd frontend
|
||
npm install
|
||
npm install vue-router axios element-plus @element-plus/icons-vue
|
||
```
|
||
4. 配置 `vite.config.js`(别名 @、端口 5173)
|
||
5. 创建目录结构:
|
||
```
|
||
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 已安装
|
||
|
||
**实现内容**:
|
||
1. 创建 `.env.development`:
|
||
```
|
||
VITE_API_BASE_URL=http://localhost:8000/api/v1
|
||
```
|
||
2. 创建 `src/api/client.js`:
|
||
```javascript
|
||
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
|
||
```
|
||
3. 创建 `src/utils/message.js`(封装 ElMessage)
|
||
|
||
**输出契约**:
|
||
- 交付物: 配置完成的 Axios 实例
|
||
- 验收标准:
|
||
- 拦截器正确处理 4xx/5xx 错误
|
||
- 环境变量正确读取
|
||
- 网络错误显示提示
|
||
- 质量要求: 错误提示用户友好,支持详细错误信息
|
||
|
||
**后置任务**: T3, T4, T5, T6
|
||
|
||
---
|
||
|
||
### T3: 封装模型管理API
|
||
**优先级**: P1
|
||
**复杂度**: 低
|
||
**预估工时**: 30分钟
|
||
|
||
**输入契约**:
|
||
- 前置依赖: T2
|
||
- 接口文档: `/models` 相关接口
|
||
- 环境依赖: Axios client
|
||
|
||
**实现内容**:
|
||
创建 `src/api/models.js`:
|
||
```javascript
|
||
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`:
|
||
```javascript
|
||
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`:
|
||
```javascript
|
||
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`:
|
||
```javascript
|
||
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
|
||
- 路由设计: 参考设计文档
|
||
|
||
**实现内容**:
|
||
1. 创建 `src/router/index.js`:
|
||
```javascript
|
||
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
|
||
})
|
||
```
|
||
2. 在 `main.js` 中注册路由
|
||
3. 在 `App.vue` 中添加 `<router-view />`
|
||
|
||
**输出契约**:
|
||
- 交付物: 路由配置文件
|
||
- 验收标准: 路由可正常跳转(临时创建空白页面组件)
|
||
- 质量要求: 懒加载配置正确,props 传递配置正确
|
||
|
||
**后置任务**: T8
|
||
|
||
---
|
||
|
||
### T8: 创建主布局
|
||
**优先级**: P0(阻塞)
|
||
**复杂度**: 中
|
||
**预估工时**: 1小时
|
||
|
||
**输入契约**:
|
||
- 前置依赖: T7
|
||
- 设计稿: 参考设计文档布局
|
||
|
||
**实现内容**:
|
||
1. 修改 `App.vue`:
|
||
```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>
|
||
```
|
||
2. 在 `main.js` 中引入 Element Plus 样式
|
||
3. 创建全局样式 `src/styles/global.css`
|
||
|
||
**输出契约**:
|
||
- 交付物: 主布局组件
|
||
- 验收标准:
|
||
- 左侧菜单可正常导航
|
||
- 当前路由高亮显示
|
||
- 响应式布局正常
|
||
- 质量要求: 样式简洁,图标清晰
|
||
|
||
**后置任务**: T9, T10, T11, T12, T13
|
||
|
||
---
|
||
|
||
### T9: 实现模型管理页
|
||
**优先级**: P1
|
||
**复杂度**: 中
|
||
**预估工时**: 2小时
|
||
|
||
**输入契约**:
|
||
- 前置依赖: T3, T8
|
||
- API: modelAPI
|
||
- UI 组件: Element Plus
|
||
|
||
**实现内容**:
|
||
创建 `src/views/Models.vue`:
|
||
1. 模型列表表格(ID, 名称, 类型, 状态, 默认, 操作)
|
||
2. 类型筛选(Select: 全部/LLM/Embedding)
|
||
3. 创建模型弹窗(表单:name, type, config, is_default)
|
||
4. 编辑功能(复用表单,PATCH 更新)
|
||
5. 删除确认(ElMessageBox)
|
||
6. 加载状态(ElLoading)
|
||
|
||
**核心逻辑**:
|
||
```javascript
|
||
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`:
|
||
1. 知识库列表(ID, 名称, 描述, 文档数, 操作)
|
||
2. 创建知识库表单
|
||
3. **文档摄取弹窗**:
|
||
- 动态添加/删除文档行
|
||
- 每行:title, content (textarea), source, metadata (JSON)
|
||
- Embedding 模型选择(从模型列表获取 type=embedding)
|
||
- 提交后显示成功提示(不追踪状态)
|
||
4. **查询弹窗**:
|
||
- 查询文本输入
|
||
- k 值选择(1-10)
|
||
- Embedding 模型选择
|
||
- 结果展示(卡片形式,显示 content + score)
|
||
5. 状态查看(显示文档数、索引状态)
|
||
6. 删除知识库
|
||
|
||
**核心逻辑**:
|
||
```javascript
|
||
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`:
|
||
1. 会话列表表格(ID, 标题, 用户ID, 创建时间, 操作)
|
||
2. 创建会话表单(user_id, title)
|
||
3. "进入聊天"按钮(跳转到 `/conversations/:id/chat`)
|
||
4. 删除会话(确认弹窗)
|
||
|
||
**核心逻辑**:
|
||
```javascript
|
||
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`:
|
||
1. **顶部配置栏**:
|
||
- RAG 开关(Switch)
|
||
- 知识库选择(显示在 RAG 启用时)
|
||
- LLM 选择
|
||
2. **消息区域**:
|
||
- 消息列表(用户/助手气泡)
|
||
- 显示来源信息(sources)
|
||
- "加载更多"按钮(分页)
|
||
- 自动滚动到底部
|
||
3. **输入区域**:
|
||
- 文本输入框(支持 Enter 发送)
|
||
- 发送按钮
|
||
4. **分页加载逻辑**:
|
||
- 初始 limit=50, offset=0
|
||
- 点击"加载更多" offset+=50
|
||
|
||
**核心逻辑**:
|
||
```javascript
|
||
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`:
|
||
1. **任务输入区**:
|
||
- 任务描述(Textarea)
|
||
- 知识库选择(可选)
|
||
- LLM 选择
|
||
- 执行按钮
|
||
2. **结果展示区**:
|
||
- 执行状态(成功/失败)
|
||
- 输出结果(Card 显示)
|
||
- Agent ID 展示
|
||
3. **日志展示区**(自动加载):
|
||
- 工具调用日志表格
|
||
- 列:工具名称、输入、输出、时间
|
||
- 支持展开查看详细 JSON
|
||
|
||
**核心逻辑**:
|
||
```javascript
|
||
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
|
||
|
||
**实现内容**:
|
||
1. **功能测试**:
|
||
- 创建 LLM 模型配置
|
||
- 创建 Embedding 模型配置
|
||
- 创建知识库
|
||
- 摄取测试文档
|
||
- 查询知识库
|
||
- 创建会话
|
||
- 发送消息(启用/禁用 RAG)
|
||
- 执行 Agent 任务
|
||
- 查看 Agent 日志
|
||
|
||
2. **边界测试**:
|
||
- 表单验证(空值、格式错误)
|
||
- 网络错误处理(关闭后端)
|
||
- 404 错误(不存在的 ID)
|
||
- 分页边界(offset 超出范围)
|
||
|
||
3. **用户体验测试**:
|
||
- Loading 状态显示
|
||
- 成功/失败提示
|
||
- 路由跳转流畅
|
||
- 响应式布局
|
||
|
||
**测试清单**:
|
||
- [ ] 模型管理所有操作
|
||
- [ ] 知识库所有操作
|
||
- [ ] 对话所有操作
|
||
- [ ] Agent 执行和日志
|
||
- [ ] 错误场景处理
|
||
- [ ] 用户体验验证
|
||
|
||
**输出契约**:
|
||
- 交付物: 测试报告(记录在 ACCEPTANCE 文档)
|
||
- 验收标准: 所有核心流程通过
|
||
- 质量要求: 发现的问题及时修复
|
||
|
||
**后置任务**: T15
|
||
|
||
---
|
||
|
||
### T15: 文档编写
|
||
**优先级**: P1
|
||
**复杂度**: 低
|
||
**预估工时**: 1小时
|
||
|
||
**输入契约**:
|
||
- 前置依赖: T14
|
||
- 项目信息: package.json, 环境配置
|
||
|
||
**实现内容**:
|
||
1. 创建 `frontend/README.md`:
|
||
```markdown
|
||
# 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
|
||
```
|
||
|
||
2. 创建 `.env.example`:
|
||
```
|
||
VITE_API_BASE_URL=http://localhost:8000/api/v1
|
||
```
|
||
|
||
3. 更新 `.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: 文档编写
|
||
|
||
---
|
||
|
||
## 风险控制
|
||
|
||
### 任务风险
|
||
1. **T10 复杂度高**: 文档摄取多字段,可能需要更多时间
|
||
- 缓解:预留缓冲时间,优先实现核心功能
|
||
|
||
2. **T12 分页逻辑**: offset/limit 边界处理
|
||
- 缓解:参考设计文档,做好边界检查
|
||
|
||
3. **T14 后端依赖**: 需要后端服务正常运行
|
||
- 缓解:提前验证后端 API 可用性
|
||
|
||
### 时间风险
|
||
- **总预估工时**: 约 16 小时
|
||
- **建议工期**: 2-3 个工作日
|
||
- **缓冲时间**: 预留 20% 用于调试和优化
|
||
|
||
---
|
||
|
||
**任务拆分完成,等待审批。**
|