ai生成样式加入聊天历史,优化提示词

master
joefalmko 9 months ago
parent 8241bb72f7
commit c4f131f291

@ -15,7 +15,7 @@ import (
func RequestStyle(c *gin.Context) (interface{}, error) { func RequestStyle(c *gin.Context) (interface{}, error) {
// userMsg := c.PostForm("user_input") // userMsg := c.PostForm("user_input")
userMsg:=c.GetString(consts.ValidatorPrefix+"user_input") userMsg := c.GetString(consts.ValidatorPrefix + "user_input")
qianfan.GetConfig().AccessKey = variable.ConfigYml.GetString("BaiduCE.QianFanAccessKey") qianfan.GetConfig().AccessKey = variable.ConfigYml.GetString("BaiduCE.QianFanAccessKey")
qianfan.GetConfig().SecretKey = variable.ConfigYml.GetString("BaiduCE.QianFanSecretKey") qianfan.GetConfig().SecretKey = variable.ConfigYml.GetString("BaiduCE.QianFanSecretKey")
@ -29,23 +29,45 @@ func RequestStyle(c *gin.Context) (interface{}, error) {
// 读取prompt文件 // 读取prompt文件
systemMsgPath := variable.ConfigYml.GetString("BaiduCE.StyleGeneratePromptPath") systemMsgPath := variable.ConfigYml.GetString("BaiduCE.StyleGeneratePromptPath")
// 读取文件内容 // 读取文件内容
prompt, err := os.ReadFile(variable.BasePath+systemMsgPath) prompt, err := os.ReadFile(variable.BasePath + systemMsgPath)
if err != nil || len(prompt) == 0 { if err != nil || len(prompt) == 0 {
variable.ZapLog.Error(fmt.Sprintf("读取提示词文件失败: %v", err)) variable.ZapLog.Error(fmt.Sprintf("读取提示词文件失败: %v", err))
return nil, err return nil, err
} }
// add user history to chat history // add user history to chat history
userHistory,exist := c.Get(consts.ValidatorPrefix+"chat_history") userHistory, exist := c.Get(consts.ValidatorPrefix + "chat_history")
if exist&&userHistory!=nil{ if exist && userHistory != nil {
// TODO: check if userHistory is of type []struct{Role string;Content string} // check if userHistory is of type []struct{Role string;Content string}
userHistory := userHistory.([]struct{Role string;Content string}) historySlice, ok := userHistory.([]interface{})
if len(userHistory)%2!=0{ if !ok || len(historySlice)%2 != 0 {
variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v", userHistory)) variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v", userHistory))
return nil, fmt.Errorf("用户历史对话格式错误") return nil, fmt.Errorf("用户历史对话格式错误")
} }
for _,msg := range userHistory{
chatHistory = append(chatHistory, qianfan.ChatCompletionMessage{Role:msg.Role,Content:msg.Content}) // convert userHistory to []qianfan.ChatCompletionMessage
var chatHistoryConverted []qianfan.ChatCompletionMessage
for _, item := range historySlice {
if itemMap, ok := item.(map[string]interface{}); ok {
role, roleOk := itemMap["role"].(string)
content, contentOk := itemMap["content"].(string)
if roleOk && contentOk {
chatHistoryConverted = append(chatHistoryConverted, qianfan.ChatCompletionMessage{
Role: role,
Content: content,
})
} else {
variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v\nrole 或 content 类型断言失败", userHistory))
return nil, fmt.Errorf("用户历史对话格式错误")
}
} else {
variable.ZapLog.Error(fmt.Sprintf("用户历史对话格式错误: %v\n无法将 item 转换为 map[string]interface{}", userHistory))
return nil, fmt.Errorf("用户历史对话格式错误")
}
}
if len(chatHistoryConverted) > 0 && len(chatHistoryConverted)%2 == 0 {
chatHistory = append(chatHistory, chatHistoryConverted...)
} }
} }
@ -53,7 +75,7 @@ func RequestStyle(c *gin.Context) (interface{}, error) {
chatHistory = append(chatHistory, qianfan.ChatCompletionUserMessage(userMsg)) chatHistory = append(chatHistory, qianfan.ChatCompletionUserMessage(userMsg))
// define a stream chat client // define a stream chat client
response,err:=chat.Do(context.TODO(),&qianfan.ChatCompletionRequest{System: string(prompt),Messages: chatHistory}) response, err := chat.Do(context.TODO(), &qianfan.ChatCompletionRequest{System: string(prompt), Messages: chatHistory})
if err != nil { if err != nil {
variable.ZapLog.Error(fmt.Sprintf("对话失败: %v", err)) variable.ZapLog.Error(fmt.Sprintf("对话失败: %v", err))
return nil, err return nil, err

@ -1,7 +1,7 @@
### 角色 ### 角色
你是一个设计和 CSS 专家,能够根据用户需求生成精确的 CSS 样式。 如果用户提出与生成CSS样式无关的问题请回答“对不起我无法回答该问题” 你是一个设计和 CSS 专家,能够根据用户需求生成精确的 CSS 样式。只能使用css来生成对应的样式不能修改页面的html代码和使用js代码。 如果用户提出与生成CSS样式无关的问题请回答“对不起我无法回答该问题”
### 任务 ### 知识
为以下元素生成 CSS 样式类 不同的样式对应的element如下
标题:<hi>i为标题级别如 h1, h2 等) 标题:<hi>i为标题级别如 h1, h2 等)
文本块:<p> 文本块:<p>
块引用:<blockquote> 块引用:<blockquote>
@ -14,8 +14,11 @@
[element为不同样式类对应的元素名如文本框对应的element为p] [element为不同样式类对应的元素名如文本框对应的element为p]
### 输出 ### 输出
仅输出你编写的 CSS 内容,不要对其进行解释和输出其他内容。!important 仅输出你编写的 CSS 内容,不要对其进行解释和输出其他内容。!important
只需要精确输出用户需要生成的样式,不要生成用户未指定的样式。
### 示例 ### 示例
生成一个文本块样式,生成的样式如下所示。 #### 示例一
用户输入:生成一个文本块样式
输出:
``` css ``` css
.ck-content p.info-box { .ck-content p.info-box {
--background-size: 30px; --background-size: 30px;
@ -28,7 +31,10 @@
box-shadow: 5px 5px 0 #ffe6ef; box-shadow: 5px 5px 0 #ffe6ef;
} }
``` ```
生成一个代码框样式,生成的样式如下所示:
#### 示例二
用户输入:生成一个代码框样式
输出:
```css ```css
.ck-content pre.fancy-code { .ck-content pre.fancy-code {
border: 0; border: 0;
@ -52,7 +58,10 @@
box-shadow: 5px 5px 0 #0000001f; box-shadow: 5px 5px 0 #0000001f;
} }
``` ```
生成一个块引用样式,生成的样式如下所示
#### 示例三
用户输入:生成一个块引用样式
输出:
```css ```css
.ck-content blockquote.side-quote { .ck-content blockquote.side-quote {
font-family: 'Oswald'; font-family: 'Oswald';

@ -2,11 +2,7 @@ import { createApp } from 'vue';
import '../public/style.css'; import '../public/style.css';
import App from './App.vue'; import App from './App.vue';
import { CkeditorPlugin } from '@ckeditor/ckeditor5-vue'; import { CkeditorPlugin } from '@ckeditor/ckeditor5-vue';
import mitt from 'mitt';
const app = createApp(App); const app = createApp(App);
const emitter = mitt();
app.config.globalProperties.emitter = emitter;
app.use(CkeditorPlugin); app.use(CkeditorPlugin);
app.mount('#app'); app.mount('#app');

@ -3,7 +3,7 @@
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 350px; width: 450px;
height: 100%; height: 100%;
overflow-y: hidden; overflow-y: hidden;
transition: transform 0.3s ease; transition: transform 0.3s ease;

@ -327,7 +327,6 @@ export default {
wordSpacing: '' wordSpacing: ''
}, },
previewStyle: {}, previewStyle: {},
messages: [], //
}; };
}, },
mounted() { mounted() {
@ -395,10 +394,6 @@ export default {
displayMessage(text, sender) { displayMessage(text, sender) {
const messagesDiv = document.getElementById('messages'); const messagesDiv = document.getElementById('messages');
// messages
const previousButtonsMessage = messagesDiv.querySelectorAll('.preview-buttons');
previousButtonsMessage.forEach(buttons => buttons.remove());
const messageDiv = document.createElement('div'); const messageDiv = document.createElement('div');
messageDiv.className = 'message'; messageDiv.className = 'message';
// 使 pre text // 使 pre text
@ -412,28 +407,84 @@ export default {
// TODO css // TODO css
preElement.textContent = `文心一言:\n` + preElement.textContent; preElement.textContent = `文心一言:\n` + preElement.textContent;
messageDiv.style.backgroundColor = '#bdc3c7'; messageDiv.style.backgroundColor = '#bdc3c7';
//
this.previewStyleAtMessages(text);
}
// messagesDiv.scrollTop = messagesDiv.scrollHeight;
},
//
sendMessage() {
const userInput = document.getElementById('userInput');
const messageText = userInput.value;
if (messageText.trim() === '') return;
//
let chatHistory = [];
const messages = document.getElementById('messages').children;
for (let i = 0; i < messages.length; i++) {
if (i%4==0){
chatHistory.push({ Role: 'user', Content: messages[i].textContent });
}else if (i%4==1){
const assistantResponse = messages[i].textContent.replaceAll('文心一言:\n', '');
chatHistory.push({ Role: 'assistant', Content: assistantResponse });
}
}
console.log(chatHistory);
// Display user's message
this.displayMessage(messageText, 'user');
// APIresponse
// messages
// TODO
// const chat_history = []
axios({
url: 'http://localhost:14514/admin/ai_layout/style_generate',
method: 'POST',
data: {
user_input: userInput.value,
...(chatHistory.length > 0 && { chat_history: chatHistory }),
}
})
.then(response => {
console.log(response);
this.displayMessage(response.data.data, 'ai')
})
.catch(error => {
console.error('Error:', error);
});
userInput.value = '';
},
//
previewStyleAtMessages(style) {
const messagesDiv = document.getElementById('messages');
// preview // preview
const previewWrapper = document.createElement('div'); const previewWrapper = document.createElement('div');
previewWrapper.style.border = '1px solid #ccc'; previewWrapper.style.border = '1px solid #ccc';
previewWrapper.style.display = 'flow-root'; previewWrapper.style.display = 'flow-root';
messagesDiv.appendChild(previewWrapper);
// 'preview' // 'preview'
const previewLabel = document.createElement('div'); const previewLabel = document.createElement('div');
previewLabel.textContent = 'preview'; previewLabel.textContent = 'preview';
previewWrapper.appendChild(previewLabel); previewWrapper.appendChild(previewLabel);
// //
const previewStyle = document.createElement('style'); const previewStyle = document.createElement('style');
// //
// csscss,css,} // csscss,css,}
const cssRegex = /css([\s\S]*)\}/; const cssRegex = /```css\n([\s\S]*?)```/;
const cssMatch = cssRegex.exec(text); const cssMatch = cssRegex.exec(style);
let cssText; // css
// css
if (cssMatch) { if (cssMatch) {
previewStyle.textContent = cssMatch[0].replace('css', ''); cssText = cssMatch[0].replace('css', '').replaceAll('```', '');
} else { } else {
previewStyle.textContent = text; cssText = style;
} }
previewStyle.textContent = previewStyle.textContent.replace(/\.ck-content/g, ''); previewStyle.textContent = cssText.replace(/\.ck-content/g, '');
document.head.appendChild(previewStyle); previewWrapper.appendChild(previewStyle);
// //
let previewElement; let previewElement;
@ -441,18 +492,25 @@ export default {
const styleRegex = /\.ck-content\s+([a-z]+)\.([a-z-]+)\s*\{/g; const styleRegex = /\.ck-content\s+([a-z]+)\.([a-z-]+)\s*\{/g;
let match; let match;
const classNames = []; const classNames = [];
while ((match = styleRegex.exec(text)) !== null) { while ((match = styleRegex.exec(cssText)) !== null) {
if (!previewElement) { if (!previewElement) {
previewElement = document.createElement(match[1]); previewElement = document.createElement(match[1]);
previewElement.textContent = 'AaBbCcDdEeFf'; // previewElement.textContent = 'AaBbCcDdEeFf';
const previewText = document.createElement('p');
previewText.textContent = 'AaBbCcDd';
previewElement.appendChild(previewText);
previewWrapper.appendChild(previewElement); previewWrapper.appendChild(previewElement);
} }
classNames.push(match[2]);
// classNameclass
const newClassName = match[2]+"_"+Math.floor(Math.random()*1000);
previewStyle.textContent = previewStyle.textContent.replaceAll(match[2], newClassName);
classNames.push(newClassName);
} }
if (previewElement) { if (previewElement) {
previewElement.className = classNames.join(' '); previewElement.className = classNames.join(' ');
} }
messagesDiv.appendChild(previewWrapper);
// //
const buttonsMessageDiv = document.createElement('div'); const buttonsMessageDiv = document.createElement('div');
@ -479,6 +537,7 @@ export default {
classes: classNames classes: classNames
}; };
console.log(styleDefinition); console.log(styleDefinition);
console.log(cssText);// css
}; };
// clear // clear
const clearButton = document.createElement('el-button'); const clearButton = document.createElement('el-button');
@ -492,48 +551,12 @@ export default {
while (messagesDiv.firstChild) { while (messagesDiv.firstChild) {
messagesDiv.removeChild(messagesDiv.firstChild); messagesDiv.removeChild(messagesDiv.firstChild);
} }
// style
document.head.removeChild(previewStyle);
}; };
// //
buttonsMessageDiv.appendChild(saveButton); buttonsMessageDiv.appendChild(saveButton);
buttonsMessageDiv.appendChild(clearButton); buttonsMessageDiv.appendChild(clearButton);
messagesDiv.appendChild(buttonsMessageDiv); messagesDiv.appendChild(buttonsMessageDiv);
} }
// messagesDiv.scrollTop = messagesDiv.scrollHeight;
},
sendMessage() {
const userInput = document.getElementById('userInput');
const messageText = userInput.value;
if (messageText.trim() === '') return;
// Display user's message
this.displayMessage(messageText, 'user');
// APIresponse
// messages
// TODO
chat_history = []
axios({
url:'http://localhost:14514/admin/ai_layout/style_generate',
method: 'POST',
data:{
user_input: userInput.value
}
})
.then(response => {
// let formatedResponse = response.data.response;
// this.displayMessage(formatedResponse, 'ai');
console.log(response);
this.displayMessage(response.data.data,'ai')
})
.catch(error => {
console.error('Error:', error);
});
userInput.value = '';
},
}, },
components: { components: {
// //

Loading…
Cancel
Save