feat: 将系统提示词加入会话上下文中,系统提示词不会显示在前端。

This commit is contained in:
肖应宇 2026-03-11 13:39:41 +08:00
parent 38faeeb46d
commit 3471e8552f
6 changed files with 115 additions and 29 deletions

View File

@ -223,15 +223,25 @@ async function handleSend(
await chatStore.createConversation();
}
//
// 使使
const systemPrompt = options?.systemPrompt || currentConversation.value?.settings?.systemPrompt;
//
const existingMessages = currentConversation.value?.messages || [];
const hasSystemMessage = existingMessages.some((m: any) => m.role === MessageRole.SYSTEM);
//
if (systemPrompt && !hasSystemMessage) {
await chatStore.addMessage(MessageRole.SYSTEM, {
type: MessageType.TEXT,
text: systemPrompt,
});
}
//
const updatedMessages = currentConversation.value?.messages || [];
const MAX_HISTORY_ROUNDS = 20; // 20 40
const historyMessages = existingMessages
.filter(
(m: any) =>
m.role === MessageRole.USER || m.role === MessageRole.ASSISTANT,
)
.filter((m: any) => m.content?.text) //
const historyMessages = updatedMessages.filter((m: any) => m.content?.text) //
.slice(-(MAX_HISTORY_ROUNDS * 2))
.map((m: any) => ({ role: m.role, content: m.content.text }));

View File

