小明与企业客服升级的故事
1 场景背景:让客户满意的挑战
小明近期在一家电商企业实习,发现公司常接到顾客各种各样的问题:
- "你们的最新产品有什么功能?"
- "能否介绍一下优惠活动?"
- "是否支持7天无理由退换?"
- "我怎么查物流?"
人工客服应接不暇,于是小明提出打造一款 "自动客服机器人" 的想法,专门回答常见问题或提供产品介绍。除此之外,市场部门也希望能自动生成一段营销文案 来吸引顾客。小明决定用深度学习中的RNN文本生成来为企业客服带来更多"创意回复"的可能性。
2 目标与原理:RNN帮助"写文案、答问题"
-
目标
- 降低客服压力:自动回复部分重复性问题;
- 生成简易文案:基于用户关键字自动组成一句或几句介绍文本。
-
为什么使用RNN来做文本生成
- 序列数据处理:客服对话、产品描述都是自然语言文本;
- 灵活回答:既能在已有数据基础上"学习"企业话术,又能在生成阶段适当拼接新词汇,提供多样化回复;
- 融入对话场景:后续也可扩展为更高级的Seq2Seq或Transformer结构。
3 从数据到部署:完整代码示例
下面以两个脚本 train.py
和 app.py
来演示:
train.py
:包含极简示例数据、数据处理、RNN 模型构建与训练,并保存为 H5 格式(Keras 3 兼容)。app.py
:使用 Flask 加载已训练的 H5 模型,实现一个简易的网页界面,让用户输入开头文字,系统自动继续生成文本。
提示:以下示例仅作演示用,数据量非常少,生成效果可能"驴唇不对马嘴"。在商业场景需准备更多语料、做更强大模型或使用检索式问答等。
3.1 项目目录结构
在名为 rnn_text_generation_demo
的文件夹中放置以下文件:
rnn_text_generation_demo/
├── train.py # 训练脚本
├── app.py # Flask 部署脚本
└── saved_model/ # 保存模型用,脚本运行后自动生成
3.2 训练脚本:train.py
请将下面代码复制到 train.py
文件里。它会执行以下步骤:
- 准备一小段原始文本数据(客服与产品描述示例)。
- 清洗、分词,构建词典。
- 组织 (input, target) 序列进行训练。
- 构建并训练一个简单的 LSTM 模型。
- 以 H5 格式 保存模型 + 词典信息(为 Keras 3 兼容重点)。
python
"""
train.py
示例:使用 tf.keras + RNN(LSTM) 做简单的文本生成训练,并以H5方式保存模型,兼容Keras 3。
"""
import tensorflow as tf
import re
import os
# ============= 1. 示例数据(极简) =============
raw_text_corpus = [
"我们的新款手机屏幕是6.5英寸,拥有1080P高清分辨率。",
"这款耳机支持降噪功能,续航时间可达24小时。",
"满500减50的活动正在进行中,抓紧抢购哦!",
"这款运动鞋防水、防滑,适合户外运动。",
"物流信息可通过订单号在官网查询。",
"我们的客服团队将竭诚为您服务。",
"欢迎咨询产品详情或优惠活动。"
]
# ============= 2. 数据清洗与分词 =============
def simple_clean_text(text):
# 仅作基本示例:去除特殊字符,只保留中英文、数字和常见标点
text = re.sub(r"[^a-zA-Z0-9\u4e00-\u9fa5。,!?:,\.\!\?\:]", "", text)
return text
def simple_tokenize(text):
"""
极简分词示例:把中文当作逐字拆分,英文数字以字符拆分。
真实项目请使用jieba或更成熟分词工具。
"""
text = text.strip()
tokens = []
for char in text:
if char.strip():
tokens.append(char)
return tokens
cleaned_sentences = []
for line in raw_text_corpus:
line = simple_clean_text(line)
tokens = simple_tokenize(line)
cleaned_sentences.append(tokens)
# ============= 3. 建立词典 =============
all_tokens = []
for tokens in cleaned_sentences:
all_tokens.extend(tokens)
unique_tokens = list(set(all_tokens))
# 保留一些特殊token
word_to_id = {"<PAD>":0, "<UNK>":1}
for idx, token in enumerate(unique_tokens, start=2):
word_to_id[token] = idx
id_to_word = {v:k for k,v in word_to_id.items()}
vocab_size = len(word_to_id) # 词典大小
# ============= 4. 组织 (input, target) 数据 =============
input_sequences = []
target_sequences = []
for tokens in cleaned_sentences:
token_ids = [word_to_id.get(t, 1) for t in tokens]
for i in range(1, len(token_ids)):
input_part = token_ids[:i]
target = token_ids[i]
input_sequences.append(input_part)
target_sequences.append(target)
max_len = 10
from tensorflow.keras.preprocessing.sequence import pad_sequences
X = pad_sequences(input_sequences, maxlen=max_len, padding='pre', value=0)
y = tf.convert_to_tensor(target_sequences)
print("样本数:", len(X))
print("词典大小:", vocab_size)
# ============= 5. 构建 LSTM 模型 =============
model = tf.keras.Sequential([
tf.keras.layers.Embedding(input_dim=vocab_size,
output_dim=64,
input_length=max_len),
tf.keras.layers.LSTM(128),
tf.keras.layers.Dense(vocab_size, activation='softmax')
])
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.summary()
# ============= 6. 训练 =============
model.fit(X, y, batch_size=4, epochs=20)
# ============= 7. 以 H5 格式 保存模型 =============
os.makedirs("saved_model", exist_ok=True)
save_path = "saved_model/my_rnn_model.h5" # 使用H5后缀
model.save(save_path)
print(f"模型已保存到: {save_path}")
# ============= 8. 保存词典与参数信息 =============
import pickle
dict_info = {
"word_to_id": word_to_id,
"id_to_word": id_to_word,
"max_len": max_len
}
with open("saved_model/dict_info.pkl", "wb") as f:
pickle.dump(dict_info, f)
print("词典和参数信息已保存到: saved_model/dict_info.pkl")
如何运行:
- 进入
rnn_text_generation_demo
目录 - 执行
python train.py
- 若无报错,训练结束后会在
saved_model/
目录下生成my_rnn_model.h5
和dict_info.pkl
。
3.3 Flask部署脚本:app.py
下面是 Flask 的部署示例,放到 app.py
文件中。它将做以下几步:
- 加载我们在
train.py
中保存的 H5 模型 (my_rnn_model.h5
); - 导入词典和最大序列长度;
- 提供一个网页输入框,让用户输入开头的文字;
- 调用模型来逐词生成后续文本;
- 返回生成的结果到网页上显示。
python
"""
app.py
示例:使用Flask部署训练好的RNN模型,实现简易的"自动续写"功能。
"""
import os
import pickle
from flask import Flask, request
import tensorflow as tf
import numpy as np
import re
app = Flask(__name__)
# ============= 1. 加载模型和词典信息 (兼容Keras 3) =============
model_path = "saved_model/my_rnn_model.h5"
model = tf.keras.models.load_model(model_path)
with open("saved_model/dict_info.pkl", "rb") as f:
dict_info = pickle.load(f)
word_to_id = dict_info["word_to_id"]
id_to_word = dict_info["id_to_word"]
max_len = dict_info["max_len"]
vocab_size = len(word_to_id)
def simple_clean_text(text):
text = re.sub(r"[^a-zA-Z0-9\u4e00-\u9fa5。,!?:,\.\!\?\:]", "", text)
return text.strip()
def simple_tokenize(text):
tokens = []
for char in text:
if char.strip():
tokens.append(char)
return tokens
# ============= 2. 构建文本生成函数 =============
def generate_text_rnn(model, start_string, num_generate=10):
start_string = simple_clean_text(start_string)
tokens = simple_tokenize(start_string)
token_ids = [word_to_id.get(t, 1) for t in tokens]
# 保证输入长度不超过max_len
if len(token_ids) > max_len:
token_ids = token_ids[-max_len:]
input_eval = np.zeros((1, max_len), dtype=np.int32)
input_eval[0, -len(token_ids):] = token_ids
result = tokens[:]
for _ in range(num_generate):
predictions = model.predict(input_eval, verbose=0)
predicted_id = np.argmax(predictions[0])
predicted_word = id_to_word.get(predicted_id, "<UNK>")
result.append(predicted_word)
seq_list = list(input_eval[0])
seq_list.append(predicted_id)
seq_list = seq_list[-max_len:]
input_eval[0] = seq_list
return "".join(result)
# ============= 3. Flask 路由 =============
@app.route("/", methods=["GET", "POST"])
def index():
html_form = """
<html>
<head>
<title>RNN Text Generation Demo</title>
</head>
<body>
<h1>简易RNN文本生成演示</h1>
<form method="post">
<label>请输入开头文本:</label><br>
<input type="text" name="user_input" style="width:400px;" /><br><br>
<button type="submit">生成</button>
</form>
<hr>
{}
</body>
</html>
"""
if request.method == "POST":
user_input = request.form.get("user_input", "")
if user_input.strip():
generated_text = generate_text_rnn(model, user_input, num_generate=20)
return html_form.format(f"<p><strong>生成结果:</strong> {generated_text}</p>")
else:
return html_form.format("<p>请输入有效文本。</p>")
else:
return html_form.format("")
if __name__ == "__main__":
app.run(debug=True, port=5000)
如何运行:
- 确保
train.py
已成功执行并生成my_rnn_model.h5
和dict_info.pkl
; - 执行
python app.py
; - 打开浏览器访问
http://127.0.0.1:5000/
; - 在输入框里键入一些文字(如"我们的新款手机"),点击"生成",即可得到后续词生成的演示结果。

5 结果验证与改进方向
- 生成结果:由于示例数据非常有限,你可能得到语句片段像"我们的新款耳机支持客服活动满500减"。这说明模型只是在小样本上拼接 learned tokens,缺乏长语境训练。
- 数据规模:商业场景通常需要数千甚至数十万条客服/产品记录,以提升模型的生成质量;
- 模型结构:可以尝试多层RNN、双向RNN、Seq2Seq、Transformer等,更适合问答或复杂上下文;
- 部署:若要上线,需要考虑并发量、响应速度、GPU加速或容器化(Docker/K8s)等。
6 小结:企业客服升级的第一步
- 你已看到一个从数据 →训练 →保存 →Flask加载的端到端流程;
- 通过 H5 文件 来存储模型,以便在 Keras 3 环境下顺利使用;
- 尽管示例极其简化,却为你在"对话与文案生成"的商业项目中打下基础。如果想让客服机器人真正可用,还需结合"知识库检索""问答匹配"与"强化生成式"方法,使回复既有创意 又能正确地回答顾客问题。
祝你在企业客服升级之路上一切顺利,为公司和客户提供更优质、更高效的服务体验!