本文将带大家一步一步的在腾讯云HAI平台上部署deepseek,然后使用对外API+python+django+vue+elementUI做一个漂亮的法律咨询(律师)辅助平台工具。
包含部署过程、功能设计、开发平台过程、接口调通过程、实际测试等步骤。能为读者提供一个全面详细的新手指南,减少面对法律纠纷时候的分析成本。尤其是律师朋友们可以通过这个平台大大提高工作效率,减少脑细胞消耗!
纯新手向,白话流,没有过编程经验的小伙伴正好借此学习如何打造一个简单的web平台。
首先先进入腾讯云官网并点击右上角进行注册:https://cloud.tencent.com/
注册后直接登录即可。
网址如下:https://console.cloud.tencent.com/hai/instance?rid=8
或在腾讯云顶部搜索:HAI ,结果第一条点击立即使用。
首次进入会提示需要授权,点击“同意授权”
点击“新建”,开始创造一个新应用吧!
在新建页面中,依次按照如图选择:
当一切配置完成后,点击右下角立即购买即可。
等待创建完成(需要几分钟),就可以在【算力管理】页面中看到这个实例【法律咨询(小律师)辅助平台】了。
友情提示(这个实例可以开机关机,在“更多”里操作即可。)
此刻让其保持开机状态:也就是运行中,即可开始后续步骤。
点击算力链接,在弹出的选项中选择 JupyterLab,这样可以打开控制后台的页面。
(记下自己的公网IP,这个后面是有用的)
在打开的页面中,点击Terminal:(就会进入命令行的终端界面了)
接下来,我们将通过ollama工具来启动这个deepseek服务,命令如下(14b是我觉得还是可以用,有钱的上更大的)
ollama run deepseek-r1:14b
还记得之前的这个实例外面显示的公网IP么?
此刻这个公网IP + 端口6399 ,就是这个deepseek的远程网址了。在你自己的电脑浏览器可以直接输入以下网址测试了:
(注意:这个公网IP每次关机开机后可能都会变化,当然一旦服务平台启动了,也就不该轻易关机了)
如上图,看到这个显示:Ollama is running 就代表服务启动成功了。
之后我们在开发本地的网站平台的时候,就可以通过这个域名的接口来远程调用这个deepseek-r1的问答等功能了。
相当于我们最终要实现的web平台:法律咨询(小律师)辅助平台 的AI引擎已经弄好了,接下来就搞定平台的外壳即可。
我本地的环境版本为以下这些,各位其实可以用其他版本来开发,大版本号一样那代码和操作也基本差不多。
编程IDE:pycharm 专业版
Python : 3.7.6 然后以该版本的python的pip工具直接下载其他库即可自动安装适合的版本。
Django : 3.2.13
1. 自己本地电脑终端或cmd窗口输入命令:django-admin startproject FLZX
2. 进入创建好的FLZX项目根目录:cd FLZX
3. 创建具体app应用:django-admin startapp Myapp
创建好后,在pycharm中打开该项目,如图所示:
settings.py文件的修改如下
在Myapp目录下手动创建static和templates俩个文件夹,用来存放网页模版和静态资源
在django项目根目录(Terminal面板)中执行一句同步sql的命令:python3 manage.py migrate
可以再执行一句创建超管的命令,然后按照提示输入邮箱、密码等即可:python3 manage.py createsuperuser
首先在templates文件夹内创建一个HTML文件。
取名为:Home.html (如下图,自动填充好了一些基本元素)
为了能访问这个html页面,我们需要先构建url 和 对应的def函数,并把他们三个给串联起来:
url就写在urls.py中:
views.py中写def:
接下来,就是开发这个Home.html了。
关于这个页面的设计,我的预想是有个一大大的输入框,用来填充遇到的案子描述。
然后有下方有单选框组,就是用来选定各个功能的。(包括:案子成功率,案子可参考的法律条目,起诉书或其他什么文件生成,还有可以想到的打赢官司的各种办法,还有可以参考的案例等)然后单选框组右侧有个输入框,用来输入一些具体的文案。
然后在单选框组下方还有个按钮,用来启动执行。点击执行按钮后,发送请求给后台
最后下面有个大大的deepseek回答展示区。
源码如下:(可复制)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DeepSeek法律智能助手专业版</title>
<style>
/* 添加以下样式 */
.loading {
padding: 1.5rem;
text-align: center;
color: #2c5f9d;
}
.loader {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid #f3f3f3;
border-radius: 50%;
border-top: 3px solid #2c5f9d;
animation: spin 1s linear infinite;
margin-left: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.result-card {
background: #f8fbfe;
padding: 1.5rem;
border-radius: 8px;
border-left: 4px solid #2c5f9d;
}
.result-card h3 {
color: #2c5f9d;
margin-bottom: 1rem;
}
.result-card .content {
line-height: 1.8;
color: #444;
}
.result-card ul {
padding-left: 2rem;
margin: 1rem 0;
}
.result-card li {
margin: 0.5rem 0;
}
.error {
color: #dc3545;
padding: 1rem;
background: #ffeef0;
border-radius: 6px;
}
:root {
--primary-color: #2c5f9d;
--accent-color: #3a7ab9;
--text-dark: #1e3b50;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: '微软雅黑', 'Segoe UI', sans-serif;
}
body {
background: #f8fbfe;
padding: 2rem;
max-width: 1200px;
margin: 0 auto;
min-height: 100vh;
}
h2 {
color: var(--text-dark);
text-align: center;
margin: 0 0 2rem;
font-size: 2.2rem;
letter-spacing: 1px;
}
/* 案件输入区 */
.case-input {
width: 100%;
height: 150px;
padding: 1.2rem;
border: 2px solid var(--primary-color);
border-radius: 8px;
margin-bottom: 1.5rem;
resize: vertical;
font-size: 1rem;
line-height: 1.6;
box-shadow: 0 2px 4px rgba(44, 62, 80, 0.1);
}
/* 控制面板 */
.control-panel {
display: flex;
gap: 1.5rem;
margin-bottom: 1.5rem;
}
/* 横向单选框组 */
.radio-grid {
flex: 1;
background: white;
padding: 1.5rem;
border-radius: 10px;
box-shadow: 0 3px 6px rgba(0,0,0,0.08);
min-height: 180px;
display: flex;
flex-direction: column;
}
.radio-group {
display: flex;
flex-wrap: wrap;
gap: 0.8rem;
margin-top: 0.5rem;
}
.radio-item {
flex: 1 1 calc(33.33% - 0.8rem);
min-width: 200px;
padding: 0.8rem;
background: #f8fafd;
border-radius: 6px;
transition: all 0.2s;
}
.radio-item:hover {
background: #f2f6fc;
transform: translateY(-1px);
}
.radio-item input[type="radio"] {
width: 16px;
height: 16px;
margin-right: 0.6rem;
accent-color: var(--primary-color);
}
/* 参数输入区 */
.params-box {
flex: 1;
background: white;
border-radius: 10px;
padding: 1.5rem;
box-shadow: 0 3px 6px rgba(0,0,0,0.08);
min-height: 180px;
display: flex;
flex-direction: column;
}
.params-input {
flex: 1;
margin-top: 0.5rem;
}
.params-input textarea {
width: 100%;
height: 100%;
padding: 1rem;
border: 1px solid #dde3e9;
border-radius: 6px;
resize: none;
font-size: 0.95rem;
}
/* 执行按钮 */
.execute-btn {
align-self: flex-end;
padding: 0.8rem 2rem;
background: linear-gradient(135deg, var(--primary-color), var(--accent-color));
color: white;
border: none;
border-radius: 25px;
font-size: 1rem;
cursor: pointer;
transition: all 0.3s;
margin-top: 1rem;
box-shadow: 0 3px 6px rgba(44, 95, 157, 0.2);
}
.execute-btn:hover {
opacity: 0.9;
transform: translateY(-1px);
}
/* 响应区 */
.response-area {
background: white;
border-radius: 10px;
padding: 2rem;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
min-height: 300px;
}
.response-area h2 {
color: var(--text-dark);
margin-bottom: 1.5rem;
font-size: 1.3rem;
border-left: 4px solid var(--primary-color);
padding-left: 1rem;
}
@media (max-width: 768px) {
.control-panel {
flex-direction: column;
}
.radio-item {
flex: 1 1 100%;
}
}
</style>
</head>
<body>
<h2>DeepSeek法律智能助手</h2>
<textarea class="case-input"
placeholder="请详细描述法律案件(包含时间、地点、涉案人员、争议焦点等关键信息)..."></textarea>
<div class="control-panel">
<!-- 功能选择区 -->
<div class="radio-grid">
<h3>智能法律工具</h3>
<div class="radio-group">
<label class="radio-item">
<input type="radio" name="function" checked>
胜率预测
</label>
<label class="radio-item">
<input type="radio" name="function">
法律条文
</label>
<label class="radio-item">
<input type="radio" name="function">
文书生成
</label>
<label class="radio-item">
<input type="radio" name="function">
诉讼策略
</label>
<label class="radio-item">
<input type="radio" name="function">
类案检索
</label>
<label class="radio-item">
<input type="radio" name="function">
时效计算
</label>
<label class="radio-item">
<input type="radio" name="function">
管辖分析
</label>
<label class="radio-item">
<input type="radio" name="function">
费用估算
</label>
<label class="radio-item">
<input type="radio" name="function">
证据评估
</label>
</div>
</div>
<!-- 参数设置区 -->
<div class="params-box">
<h3>参数配置</h3>
<div class="params-input">
<textarea
placeholder="请输入具体要求(例如:文书类型/法律领域/金额区间等)..."></textarea>
</div>
<button class="execute-btn">立即分析</button>
</div>
</div>
<!-- 响应展示区 -->
<div class="response-area">
<h2>专业分析结果</h2>
<div id="deepseek-response">
<!-- 分析结果将通过JavaScript动态加载 -->
</div>
</div>
</body>
<script>
// DOM元素获取
const executeBtn = document.querySelector('.execute-btn');
const caseInput = document.querySelector('.case-input');
const paramsInput = document.querySelector('.params-input textarea');
const responseArea = document.getElementById('deepseek-response');
// 事件监听
executeBtn.addEventListener('click', async () => {
try {
// 收集表单数据
const formData = {
caseDescription: caseInput.value,
selectedFunction: document.querySelector('input[name="function"]:checked').parentElement.textContent.trim(),
params: paramsInput.value
};
// 显示加载状态
responseArea.innerHTML = '<div class="loading">分析中...<div class="loader"></div></div>';
// 发送请求
const response = await fetch('/get_answer/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
});
if (!response.ok) throw new Error(`请求失败: ${response.status}`);
// 解析结果
const result = await response.json();
// 渲染结果
responseArea.innerHTML = `
<div class="result-card">
<h3>${result.title || '分析结果'}</h3>
<div class="content">${formatResult(result.content)}</div>
${result.reference ? `<div class="reference">依据:${result.reference}</div>` : ''}
</div>
`;
} catch (error) {
console.error('请求失败:', error);
responseArea.innerHTML = `<div class="error">错误: ${error.message}</div>`;
}
});
// 结果格式化函数
function formatResult(content) {
// 如果是数组格式自动转换为列表
if (Array.isArray(content)) {
return `<ul>${content.map(item => `<li>${item}</li>`).join('')}</ul>`;
}
return content.replace(/\n/g, '<br>');
}
</script>
</html>
上部代码中,点击执行后会发出一个路由为/get_answer/的请求,
而这个请求就需要我们去urls.py中设置映射和去views.py中设置对应的函数才行。
代码如下:(中间需要调用腾讯云HAI刚刚部署的Deepseek对外的接口,可复制)
from django.shortcuts import render
from django.http import HttpResponse,JsonResponse
from Myapp.models import *
from django.views.decorators.http import require_http_methods
import json,os,requests
# Create your views here.
def home(request):
return render(request,'Home.html')
@require_http_methods(["POST"])
def get_answer(request):
'''组成提问,传递给下游函数,得到结果后返回给前端'''
data = json.loads(request.body)
print(data)
question = '你现在是一个精通法律的律师,以下是我最近头疼的一个案子的描述:%s\n 我需要你帮我做一个:%s\n 这是我的一些补充:%s'%(data['caseDescription'],data['selectedFunction'],data['params'])
result = {
"title": data['selectedFunction'],
"content": search_laws(question),
"reference": "法律法规数据库"
}
return JsonResponse(result, safe=False)
def search_laws(question):
"""发送给腾讯云HAI的deepseek"""
url = "http://你的公网IP:6399/api/generate"
payload = {
"model": "deepseek-r1:14b", # Ollama服务中注册的模型名称
"prompt": question,
"stream": False, # 设置为False获取完整响应
"options": {
"temperature": 0.7, # 控制生成随机性(0-1)
"max_tokens": 512 # 最大输出长度
}
}
try:
response = requests.post(
url,
json=payload,
timeout=30 # 设置超时时间为30秒
)
if response.status_code == 200:
result = response.json()
return result["response"]
else:
return f"请求失败,状态码:{response.status_code},响应:{response.text}"
except Exception as e:
return f"请求异常:{str(e)}"
到此,搭建完成!
感谢阅读的小伙伴支持哦!
帮忙一键三连吧~
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。