@ -3,7 +3,7 @@
<div ref="containerRef" class="message-list" @scroll="handleScroll">
<!-- 欢迎界面 -->
<WelcomeScreen
v-if="messages.length === 0"
v-if="visibleMessages.length === 0"
@select="$emit('select-suggestion', $event)"
/>
@ -12,12 +12,12 @@
<div class="messages-wrapper">
<TransitionGroup name="message">
<MessageBubble
v-for="(message, index) in messages"
v-for="(message, index) in visibleMessages"
:key="message.id"
:message="message"
:show-timestamp="showTimestamp"
:compact="compact"
:is-New="index === messages.length - 1"
:is-New="index === visibleMessages.length - 1"
@retry="$emit('retry', message.id)"
@regenerate="$emit('regenerate', message.id)"
@copy="handleCopy(message)"
@ -62,12 +62,13 @@
</template>
<script setup lang="ts">
import { ref, watch, nextTick, onMounted } from "vue";
import { ref, watch, nextTick, onMounted, computed } from "vue";
import { useChatStore } from "@/stores/chat";
import MessageBubble from "@/components/message/MessageBubble.vue";
import WelcomeScreen from "./WelcomeScreen.vue";
import { Bot, ChevronDown } from "@/components/icons";
import type { Message, Attachment, VideoInfo, Suggestion } from "@/types/chat";
import { MessageRole } from "@/types/chat";
const props = withDefaults(
defineProps<{
@ -83,6 +84,13 @@ const props = withDefaults(
},
);
//
const visibleMessages = computed(() => {
return props.messages.filter(
(message) => message.role !== MessageRole.SYSTEM
);
});
const emit = defineEmits<{
retry: [messageId: string];
regenerate: [messageId: string];
@ -175,7 +183,7 @@ function handleDownloadFile(file: Attachment) {
//
watch(
() => props.messages.length,
() => visibleMessages.value.length,
(newLen, oldLen) => {
if (newLen > oldLen) {
if (isAutoScrolling.value) {
@ -191,7 +199,7 @@ watch(
//
watch(
() => props.messages[props.messages.length - 1]?.content.text,
() => visibleMessages.value[visibleMessages.value.length - 1]?.content.text,
() => {
if (isAutoScrolling.value) {
nextTick(() => {

View File

@ -163,7 +163,7 @@ async function textCopy(data: any) {
/* 可折叠内容 */
.thinking-content {
max-height: 2000px;
overflow: hidden;
overflow: auto;
transition:
max-height 0.35s ease,
opacity 0.25s ease;

View File

@ -202,6 +202,7 @@ import FormSelect from "@/components/ui/FormSelect.vue";
import { MessageSquare, X, Check, Trash2 } from "@/components/icons";
import { chatApi } from "@/services/api.ts";
import type { ConversationSettings } from "@/types/chat";
import { MessageRole, MessageType } from "@/types/chat";
const chatStore = useChatStore();
const settingsStore = useSettingsStore();
@ -359,6 +360,25 @@ function handleSave() {
//
chatStore.updateConversationSettings(conversation.value.id, convSettings);
//
if (localSettings.value.systemPrompt) {
const messages = conversation.value.messages || [];
const systemMsgIndex = messages.findIndex((m: any) => m.role === MessageRole.SYSTEM);
if (systemMsgIndex >= 0) {
//
chatStore.updateMessage(messages[systemMsgIndex].id, {
content: {
type: MessageType.TEXT,
text: localSettings.value.systemPrompt,
},
});
} else {
//
chatStore.addSystemMessage(conversation.value.id, localSettings.value.systemPrompt);
}
}
close();
//

View File

@ -121,21 +121,36 @@ class ChatApi {
}
// 将前端简化的请求翻译为 OpenAI 兼容的规范请求体
// 构建 messages 数组system + 历史消息 + 当前用户消息
const systemMessage = {
role: "system",
content:
request.systemPrompt ||
"你是一个智能助手,可以分析用户发送的文字,文件或图片内容,并进行回答。",
};
const currentUserMessage = {
role: "user",
content: userContent,
};
const allMessages =
request.history && request.history.length > 0
? [systemMessage, ...request.history, currentUserMessage]
: [systemMessage, currentUserMessage];
// 检查历史消息中是否已有系统消息
const historyHasSystem = request.history?.some((m) => m.role === "system");
// 构建 messages 数组
let allMessages: Array<{ role: string; content: any }>;
if (request.history && request.history.length > 0) {
// 如果历史中有系统消息,直接使用历史消息
if (historyHasSystem) {
allMessages = [...request.history, { role: "user", content: userContent }];
} else {
// 否则添加系统消息
const systemMessage = {
role: "system",
content:
request.systemPrompt ||
"你是一个智能助手,可以分析用户发送的文字,文件或图片内容,并进行回答。",
};
allMessages = [systemMessage, ...request.history, { role: "user", content: userContent }];
}
} else {
// 没有历史消息,添加系统消息
const systemMessage = {
role: "system",
content:
request.systemPrompt ||
"你是一个智能助手,可以分析用户发送的文字,文件或图片内容,并进行回答。",
};
allMessages = [systemMessage, { role: "user", content: userContent }];
}
const openAiRequest = {
model: request.model || "glm-4-flash",

View File

@ -290,6 +290,38 @@ export const useChatStore = defineStore("chat", () => {
return message;
}
// 添加系统消息(放在消息列表开头)
async function addSystemMessage(
conversationId: string,
systemPrompt: string
): Promise<Message> {
const conversation = conversations.value.find((c) => c.id === conversationId);
if (!conversation) {
throw new Error("Conversation not found");
}
const message: Message = {
id: generateId(),
role: MessageRole.SYSTEM,
content: { type: "text" as const, text: systemPrompt },
timestamp: Date.now(),
isStreaming: false,
} as Message;
// 将系统消息插入到消息列表开头
conversation.messages.unshift(message);
conversation.updatedAt = Date.now();
// 异步保存
try {
await conversationApi.addMessage(conversationId, message);
} catch (error) {
console.error("Failed to save system message:", error);
}
return message;
}
// 更新消息
async function updateMessage(messageId: string, updates: Partial<Message>) {
const conversation = currentConversation.value;
@ -479,6 +511,7 @@ export const useChatStore = defineStore("chat", () => {
renameConversation,
updateConversationSettings,
addMessage,
addSystemMessage,
updateMessage,
updateMessageContent,
saveConversation,