一、使用腾讯云HAI + TDSQL-C MySQL Serverless实现AI海报文案智能生成:
互联网产品的核心就是流量生意,由于运营活动部门,主要负责公司的活动策划与方案落地,高效的拉来流量并进行转化,经常需要使用小程序中的海报功能用于业务推广,而且活动的类型也比较繁杂,比如清理库存、新品上市、阶梯式折扣、促销活动、秒杀活动等等。
但是,想要写好海报文案和分享文案需要很多技巧,以确保信息清晰、吸引人,并能有效传达意图。同时,也需要花费大量的时间来思考,通常运营人员需要大量百度一些文案来参考,非常的耗费时间、人力、资源。
【实验手册思维发散】:
既然实验手册能通过自然语言AI生成需要分析的SQL语句,那么是不是可以通过一些提示词来给AI来生成所需要的海报、分享的文案呢?顺着这个思路,马上把实验手册Demo的示例改改来实现一下,思路是如下:
- ①. 定义好提示词,即生成文案的主题、使用场景、受众等信息。
- ②. 通过ChatOllama模型来AI生成相关需要的海报、分享的文案。
由于也是刚刚接触AI相关的技术领域,对于代码不是很熟悉,刚好腾讯云出品了一款“AI代码助手”,让他来帮助我们一起来帮我学、帮我做、帮我写,有效的加快我们学习的步伐,通过简单的嵌套VsCode IDE中使用,非常方便。
1. 什么是ChatOllama?
ChatOllama是一个开源的大模型聊天机器人框架,它允许开发者基于自己的数据集训练出定制化的对话模型,基于大规模对话数据集进行训练,采用高效的算法和硬件加速技术,确保模型训练和推理的速度。以下是ChatOllama的详细描述:
2. 关键代码解释:
在查看手册提示的示例代码时,发现主要逻辑还是在ChatPromptTemplate.from_template和text_2_sql_chain2、text_2_sql_chain.invoke这三块代码逻辑上,这里应该就是AI生成代码的主要逻辑,因为也不太清楚啥意思,放到腾讯云AI代码助手上进行解释:
经过对代码的研究和不断的优化相关提示词的实践过程,最终,改造为以下的代码逻辑后,即可通过ChatOllama模型生成了一些符合要求的文案(是一个持续迭代优化提示词的过程):
from langchain_community.utilities import SQLDatabase
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.chat_models import ChatOllama
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
import yaml
import mysql.connector
from decimal import Decimal
import plotly.graph_objects as go
import plotly
import pkg_resources
import matplotlib
#获取llm用于提供AI交互
ollama = ChatOllama(model='llama3.1:8b',base_url='http://150.109.254.40:6399/')
# 获得schema
def get_schema(db):
schema = mysql_db.get_table_info()
return schema
def getResult(content):
global mysql_db
# 数据库连接
mysql_db = SQLDatabase.from_uri(f"mysql+mysqlconnector://{'用户名'}:{密码}@{'IP地址'}:{端口号}/{'数据库名称'}")
# 获得 数据库中表的信息
#mysql_db_schema = mysql_db.get_table_info()
#print(mysql_db_schema)
template = """
帮我生成海报相关的文案,需要返回4条数据
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
text_2_sql_chain = (
RunnablePassthrough.assign(schema=get_schema)
| prompt
| ollama
| StrOutputParser()
)
# 执行langchain 获取操作的sql语句
sql = text_2_sql_chain.invoke({"question": content})
print(sql)
getResult("创意主题是上海城市需要进行爱肯拿狗粮的中秋活动,需要生成海报文案,文案需要包括上海的一些地标名称,文案需要包含表情")
最终在修改手册提供的代码后,通过传入不同的主题提示词来生成不同的文案,上面只是一个简单的Demo演示,在生产环境中还是需要不断的优化“tempate” – 即AI中需要用到的Prompt(提示词)。
Prompt在自然语言处理中的应用非常广泛,从简单的问答系统到更复杂的机器翻译和文本生成,甚至包括在法律、金融和医疗领域中的应用。Prompt的设计不仅仅是简单地将问题转换为指令,而且要考虑到上下文、语法和语言风格等多个方面。
【文案生成方案落地】:
- ①. 活动文案管理模块:将不同活动的提示词存到TDSQL-C MySQL Serverless数据库中。
- ②. 活动文案详情模块:在不同的活动创建文案记录时,根据提示词调用HAI提供ChatOllama在线API服务来AI生成相关需要的海报、分享的文案,并且处理返回的文本数据结构化。
- ③. 活动文案审核模块:生成的AI文案,也可以进行修改,在不同的环节也可以进行拒绝和修改,或者AI重新批量生成一批、生成单个。
3. 活动文案管理模块:
不同的活动生成的提示词肯定是不通用的,如果要实现系统化的功能,肯定是需要将不同活动的提示词存到在数据库TDSQL-C MySQL Serverless中,这样的话当进行不同活动调用公共服务HAI ChatOllama模型的时候,可以传入不同的参数,再生成不同的结果文案。
先在TDSQL-C MySQL Serverless中,创建一张活动的主表,id表示活主表的主键ID,activityName表示活动的名称,activityPrompt表示活动的提示词,status表示状态。
CREATE TABLE `activitys` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`activityName` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`activityPrompt` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`status` char(1) COLLATE utf8mb4_unicode_ci DEFAULT 1,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
创建数据表完成后,即可使用Go的Gin框架代码添加相关Form表单字段写入数据库中,因为ID是自增主键、状态设置了默认值,只需要定义2个字段(activityName、activityPrompt)的Activitys结构体即可,以下是活动主表CURD四种操作的代码:
type Activitys struct {
ID int `json:"id"`
ActivityName string `json:" activity_name"`
ActivityPrompt string `json:" activity_prompt "`
}
func createActivity(c *gin.Context) {
var activity Activity
if err := c.ShouldBindJSON(&activity); err!= nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
activities = append(activities, activity)
c.JSON(http.StatusCreated, activity)
}
func getActivity(c *gin.Context) {
id := c.Param("id")
for _, activity := range activities {
if activity.ID == id {
c.JSON(http.StatusOK, activity)
return
}
}
c.JSON(http.StatusNotFound, gin.H{"error": "Activity not found"})
}
func updateActivity(c *gin.Context) {
id := c.Param("id")
var activity Activity
if err := c.ShouldBindJSON(&activity); err!= nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
for i, a := range activities {
if a.ID == id {
activity.ID = id
activities[i] = activity
c.JSON(http.StatusOK, activity)
return
}
}
c.JSON(http.StatusNotFound, gin.H{"error": "Activity not found"})
}
func deleteActivity(c *gin.Context) {
id := c.Param("id")
for i, activity := range activities {
if activity.ID == id {
activities = append(activities[:i], activities[i+1:]...)
c.JSON(http.StatusOK, gin.H{"message": "Activity deleted"})
return
}
}
c.JSON(http.StatusNotFound, gin.H{"error": "Activity not found"})
}
前端使用的是Vue3的技术栈写的Form表单与Table列表的代码,使用的是element-ui,以下是前端Vue3的相关代码:
<el-table
:data="state.tableList"
border
style="width: 100%"
:header-cell-style="{ background: 'linear-gradient(rgb(244, 247, 254) 0%, rgb(228, 237, 255) 100%)', color: '#333333' }"
header-align="center"
>
<el-table-column type="index" label="序号" width="60" header-align="center" align="center"/>
<el-table-column prop="activityName" label="活动任务名称" width="250" header-align="center" align="center"/>
<el-table-column prop="activityPrompt" label="活动任务提示词" header-align="center" align="center" />
<el-table-column prop="status" label="状态" width="160" header-align="center" align="center">
<template #default="scope">
<div>{{ state. activityStatus[scope.row.status] || '' }}</div>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="center" width="120">
<template #default="scope">
<div style="display: flex;align-items: center;justify-content: center;">
<div style="color: #409eff;font-size: 14px;font-weight: 500;padding: 0 10px;cursor: pointer;" @click="show(scope.row)">详情</div>
<div style="color: #409eff;font-size: 14px;font-weight: 500;padding: 0 10px;cursor: pointer;" @click="editor(scope.row)">编辑</div>
</div>
</template>
</el-table-column>
</el-table>