utils.py:
# 所有和ai交互的代码放进utils.py里(utils 通常是 “utilities” 的缩写,意为 “实用工具” 或 “实用函数”)
from langchain.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_community.utilities import WikipediaAPIWrapper
import os
# 根据主题和时长,规定创造性,获得视频的标题和脚本
def generate_script(subject, video_length, creativity, api_key):
model = ChatOpenAI(api_key=api_key, base_url="https://api.gptsapi.net/v1",
temperature=creativity) # 初始化模型
# 获得视频的标题
title_template = ChatPromptTemplate.from_messages(
[
("human", "请为主题为‘{subject}’的视频起一个吸引人的标题")
]
) # 定义提示模板
title = (title_template | model).invoke(
{
"subject": subject
}
).content # 调用链的invoke,获得最终结果
# 调用维基百科的API获得相关信息
search = WikipediaAPIWrapper(lang="zh")
search_result = search.run(subject)
# 获得视频的脚本内容
script_template = ChatPromptTemplate.from_messages(
[
("human",
"""你是一位短视频频道的博主。根据以下标题和相关信息,为短视频频道写一个视频脚本。
视频标题:{title},视频时长:{duration}分钟,人的正常语速约为每分钟 200 字,所以生成的脚本长度必须在 {min_length} 到 {max_length} 字之间。
要求开头抓住眼球,中间提供干货内容,结尾有惊喜,脚本格式也请按照【开头、中间,结尾】分隔。
整体内容的表达方式要尽量轻松有趣,吸引年轻人。
脚本内容可以结合以下维基百科搜索出的信息,但仅作为参考,只结合相关的即可,对不相关的进行忽略:
```{wikipedia_search}```
注意:脚本长度不应该包括维基百科内容的字数。
""")
]
)
# 计算最小和最大长度
min_length = video_length * 200 - 20
max_length = video_length * 200 + 20
script = (script_template | model).invoke(
{
"title": title,
"duration": video_length,
"wikipedia_search": search_result,
"min_length": min_length,
"max_length": max_length
}
).content
return search_result, title, script
# 示例调用
# print(generate_script("deepseek大模型", 0.5, 0.7, os.getenv("OPENAI_API_KEY")))
main.py:
# 网站的主页
import streamlit as st
from utils import generate_script
st.title("视频脚本生成器")
# 侧边栏
with st.sidebar:
api_key = st.text_input("请输入OpenAI API密钥:",type="password")
st.markdown("[获取api密钥](https://2233.ai/api)")
# 输入其他信息
subject = st.text_input("请输入视频的主题:")
video_length = st.number_input("请输入视频的大致时长(单位:分钟)",min_value=0.1,step=0.1)
creativity = st.slider("请输入视频脚本的创造力(数字越小越严谨,数字越大越天马行空):",
min_value=0.0,max_value=1.0,value=0.5,step=0.1)
# 提交按钮(需要校验,点击提交按钮前输入了api密钥,并且输入了视频主题)
submit = st.button("生成脚本")
if submit and not api_key:
st.info("请输入你的OpenAI API密钥")
st.stop() #stop让后面的代码不再执行
if submit and not subject:
st.info("请输入视频的主题")
st.stop()
if submit:
with st.spinner("AI正在思考中,请稍等···"): #“思考中”组件,只要缩进里的代码没有执行完,就一直有个加载的效果
search_result,title,script = generate_script(subject,video_length,creativity,api_key)
st.success("视频脚本已生成!")
st.subheader("标题:")
st.write(title)
st.subheader("视频脚本:")
st.write(script)
with st.expander("维基百科搜索结果:"): #折叠展开组件
st.info(search_result)
补充:
1、st.info:显示的信息会在一个蓝色背景的容器中呈现,更侧重于显示特定的信息性提示
st.write:会根据输入内容以不同样式显示,如普通文本正常显示,Markdown 文本会进行相应的格式渲染,列表和字典会以表格形式展示。功能更强大、更通用。
2、st.title:主标题
st.subheader:副标题
3、st.spinner:显示加载提示,用来告知用户应用正在处理任务,避免用户因为等待而产生困惑或不耐烦。
使用 st.success显示的消息会被放置在一个带有绿色边框和背景的容器中,这种样式设计能让成功消息在页面上非常醒目,使用户能快速注意到操作已成功完成。
4、通过将相关功能封装在
generate_script
函数中,main.py
只需要导入这个函数就可以使用其功能,而不需要关心其内部实现细节和相关的导入语句,即不需要再次导入openai相关的库。5、如果在使用 Streamlit 的 number_input 函数时仅设置了 min_value 和 max_value,而没有指定 value 参数,那么数字输入框的初始值会默认为 min_value。如果没有提供 min_value,则默认的初始值将是 0(除非指定了 value 参数来覆盖这个默认值)。
6、
st.stop()
并不是结束整个 Python 程序,而是停止 Streamlit 应用的当前执行流程,不再执行后续的 Streamlit 命令。如果这个 Streamlit 应用是在服务器上运行,服务器仍然在运行,并且用户可以继续与应用进行交互(例如重新输入内容)。
报错记录(详细报错信息可在部署页面的右下角查看):
1、安装依赖错误:
requirements.txt不能用pip freeze生成,会很混乱,交给ai总结即可
2、import错误:
langchain
langchain-openai
langchain-community
streamlit
openai
python-dotenv
wikipedia #虽然写的是从langchain里导入,但是有bug,就按照ai的建议加上一个独立的wikipedia
(尽管 langchain-community 或其相关模块可能试图导入或使用 wikipedia 包,但这个包本身并不是这些库的默认依赖项。因此,如果您在代码中使用了 WikipediaAPIWrapper 或者其他需要 wikipedia 包的功能,您需要手动安装它。)
3、生成的视频脚本长度不会自己调节
prompt设计得不好,后来加上了对“脚本长度”的详细解释