Rename product to Dabenying QA assistant
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# AI 知识库系统 V2 管理后台
|
||||
# 大本营答疑助手管理后台
|
||||
|
||||
这是 V2 的管理后台,使用 Vue 3、Vite、TypeScript 和 Element Plus。
|
||||
这是大本营答疑助手的管理后台,使用 Vue 3、Vite、TypeScript 和 Element Plus。
|
||||
|
||||
## 本地启动
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>AI 知识库后台</title>
|
||||
<title>大本营答疑助手后台</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -1035,21 +1035,21 @@ function buildChatQuery() {
|
||||
<section class="login-hero">
|
||||
<div class="login-hero-main">
|
||||
<div class="login-brand">
|
||||
<span>AI</span>
|
||||
<strong>知识库管理后台</strong>
|
||||
<span>答</span>
|
||||
<strong>大本营答疑助手后台</strong>
|
||||
</div>
|
||||
<h1>让知识库、Agent 和用户运营保持在同一个控制台里。</h1>
|
||||
<p>统一维护学员、知识库、模型配置、问答记录和系统运行参数,方便排查与交接。</p>
|
||||
<h1>把大本营答疑、知识库和学员运营放在同一个控制台里。</h1>
|
||||
<p>统一维护学员名单、开放知识库、模型接入、Agent 调试、问答记录和系统运行参数,方便排查与交接。</p>
|
||||
<div class="login-highlights">
|
||||
<span>知识库运营</span>
|
||||
<span>Agent 调试</span>
|
||||
<span>记录审计</span>
|
||||
<span>大本营知识库</span>
|
||||
<span>答疑 Agent 调试</span>
|
||||
<span>问答记录审计</span>
|
||||
</div>
|
||||
</div>
|
||||
<section class="login-card">
|
||||
<div class="login-card-head">
|
||||
<h2>管理员登录</h2>
|
||||
<p>请输入后台管理员账号和密码。</p>
|
||||
<h2>登录答疑后台</h2>
|
||||
<p>请输入大本营答疑助手后台管理员账号和密码。</p>
|
||||
</div>
|
||||
<el-form label-position="top" @submit.prevent="login">
|
||||
<el-form-item label="管理员账号">
|
||||
@@ -1064,7 +1064,7 @@ function buildChatQuery() {
|
||||
show-password
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-button type="primary" :loading="loading" class="full-btn login-submit" @click="login">登录后台</el-button>
|
||||
<el-button type="primary" :loading="loading" class="full-btn login-submit" @click="login">进入答疑后台</el-button>
|
||||
</el-form>
|
||||
</section>
|
||||
</section>
|
||||
@@ -1072,7 +1072,7 @@ function buildChatQuery() {
|
||||
|
||||
<main v-else class="admin-shell">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-title">AI 知识库</div>
|
||||
<div class="sidebar-title">大本营答疑</div>
|
||||
<button :class="{ active: activeMenu === 'dashboard' }" @click="switchMenu('dashboard')">Dashboard</button>
|
||||
<button :class="{ active: activeMenu === 'users' }" @click="switchMenu('users')">用户管理</button>
|
||||
<button :class="{ active: activeMenu === 'knowledge' }" @click="switchMenu('knowledge')">知识库管理</button>
|
||||
@@ -1591,7 +1591,7 @@ function buildChatQuery() {
|
||||
:class="message.role"
|
||||
>
|
||||
<div class="message-meta">
|
||||
<strong>{{ message.role === 'user' ? '用户' : 'AI 助手' }}</strong>
|
||||
<strong>{{ message.role === 'user' ? '用户' : '大本营答疑助手' }}</strong>
|
||||
<span>{{ message.createdAt }}</span>
|
||||
</div>
|
||||
<pre>{{ message.content }}</pre>
|
||||
|
||||
@@ -3,7 +3,9 @@ import {
|
||||
ElCollapse,
|
||||
ElCollapseItem,
|
||||
ElDatePicker,
|
||||
ElDivider,
|
||||
ElDrawer,
|
||||
ElEmpty,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
@@ -21,7 +23,9 @@ import "element-plus/theme-chalk/base.css";
|
||||
import "element-plus/theme-chalk/el-button.css";
|
||||
import "element-plus/theme-chalk/el-collapse.css";
|
||||
import "element-plus/theme-chalk/el-date-picker.css";
|
||||
import "element-plus/theme-chalk/el-divider.css";
|
||||
import "element-plus/theme-chalk/el-drawer.css";
|
||||
import "element-plus/theme-chalk/el-empty.css";
|
||||
import "element-plus/theme-chalk/el-form.css";
|
||||
import "element-plus/theme-chalk/el-input.css";
|
||||
import "element-plus/theme-chalk/el-input-number.css";
|
||||
@@ -48,7 +52,9 @@ app.config.globalProperties.$ELEMENT = { locale: zhCn };
|
||||
ElCollapse,
|
||||
ElCollapseItem,
|
||||
ElDatePicker,
|
||||
ElDivider,
|
||||
ElDrawer,
|
||||
ElEmpty,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AI 知识库系统 V2 后端
|
||||
# 大本营答疑助手后端
|
||||
|
||||
这是 V2 的后端服务目录,当前处于阶段二第一批建设:后端基础工程、核心数据模型、mock 登录能力。
|
||||
这是大本营答疑助手的后端服务目录,当前处于阶段二第一批建设:后端基础工程、核心数据模型、mock 登录能力。
|
||||
|
||||
## 技术栈
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ from app.services.rag_service import RagResult
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
DEFAULT_PROMPT = "你是企业飞书知识库 AI 助手。你只能基于提供的知识片段回答,不能编造。"
|
||||
DEFAULT_PROMPT = "你是大本营答疑助手。你只能基于提供的知识片段回答,不能编造。"
|
||||
|
||||
|
||||
@router.get("/prompt")
|
||||
|
||||
@@ -214,7 +214,7 @@ class ChatService:
|
||||
|
||||
# 拼接成文本
|
||||
import re
|
||||
role_labels = {"user": "用户", "assistant": "AI助手"}
|
||||
role_labels = {"user": "用户", "assistant": "大本营答疑助手"}
|
||||
parts = []
|
||||
for msg in to_summarize:
|
||||
content = re.sub(r"<think[\s\S]*?</think\s*>", "", msg.content, flags=re.IGNORECASE).strip()
|
||||
|
||||
@@ -184,7 +184,7 @@ def _call_openai_compatible_model(model: ModelConfig, rag_result: RagResult) ->
|
||||
payload = {
|
||||
"model": model.model_name,
|
||||
"messages": [
|
||||
{"role": "system", "content": "你是企业知识库问答助手,只能基于已提供的知识片段回答。"},
|
||||
{"role": "system", "content": "你是大本营答疑助手,只能基于已提供的知识片段回答。"},
|
||||
{"role": "user", "content": rag_result.prompt},
|
||||
],
|
||||
"stream": False,
|
||||
@@ -217,7 +217,7 @@ def _call_anthropic_messages(model: ModelConfig, rag_result: RagResult) -> str:
|
||||
payload = {
|
||||
"model": model.model_name,
|
||||
"max_tokens": model.max_token or 1024,
|
||||
"system": "你是企业知识库问答助手,只能基于已提供的知识片段回答。",
|
||||
"system": "你是大本营答疑助手,只能基于已提供的知识片段回答。",
|
||||
"messages": [{"role": "user", "content": rag_result.prompt}],
|
||||
"stream": False,
|
||||
}
|
||||
@@ -251,7 +251,7 @@ def _call_gemini_generate_content(model: ModelConfig, rag_result: RagResult) ->
|
||||
|
||||
payload = {
|
||||
"systemInstruction": {
|
||||
"parts": [{"text": "你是企业知识库问答助手,只能基于已提供的知识片段回答。"}]
|
||||
"parts": [{"text": "你是大本营答疑助手,只能基于已提供的知识片段回答。"}]
|
||||
},
|
||||
"contents": [{"role": "user", "parts": [{"text": rag_result.prompt}]}],
|
||||
}
|
||||
@@ -329,14 +329,14 @@ def _call_minimax(model: ModelConfig, rag_result: RagResult) -> str:
|
||||
payload: dict[str, Any] = {
|
||||
"model": model.model_name,
|
||||
"tokens_to_generate": model.max_token or 1024,
|
||||
"reply_constraints": {"sender_type": "BOT", "sender_name": "AI知识库助手"},
|
||||
"reply_constraints": {"sender_type": "BOT", "sender_name": "大本营答疑助手"},
|
||||
"messages": [
|
||||
{"sender_type": "USER", "sender_name": "用户", "text": rag_result.prompt},
|
||||
],
|
||||
"bot_setting": [
|
||||
{
|
||||
"bot_name": "AI知识库助手",
|
||||
"content": "你是企业知识库问答助手,只能基于已提供的知识片段回答。",
|
||||
"bot_name": "大本营答疑助手",
|
||||
"content": "你是大本营答疑助手,只能基于已提供的知识片段回答。",
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ def _stream_openai_compatible_model(model: ModelConfig, rag_result: RagResult) -
|
||||
payload: dict[str, Any] = {
|
||||
"model": model.model_name,
|
||||
"messages": [
|
||||
{"role": "system", "content": "你是企业知识库问答助手,只能基于已提供的知识片段回答。"},
|
||||
{"role": "system", "content": "你是大本营答疑助手,只能基于已提供的知识片段回答。"},
|
||||
{"role": "user", "content": rag_result.prompt},
|
||||
],
|
||||
"max_tokens": model.max_token or 1024,
|
||||
@@ -211,7 +211,7 @@ def _openai_stream_payload(model: ModelConfig, rag_result: RagResult) -> dict[st
|
||||
payload: dict[str, Any] = {
|
||||
"model": model.model_name,
|
||||
"messages": [
|
||||
{"role": "system", "content": "你是企业知识库问答助手,只能基于已提供的知识片段回答。"},
|
||||
{"role": "system", "content": "你是大本营答疑助手,只能基于已提供的知识片段回答。"},
|
||||
{"role": "user", "content": rag_result.prompt},
|
||||
],
|
||||
"max_tokens": model.max_token or 1024,
|
||||
@@ -317,7 +317,7 @@ def _stream_anthropic_messages(model: ModelConfig, rag_result: RagResult) -> Ite
|
||||
payload: dict[str, Any] = {
|
||||
"model": model.model_name,
|
||||
"max_tokens": model.max_token or 1024,
|
||||
"system": "你是企业知识库问答助手,只能基于已提供的知识片段回答。",
|
||||
"system": "你是大本营答疑助手,只能基于已提供的知识片段回答。",
|
||||
"messages": [{"role": "user", "content": rag_result.prompt}],
|
||||
}
|
||||
_put_if_not_none(payload, "temperature", _decimal_to_float(model.temperature))
|
||||
@@ -361,7 +361,7 @@ def _anthropic_stream_payload(model: ModelConfig, rag_result: RagResult) -> dict
|
||||
payload: dict[str, Any] = {
|
||||
"model": model.model_name,
|
||||
"max_tokens": model.max_token or 1024,
|
||||
"system": "你是企业知识库问答助手,只能基于已提供的知识片段回答。",
|
||||
"system": "你是大本营答疑助手,只能基于已提供的知识片段回答。",
|
||||
"messages": [{"role": "user", "content": rag_result.prompt}],
|
||||
}
|
||||
_put_if_not_none(payload, "temperature", _decimal_to_float(model.temperature))
|
||||
|
||||
@@ -61,7 +61,7 @@ class RagService:
|
||||
|
||||
class PromptService:
|
||||
_default_prompt = (
|
||||
"你是企业飞书知识库 AI 助手。你只能基于提供的知识片段回答,不能编造。"
|
||||
"你是大本营答疑助手。你只能基于提供的知识片段回答,不能编造。"
|
||||
"如果知识片段之间有冲突,需要说明不同来源的观点。"
|
||||
)
|
||||
|
||||
@@ -114,7 +114,7 @@ class PromptService:
|
||||
# 只保留最近 KEEP_RECENT 轮的原文(1 轮 = 1 个 user + 1 个 assistant)
|
||||
recent = history[-(KEEP_RECENT * 2):]
|
||||
if recent:
|
||||
role_labels = {"user": "用户", "assistant": "AI助手"}
|
||||
role_labels = {"user": "用户", "assistant": "大本营答疑助手"}
|
||||
for msg in recent:
|
||||
label = role_labels.get(msg.role, msg.role)
|
||||
content = msg.content.strip()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AI 知识库系统 V2 用户端 H5
|
||||
# 大本营答疑助手用户端 H5
|
||||
|
||||
这是 V2 的用户端 H5,技术栈为 Vue 3 + Vite + TypeScript。
|
||||
这是大本营答疑助手的用户端 H5,技术栈为 Vue 3 + Vite + TypeScript。
|
||||
|
||||
## 当前已完成
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<title>AI知识库助手</title>
|
||||
<title>大本营答疑助手</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -34,7 +34,7 @@ onMounted(async () => {
|
||||
try {
|
||||
user.value = await api.profile();
|
||||
await loadSessions();
|
||||
statusText.value = "已连接知识库服务";
|
||||
statusText.value = "已连接大本营答疑服务";
|
||||
} catch {
|
||||
clearToken();
|
||||
statusText.value = "登录已失效";
|
||||
@@ -45,7 +45,7 @@ onMounted(async () => {
|
||||
|
||||
async function onLoggedIn(profile: UserProfile) {
|
||||
user.value = profile;
|
||||
statusText.value = "已连接知识库服务";
|
||||
statusText.value = "已连接大本营答疑服务";
|
||||
await loadSessions();
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ async function scrollToBottom() {
|
||||
<header class="topbar">
|
||||
<button type="button" class="icon-btn" @click="drawerOpen = true">☰</button>
|
||||
<div>
|
||||
<h1>AI知识库助手</h1>
|
||||
<h1>大本营答疑助手</h1>
|
||||
<p>{{ statusText }}</p>
|
||||
</div>
|
||||
<button type="button" class="plain-btn" @click="logout">退出</button>
|
||||
@@ -199,7 +199,7 @@ async function scrollToBottom() {
|
||||
<section class="chat-area">
|
||||
<div v-if="messages.length === 0" class="empty-state">
|
||||
<strong>可以开始提问了</strong>
|
||||
<p>当前已接入真实知识库检索链路,若外部服务未配置或权限不足,会在回复区提示具体原因。</p>
|
||||
<p>当前已接入大本营知识库检索链路,若外部服务未配置或权限不足,会在回复区提示具体原因。</p>
|
||||
</div>
|
||||
<ChatMessage
|
||||
v-for="message in messages"
|
||||
|
||||
@@ -57,7 +57,7 @@ const renderedContent = computed(() => {
|
||||
|
||||
<template>
|
||||
<article class="message" :class="role">
|
||||
<div class="avatar">{{ role === "assistant" ? "AI" : "我" }}</div>
|
||||
<div class="avatar">{{ role === "assistant" ? "答" : "我" }}</div>
|
||||
<div class="bubble">
|
||||
<template v-if="role === 'assistant'">
|
||||
<div v-if="streaming && assistantParts.reasoning" class="thinking-indicator">
|
||||
|
||||
@@ -76,9 +76,9 @@ function showError(text: string) {
|
||||
|
||||
<template>
|
||||
<section class="login-panel">
|
||||
<div class="brand-mark">AI</div>
|
||||
<h1>AI知识库助手</h1>
|
||||
<p>企业知识统一问答入口</p>
|
||||
<div class="brand-mark">答</div>
|
||||
<h1>大本营答疑助手</h1>
|
||||
<p>围绕大本营知识库,为学员提供及时、可信的答疑支持。</p>
|
||||
|
||||
<label>
|
||||
手机号
|
||||
|
||||
Reference in New Issue
Block a user