Rename product to Dabenying QA assistant

This commit is contained in:
2026-07-09 12:28:55 +08:00
parent 6c53566a4e
commit facb3a6a56
15 changed files with 48 additions and 42 deletions

View File

@@ -1,6 +1,6 @@
# AI 知识库系统 V2 管理后台
# 大本营答疑助手管理后台
这是 V2 的管理后台,使用 Vue 3、Vite、TypeScript 和 Element Plus。
这是大本营答疑助手的管理后台,使用 Vue 3、Vite、TypeScript 和 Element Plus。
## 本地启动

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
# AI 知识库系统 V2 后端
# 大本营答疑助手后端
这是 V2 的后端服务目录当前处于阶段二第一批建设后端基础工程、核心数据模型、mock 登录能力。
这是大本营答疑助手的后端服务目录当前处于阶段二第一批建设后端基础工程、核心数据模型、mock 登录能力。
## 技术栈

View File

@@ -25,7 +25,7 @@ from app.services.rag_service import RagResult
router = APIRouter()
DEFAULT_PROMPT = "你是企业飞书知识库 AI 助手。你只能基于提供的知识片段回答,不能编造。"
DEFAULT_PROMPT = "你是大本营答疑助手。你只能基于提供的知识片段回答,不能编造。"
@router.get("/prompt")

View File

@@ -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()

View File

@@ -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": "你是大本营答疑助手,只能基于已提供的知识片段回答。",
}
],
}

View File

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

View File

@@ -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()

View File

@@ -1,6 +1,6 @@
# AI 知识库系统 V2 用户端 H5
# 大本营答疑助手用户端 H5
这是 V2 的用户端 H5技术栈为 Vue 3 + Vite + TypeScript。
这是大本营答疑助手的用户端 H5技术栈为 Vue 3 + Vite + TypeScript。
## 当前已完成

View File

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

View File

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

View File

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

View File

@@ -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>
手机号