xinli/RAG-API-EXAMPLES.md
2025-12-19 14:03:43 +08:00

909 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# RAG知识库系统 - API使用示例
## 📡 基础信息
**Base URL**: `http://localhost:8080`
**认证方式**: Bearer Token (通过登录获取)
**Content-Type**: `application/json``multipart/form-data`
## 🔐 认证
所有API请求都需要在Header中携带Token
```javascript
headers: {
'Authorization': 'Bearer ' + token
}
```
## 📚 知识库管理API
### 1. 上传文档
**接口**: `POST /psychology/knowledge/upload`
**Content-Type**: `multipart/form-data`
**参数**:
- `file`: 文件对象(必填)
- `category`: 分类(可选,默认"综合心理学"
**JavaScript示例**:
```javascript
// 使用FormData上传
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('category', '人格心理学');
fetch('http://localhost:8080/psychology/knowledge/upload', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token
},
body: formData
})
.then(response => response.json())
.then(data => {
console.log('上传成功:', data);
// data.data.doc_id - 文档ID
// data.data.filename - 文件名
// data.data.chunks - 分块数量
})
.catch(error => console.error('上传失败:', error));
```
**Vue.js示例**:
```vue
<template>
<el-upload
action="/psychology/knowledge/upload"
:headers="uploadHeaders"
:data="uploadData"
:on-success="handleSuccess"
:before-upload="beforeUpload">
<el-button type="primary">上传文档</el-button>
</el-upload>
</template>
<script>
export default {
data() {
return {
uploadHeaders: {
'Authorization': 'Bearer ' + this.$store.state.token
},
uploadData: {
category: '人格心理学'
}
}
},
methods: {
beforeUpload(file) {
const isValidType = ['application/pdf', 'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'text/plain'].includes(file.type);
const isLt50M = file.size / 1024 / 1024 < 50;
if (!isValidType) {
this.$message.error('只支持PDF、Word、TXT格式');
return false;
}
if (!isLt50M) {
this.$message.error('文件大小不能超过50MB');
return false;
}
return true;
},
handleSuccess(response) {
if (response.code === 200) {
this.$message.success('上传成功');
this.loadDocumentList(); // 刷新列表
} else {
this.$message.error(response.msg);
}
}
}
}
</script>
```
**响应示例**:
```json
{
"code": 200,
"msg": "文档上传成功",
"data": {
"doc_id": "doc_1734598234567",
"filename": "心理学教材.pdf",
"category": "人格心理学",
"file_size": 2048576,
"chunks": 15,
"vectors": 15,
"upload_time": "2025-12-19 10:30:45"
}
}
```
### 2. 获取文档列表
**接口**: `GET /psychology/knowledge/list`
**参数**:
- `pageNum`: 页码默认1
- `pageSize`: 每页数量默认10
- `category`: 分类过滤(可选)
- `filename`: 文件名搜索(可选)
**JavaScript示例**:
```javascript
fetch('http://localhost:8080/psychology/knowledge/list?pageNum=1&pageSize=10', {
headers: {
'Authorization': 'Bearer ' + token
}
})
.then(response => response.json())
.then(data => {
console.log('文档列表:', data.rows);
console.log('总数:', data.total);
});
```
**Vue.js示例**:
```vue
<template>
<div>
<!-- 搜索栏 -->
<el-form :inline="true">
<el-form-item label="分类">
<el-select v-model="queryParams.category" clearable>
<el-option label="全部" value=""></el-option>
<el-option label="人格心理学" value="人格心理学"></el-option>
<el-option label="认知心理学" value="认知心理学"></el-option>
<el-option label="临床心理学" value="临床心理学"></el-option>
</el-select>
</el-form-item>
<el-form-item label="文件名">
<el-input v-model="queryParams.filename" placeholder="请输入文件名"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="loadDocumentList">搜索</el-button>
</el-form-item>
</el-form>
<!-- 文档列表 -->
<el-table :data="documentList" border>
<el-table-column prop="filename" label="文件名" width="200"></el-table-column>
<el-table-column prop="category" label="分类" width="120"></el-table-column>
<el-table-column prop="fileSize" label="大小" width="100">
<template slot-scope="scope">
{{ formatFileSize(scope.row.fileSize) }}
</template>
</el-table-column>
<el-table-column prop="chunkCount" label="分块数" width="100"></el-table-column>
<el-table-column prop="uploadTime" label="上传时间" width="180"></el-table-column>
<el-table-column label="操作" width="150">
<template slot-scope="scope">
<el-button size="mini" @click="viewDocument(scope.row)">查看</el-button>
<el-button size="mini" type="danger" @click="deleteDocument(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="queryParams.pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size="queryParams.pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
</div>
</template>
<script>
import { listKnowledge, deleteKnowledge } from '@/api/psychology/knowledge';
export default {
data() {
return {
documentList: [],
total: 0,
queryParams: {
pageNum: 1,
pageSize: 10,
category: '',
filename: ''
}
}
},
created() {
this.loadDocumentList();
},
methods: {
loadDocumentList() {
listKnowledge(this.queryParams).then(response => {
this.documentList = response.rows;
this.total = response.total;
});
},
handleSizeChange(val) {
this.queryParams.pageSize = val;
this.loadDocumentList();
},
handleCurrentChange(val) {
this.queryParams.pageNum = val;
this.loadDocumentList();
},
formatFileSize(bytes) {
if (bytes < 1024) return bytes + ' B';
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';
return (bytes / 1024 / 1024).toFixed(2) + ' MB';
},
deleteDocument(row) {
this.$confirm('确定删除该文档吗?', '提示', {
type: 'warning'
}).then(() => {
deleteKnowledge(row.docId).then(() => {
this.$message.success('删除成功');
this.loadDocumentList();
});
});
}
}
}
</script>
```
**响应示例**:
```json
{
"code": 200,
"msg": "查询成功",
"rows": [
{
"docId": "doc_1734598234567",
"filename": "心理学教材.pdf",
"category": "人格心理学",
"fileSize": 2048576,
"chunkCount": 15,
"uploadTime": "2025-12-19 10:30:45"
}
],
"total": 1
}
```
### 3. 获取文档详情
**接口**: `GET /psychology/knowledge/{id}`
**JavaScript示例**:
```javascript
const docId = 'doc_1734598234567';
fetch(`http://localhost:8080/psychology/knowledge/${docId}`, {
headers: {
'Authorization': 'Bearer ' + token
}
})
.then(response => response.json())
.then(data => {
console.log('文档详情:', data.data);
});
```
**响应示例**:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"docId": "doc_1734598234567",
"filename": "心理学教材.pdf",
"category": "人格心理学",
"fileSize": 2048576,
"chunkCount": 15,
"uploadTime": "2025-12-19 10:30:45",
"metadata": {
"author": "张三",
"pages": 120
}
}
}
```
### 4. 删除文档
**接口**: `DELETE /psychology/knowledge/{id}`
**JavaScript示例**:
```javascript
const docId = 'doc_1734598234567';
fetch(`http://localhost:8080/psychology/knowledge/${docId}`, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer ' + token
}
})
.then(response => response.json())
.then(data => {
if (data.code === 200) {
console.log('删除成功');
}
});
```
### 5. 搜索文档
**接口**: `POST /psychology/knowledge/search`
**参数**:
```json
{
"filename": "心理学",
"category": "人格心理学",
"pageNum": 1,
"pageSize": 10
}
```
**JavaScript示例**:
```javascript
fetch('http://localhost:8080/psychology/knowledge/search', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
},
body: JSON.stringify({
filename: '心理学',
category: '人格心理学'
})
})
.then(response => response.json())
.then(data => {
console.log('搜索结果:', data.rows);
});
```
### 6. 重建索引
**接口**: `POST /psychology/knowledge/rebuild`
**JavaScript示例**:
```javascript
fetch('http://localhost:8080/psychology/knowledge/rebuild', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token
}
})
.then(response => response.json())
.then(data => {
console.log('重建结果:', data.data);
// data.data.processedDocuments - 处理的文档数
// data.data.generatedVectors - 生成的向量数
// data.data.duration - 耗时
});
```
**响应示例**:
```json
{
"code": 200,
"msg": "索引重建成功",
"data": {
"success": true,
"processedDocuments": 10,
"generatedVectors": 150,
"failedDocuments": 0,
"duration": 45000
}
}
```
## 🤖 AI分析API
### 1. 生成综合报告
**接口**: `POST /psychology/ai/generate-report`
**参数**:
```json
{
"assessmentData": {
"questionnaire_name": "MMPI",
"scores": {
"抑郁": 65,
"焦虑": 70,
"社交退缩": 60
}
},
"userProfile": {
"user_id": "123",
"name": "张三",
"age": 30,
"gender": "男"
}
}
```
**Vue.js示例**:
```vue
<template>
<div>
<el-button type="primary" @click="generateReport" :loading="generating">
生成AI报告
</el-button>
<el-card v-if="report" class="report-card">
<div slot="header">
<span>AI生成的综合报告</span>
<el-tag type="success" style="float: right">
基于知识库生成
</el-tag>
</div>
<!-- 报告内容 -->
<div v-html="formatMarkdown(report.content)"></div>
<!-- 来源引用 -->
<el-divider>知识来源</el-divider>
<el-collapse>
<el-collapse-item
v-for="(source, index) in report.sources"
:key="index"
:title="`${source.documentName} (相似度: ${(source.score * 100).toFixed(1)}%)`">
<p>{{ source.snippet }}</p>
<el-tag size="mini">{{ source.category }}</el-tag>
</el-collapse-item>
</el-collapse>
</el-card>
</div>
</template>
<script>
import { generateReport } from '@/api/psychology/ai';
import MarkdownIt from 'markdown-it';
export default {
data() {
return {
generating: false,
report: null,
md: new MarkdownIt()
}
},
methods: {
generateReport() {
this.generating = true;
const requestData = {
assessmentData: {
questionnaire_name: 'MMPI',
scores: {
'抑郁': 65,
'焦虑': 70,
'社交退缩': 60
}
},
userProfile: {
user_id: this.userId,
name: this.userName,
age: this.userAge,
gender: this.userGender
}
};
generateReport(requestData).then(response => {
this.report = response.data;
this.$message.success('报告生成成功');
}).catch(error => {
this.$message.error('报告生成失败: ' + error.message);
}).finally(() => {
this.generating = false;
});
},
formatMarkdown(content) {
return this.md.render(content);
}
}
}
</script>
```
**响应示例**:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"content": "# 心理评估综合报告\n\n## 基本信息\n- 姓名: 张三\n- 年龄: 30岁\n...",
"sources": [
{
"documentId": "doc_123",
"documentName": "MMPI量表解读.pdf",
"category": "临床心理学",
"snippet": "抑郁量表得分在60-70之间表示...",
"score": 0.85
}
],
"generationTime": 8500,
"model": "deepseek-r1:32b"
}
}
```
### 2. 智能问答
**接口**: `POST /psychology/ai/chat`
**参数**:
```json
{
"question": "什么是MMPI量表",
"context": ""
}
```
**Vue.js示例**:
```vue
<template>
<div class="chat-container">
<!-- 消息列表 -->
<div class="message-list" ref="messageList">
<div
v-for="(msg, index) in messages"
:key="index"
:class="['message', msg.role]">
<div class="message-content">
<div v-if="msg.role === 'user'" class="user-message">
{{ msg.content }}
</div>
<div v-else class="ai-message">
<div v-html="formatMarkdown(msg.content)"></div>
<!-- 来源引用 -->
<div v-if="msg.sources && msg.sources.length > 0" class="sources">
<el-divider content-position="left">参考来源</el-divider>
<el-tag
v-for="(source, idx) in msg.sources"
:key="idx"
size="mini"
@click="viewSource(source)">
{{ source.documentName }}
</el-tag>
</div>
</div>
</div>
</div>
</div>
<!-- 输入框 -->
<div class="input-area">
<el-input
v-model="question"
placeholder="请输入您的问题..."
@keyup.enter.native="sendQuestion">
<el-button
slot="append"
icon="el-icon-s-promotion"
@click="sendQuestion"
:loading="sending">
发送
</el-button>
</el-input>
</div>
</div>
</template>
<script>
import { chat } from '@/api/psychology/ai';
import MarkdownIt from 'markdown-it';
export default {
data() {
return {
messages: [],
question: '',
sending: false,
md: new MarkdownIt()
}
},
methods: {
sendQuestion() {
if (!this.question.trim()) return;
// 添加用户消息
this.messages.push({
role: 'user',
content: this.question
});
const question = this.question;
this.question = '';
this.sending = true;
// 调用API
chat({ question, context: '' }).then(response => {
// 添加AI回复
this.messages.push({
role: 'assistant',
content: response.data.content,
sources: response.data.sources
});
// 滚动到底部
this.$nextTick(() => {
this.scrollToBottom();
});
}).catch(error => {
this.$message.error('发送失败: ' + error.message);
}).finally(() => {
this.sending = false;
});
},
formatMarkdown(content) {
return this.md.render(content);
},
scrollToBottom() {
const container = this.$refs.messageList;
container.scrollTop = container.scrollHeight;
},
viewSource(source) {
// 查看来源文档详情
this.$router.push({
path: '/psychology/knowledge/detail',
query: { id: source.documentId }
});
}
}
}
</script>
<style scoped>
.chat-container {
height: 600px;
display: flex;
flex-direction: column;
}
.message-list {
flex: 1;
overflow-y: auto;
padding: 20px;
}
.message {
margin-bottom: 20px;
}
.user-message {
background: #409EFF;
color: white;
padding: 10px 15px;
border-radius: 10px;
max-width: 70%;
margin-left: auto;
}
.ai-message {
background: #F5F7FA;
padding: 10px 15px;
border-radius: 10px;
max-width: 70%;
}
.sources {
margin-top: 10px;
}
.input-area {
padding: 20px;
border-top: 1px solid #EBEEF5;
}
</style>
```
**响应示例**:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"content": "MMPI明尼苏达多相人格测验是一种广泛使用的心理测验...",
"sources": [
{
"documentId": "doc_456",
"documentName": "心理测验学.pdf",
"snippet": "MMPI包含567个题目分为10个临床量表...",
"score": 0.92
}
],
"generationTime": 3500
}
}
```
### 3. 获取系统状态
**接口**: `GET /psychology/ai/system/status`
**JavaScript示例**:
```javascript
fetch('http://localhost:8080/psychology/ai/system/status', {
headers: {
'Authorization': 'Bearer ' + token
}
})
.then(response => response.json())
.then(data => {
console.log('系统状态:', data.data);
});
```
**响应示例**:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"ollamaConnected": true,
"chromadbConnected": true,
"currentEmbedModel": "nomic-embed-text",
"currentGenerateModel": "deepseek-r1:32b",
"knowledgeStats": {
"totalDocuments": 10,
"totalVectors": 150,
"storageSize": 20971520,
"documentsByCategory": {
"人格心理学": 3,
"认知心理学": 4,
"临床心理学": 3
}
}
}
}
```
## 🧪 测试API
### 健康检查
**接口**: `GET /psychology/rag-test/health`
**JavaScript示例**:
```javascript
fetch('http://localhost:8080/psychology/rag-test/health')
.then(response => response.json())
.then(data => {
if (data.data.overall_status === 'HEALTHY') {
console.log('系统健康');
} else {
console.error('系统异常');
}
});
```
## 📦 API封装示例
创建 `src/api/psychology/knowledge.js`:
```javascript
import request from '@/utils/request'
// 上传文档
export function uploadDocument(data) {
return request({
url: '/psychology/knowledge/upload',
method: 'post',
data: data
})
}
// 获取文档列表
export function listKnowledge(query) {
return request({
url: '/psychology/knowledge/list',
method: 'get',
params: query
})
}
// 获取文档详情
export function getKnowledge(id) {
return request({
url: '/psychology/knowledge/' + id,
method: 'get'
})
}
// 删除文档
export function deleteKnowledge(id) {
return request({
url: '/psychology/knowledge/' + id,
method: 'delete'
})
}
// 搜索文档
export function searchKnowledge(data) {
return request({
url: '/psychology/knowledge/search',
method: 'post',
data: data
})
}
// 重建索引
export function rebuildIndex() {
return request({
url: '/psychology/knowledge/rebuild',
method: 'post'
})
}
```
创建 `src/api/psychology/ai.js`:
```javascript
import request from '@/utils/request'
// 生成综合报告
export function generateReport(data) {
return request({
url: '/psychology/ai/generate-report',
method: 'post',
data: data,
timeout: 60000 // 60秒超时
})
}
// 智能问答
export function chat(data) {
return request({
url: '/psychology/ai/chat',
method: 'post',
data: data,
timeout: 30000 // 30秒超时
})
}
// 获取系统状态
export function getSystemStatus() {
return request({
url: '/psychology/ai/system/status',
method: 'get'
})
}
```
## 🎯 完整使用流程示例
```javascript
// 1. 上传文档
uploadDocument(formData)
.then(response => {
console.log('文档ID:', response.data.doc_id);
// 2. 等待处理完成后,生成报告
return generateReport({
assessmentData: { /* ... */ },
userProfile: { /* ... */ }
});
})
.then(response => {
console.log('报告内容:', response.data.content);
console.log('知识来源:', response.data.sources);
})
.catch(error => {
console.error('错误:', error);
});
```
---
**提示**: 所有API都支持跨域请求CORS前端开发时无需额外配置。