设计知识库前端页面并对接接口
2024年5月15日...大约 3 分钟
一、介绍
基于前一章节的内容,实现在前端页面与大模型对话和自定义知识库的上传和使用。
二、技术方案
搜索一个合适的喜欢的AI对话页面,然后截取图片上传到 AI 工具,并告知基于这样的 UI 效果完成页面的实现。
之后在告诉 AI 处理接口的对接。当然也可以把接口一起交给 AI 工具进行处理。
三、具体实现
1. 聊天页面
根据如描述说明,帮我编写一款简单的AI对话页面。
1. 请编写html、js、tailwindcss UI 效果。不要写react、vue。
2. 点击新建聊天,会创建一个新的加入左侧的聊天列表
3. 聊天列表可以点击展开选择。
4. 选择的聊天,在对话列表中,可以点击删除或者重命名。
5. 输入内容,点击发送按钮和使用快捷键,调用服务端流式请求接口,前端渲染展示。
6. 以html、js代码方式实现,css样式使用 tailwind 编写。
7. 通过 const eventSource = new EventSource(apiUrl); 调用api接口。
8. 从 result.output.content 获取,应答的文本展示。注意 content 可能为空。
9. 从 result.metadata.finishReason = stop 获取,结束标识。
10. 支持多种模型切,将模型切换的按钮设置在消息对话框里。
11. 注意整体样式的简洁美观。
流式GET请求接口,由 SpringBoot Spring AI 框架实现,如下;
/**
* http://localhost:7080/api/v1/ollama/generate_stream?model=deepseek-r1:1.5b&message=你是?
*/
@GetMapping("generate_stream")
@Override
public Flux<ChatResponse> generateStream(@RequestParam String model, @RequestParam String message) {
return chatModel.stream(new Prompt(message, OllamaOptions.builder().model(model).build()));
}
流式GET应答数据,数组中的一条对象;
{
"result": {
"metadata": {
"finishReason": null,
"contentFilters": [],
"empty": true
},
"output": {
"messageType": "ASSISTANT",
"metadata": {
"messageType": "ASSISTANT"
},
"toolCalls": [],
"media": [],
"text": "1"
}
},
"results": [
{
"metadata": {
"finishReason": null,
"contentFilters": [],
"empty": true
},
"output": {
"messageType": "ASSISTANT",
"metadata": {
"messageType": "ASSISTANT"
},
"toolCalls": [],
"media": [],
"text": "1"
}
}
],
"metadata": {
"id": "",
"model": "deepseek-r1:1.5b",
"rateLimit": {
"tokensLimit": 0,
"tokensReset": "PT0S",
"requestsLimit": 0,
"tokensRemaining": 0,
"requestsReset": "PT0S",
"requestsRemaining": 0
},
"usage": {
"promptTokens": 0,
"completionTokens": 0,
"totalTokens": 0
},
"promptMetadata": [],
"empty": false
}
}

上图html页面的编写,使https://v0.dev/ 的效果是不错的。如果效果达不到预期可以反复提问完善页面。
相关的生成的代码,已经放到工程 docs/dev-ops,nginx、html 下。
注意如果 Spring AI 版本不同,不一定都有 STOP 标识,也可以找其他标识。如 stop 、NULL、""。
2. 上传知识库
@RestController()
@CrossOrigin("*")
@RequestMapping("/api/v1/ollama/")
public class OllamaController implements IAiService {
@PostMapping(value = "file/upload", headers = "content-type=multipart/form-data")
@Override
public Response<String> uploadFile(@RequestParam String ragTag, @RequestParam("file") List<MultipartFile> files) {
log.info("上传知识库开始 {}", ragTag);
for (MultipartFile file : files) {
TikaDocumentReader documentReader = new TikaDocumentReader(file.getResource());
List<Document> documents = documentReader.get();
List<Document> documentSplitterList = tokenTextSplitter.apply(documents);
// 添加知识库标签
documents.forEach(doc -> doc.getMetadata().put("cactusli", ragTag));
documentSplitterList.forEach(doc -> doc.getMetadata().put("cactusli", ragTag));
pgVectorStore.accept(documentSplitterList);
// 添加知识库记录
RList<String> elements = redissonClient.getList("ragTag");
if (!elements.contains(ragTag)){
elements.add(ragTag);
}
}
log.info("上传知识库完成 {}", ragTag);
return Response.<String>builder().code("1000").info("调用成功").build();
}
}
1. 请根据服务端接口,编写一款好看的前端上传页面。页面使用 html、js、tailwindcss 编写,不要提供 vue、react 代码。
2. ragTag 为知识库名称
3. files 为知识库文件,支持,md、txt、sql 文件类型上传。

v0.dev 出图的效果也是可以的。可以根据描述给出准确的页面实现。
相关的生成的代码,已经放到工程 docs/dev-ops,nginx、html 、upload3.html。
赞助