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

20 KiB
Raw Blame History

RAG知识库系统 - API使用示例

📡 基础信息

Base URL: http://localhost:8080

认证方式: Bearer Token (通过登录获取)

Content-Type: application/jsonmultipart/form-data

🔐 认证

所有API请求都需要在Header中携带Token

headers: {
  'Authorization': 'Bearer ' + token
}

📚 知识库管理API

1. 上传文档

接口: POST /psychology/knowledge/upload

Content-Type: multipart/form-data

参数:

  • file: 文件对象(必填)
  • category: 分类(可选,默认"综合心理学"

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示例:

<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>

响应示例:

{
  "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示例:

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示例:

<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>

响应示例:

{
  "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示例:

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);
});

响应示例:

{
  "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示例:

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

参数:

{
  "filename": "心理学",
  "category": "人格心理学",
  "pageNum": 1,
  "pageSize": 10
}

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示例:

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 - 耗时
});

响应示例:

{
  "code": 200,
  "msg": "索引重建成功",
  "data": {
    "success": true,
    "processedDocuments": 10,
    "generatedVectors": 150,
    "failedDocuments": 0,
    "duration": 45000
  }
}

🤖 AI分析API

1. 生成综合报告

接口: POST /psychology/ai/generate-report

参数:

{
  "assessmentData": {
    "questionnaire_name": "MMPI",
    "scores": {
      "抑郁": 65,
      "焦虑": 70,
      "社交退缩": 60
    }
  },
  "userProfile": {
    "user_id": "123",
    "name": "张三",
    "age": 30,
    "gender": "男"
  }
}

Vue.js示例:

<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>

响应示例:

{
  "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

参数:

{
  "question": "什么是MMPI量表",
  "context": ""
}

Vue.js示例:

<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>

响应示例:

{
  "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示例:

fetch('http://localhost:8080/psychology/ai/system/status', {
  headers: {
    'Authorization': 'Bearer ' + token
  }
})
.then(response => response.json())
.then(data => {
  console.log('系统状态:', data.data);
});

响应示例:

{
  "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示例:

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:

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:

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'
  })
}

🎯 完整使用流程示例

// 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前端开发时无需额外配置。