0.小学生作文润色插件【作文乐无忧】开发
0.1 项目来源
本项目来源于生活中经常需要帮助作为小学生的侄女修改作文、发言稿等小写作项目,经常是比较忙的时候接到电话,又要的比较急,特别浪费时间,于是经常用文心一言来进行文章修改润色。发现只要prompt写得好,绝对能够达到润色的地步,同时保留原作者的写作思路和习惯,因此萌发做成插件,分享给有需求的朋友。
0.2 开发构想
当前,小学生在写作过程中常常面临语言表达不清、结构混乱等问题。为了帮助他们提高写作水平,我们计划开发一款小学生作文润色插件。该插件的主要功能是通过上传小学生作文,利用文心一言进行润色修改,并给出具体的改动建议。我们的目标是让小学生能够更轻松地完成优质作文,提升他们的写作兴趣和自信心。
0.3 插件效果
1.项目说明书
1.1 项目背景与目标
本项目来源于生活中经常需要帮助作为小学生的侄女修改作文、发言稿等小写作项目,经常是比较忙的时候接到电话,又要的比较急,特别浪费时间,于是经常用文心一言来进行文章修改润色。发现只要prompt写得好,绝对能够达到润色的地步,同时保留原作者的写作思路和习惯,因此萌发做成插件,分享给有需求的朋友。 当前,小学生在写作过程中常常面临语言表达不清、结构混乱等问题。为了帮助他们提高写作水平,我们计划开发一款小学生作文润色插件。该插件的主要功能是通过上传小学生作文,利用文心一言进行润色修改,并给出具体的改动建议。我们的目标是让小学生能够更轻松地完成优质作文,提升他们的写作兴趣和自信心。
1.2 项目流程
- 1.上传作文:小学生将作文,通过插件上传至服务器。
- 2.文心一言润色:系统调用文心一言API,对上传的作文进行润色修改。
- 3.给出改动建议:根据文心一言的润色结果,插件生成具体的改动建议,展示给小学生。
- 4.保存与分享:润色后的作文及改动建议保存至服务器,返回下载链接。
1.3 技术实现
- 1.插件开发:使用flask/fastapi开发插件,实现上传作文、展示改动建议等功能。
- 2.调用文心一言API:使用HTTP请求调用文心一言API进行作文润色。
- 3.生成改动建议:根据文心一言润色结果,通过对比算法生成具体的改动建议。
- 4.保存与分享功能:作文保存至本地,分享链接,或者通过链接下载润色后文档。
1.4 预期成果与影响
- 1.提高小学生写作水平:通过润色修改与改动建议,帮助小学生更直观地了解写作中存在的问题并改进,从而提升他们的写作能力。
- 2.提升写作兴趣与自信心:插件降低了写作难度,使小学生更易于完成优质作文,从而增强他们的写作兴趣和自信心。
- 3.减轻教师负担:插件辅助教师批改作文,减轻他们的工作负担,使他们有更多时间关注学生的个人发展。
2.准备工作
2.1 logo准备
插件logo是必须的,但是好多人设置后,logo不显示,为什么呢?主要是图片资源没有部署在公网,不能够获取到。怎么解决呢?有一个非常好的办法就是在aistudio上写项目,图片上传至notebook中,这样图片就可以访问,例如作文图标如下:
获取的链接地址如下:
ai-studio-static-online.cdn.bcebos.com/f4522e97c83...
2.2 服务器准备
- 为什么需要服务器?因为要公网部署服务。
- 为什么需要域名?因为跨域访问需要域名。
- 为什么需要https?因为需要跨域,文心一言是https的,所以部署服务的服务器就需要https。
我的域名服务器:www.erniebotplugins.cn ,需要部署插件的可以联系我。
2.3 支出
- 购买服务器(一年期双十一最低配,99一年)
- 购买cn域名(一年期,优惠后8块)
2.4 域名选择
本来想注册 erniebot.cn ,结果手慢被人注册了,只好注册 erniebotplugins.cn
3.服务发布
3.1 ai-plugin.json
该文件描述了插件的基本接口,重要的及需要注意点如下:
- name_for_XXX 不需要重复,如果重名就会失败
- auth 需要配置,原先不需要auth配置的插件会失效
- logo_url 必须是公网可访问的png,尺寸48*48
- 各类端口 例如8082,是本地发布服务的端口
json
{
"schema_version":"v1",
"name_for_human":"小学生作文润色-作文乐无忧",
"name_for_model":"Primary-School-Students-Essay-Polishing---Worry-free-Writing",
"description_for_human":"支持用户上传word文档,进行作文润色,并生成作文评语。",
"description_for_model":"Support users to upload txt files and generate wordcloud images.",
"auth":{
"type":"service_http",
"authorization_type":"Basic"
},
"api":{
"type":"openapi",
"url":"http://127.0.0.1:8022/openapi.yaml"
},
"logo_url":"https://ai-studio-static-online.cdn.bcebos.com/f4522e97c83745e8bc4bf3c586c2762ccca5727ea09e4031bf74e2292ea35f86",
"contact_email":"155203350@qq.com",
"legal_info_url":"https://www.erniebotplugins.cn/legal",
"examples": {
"url": "http://127.0.0.1:8022/example.yaml"
},
"msg_content": {
"url": "http://127.0.0.1:8022/msg_content.yaml"
}
}
3.2 openapi.yaml
该文件描述了插件的功能,重要的及需要注意点如下:
- servers: 该地址必须是公网地址
- paths: 访问的url,必须跟起的服务url一致
yaml
openapi: 3.0.1
info:
title: word cloud API
version: 1.0.0
description:
servers:
- url: https://www.erniebotplugins.cn:8082
paths:
/analyze/essay/polishing:
post:
operationId: analyze
description:
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AnalyzeRequestSchema'
responses:
'200':
description: Successful SSE response
content:
text/event-stream:
schema:
$ref: '#/components/schemas/AnalyzeResponseSchema'
components:
schemas:
AnalyzeRequestSchema:
type: object
properties:
query:
type: string
description: 文字输入。如果请求中只有文字输入,fileUrl不填。
fileUrl:
type: string
description: 文字路径地址。如果请求中有地址,只填写fileUrl参数,切勿填写历史记录中的生成结果
AnalyzeResponseSchema:
type: object
properties:
errCode:
type: integer
description: 插件响应的业务错误码
errMsg:
type: string
description: 插件响应的业务错误信息
status:
type: string
description: 当前请求的状态信息
result:
type: string
description: 作文润色成结果
actionName:
type: string
description: 执行动作名称
actionContent:
type: string
description: 执行动作内容
3.3 msg_content.yaml
进度提示
yaml
analyze:
success:
# errCode = 0 是默认成功,无需单独定义
# 有时使用sse返回,执行过程中有很多过程,都应该定义为成功
- errCode: statistics
actionName: 进行作文润色
actionContent: 作文润色完成
- errCode: generate
actionName: 正在生成作文评语
actionContent: 作文评语生成完成
- errCode: output
actionName: 正在输出作文和作文评语
actionContent: 作文和作文评语输出完成
3.4 example.yaml
主要是给出示例,需要特别注意的是空格位置,yaml对此特别敏感
yaml
version: 0.0.1
examples:
- context: # 对话历史
- role: user
content: "帮我修改润色小学生作文,微笑多彩的小贝壳 XXX小学2022年度最美少年刘东东 个人宣传资料 刘东东是武功县普集镇中心小学五(1)班的一名学生,今年12岁,在班级担任班长,大队委员,英语课代表等职务。几年来,在老师的精心教导和培育下,在学习上、生活上有了很大进步。
在家里,她尊敬长辈,孝敬老人,独立自强,热爱劳动。奶奶的眼睛看东西很模糊,她会充当奶奶的眼睛,帮奶奶熬中药,端饭菜端,帮奶奶收拾东西,陪奶奶散步、聊天,只要姥姥有需要,她跑前跑后,都不觉得累。生活中,她从未有过多的要求,不挑吃穿,不乱花零用钱;父母平时工作忙,无法辅导功课,她每天自觉完成作业,温习功课;生活教会了她做饭、淘米、炒菜、洗碗、擦地板、洗衣服,每天完成功课后主动干家务。
在学校里,她是一名挺懂事的"小大人",老师和同学都很信任她。作为班长,她能够处处以身作则,为同学树立了榜样,在带头搞好学习和维护班级团结,对老师交给的任务,总是做得有条不紊,是老师的好帮手。学习上,上学从不迟到或早退,上课专心听课,独立思考,认真完成各科作业,主动帮助学习有困难的同学,把自己的学习经验和方法传达给他们,是同学们的好伙伴,上学期被评为"优秀大队干部"。
她是一枚小贝壳,是老师的海洋,给了她斑斓的色彩,成长的路是艰辛而漫长的,希望她用汗水收获自己人生路的彩虹。"
- role: bot
# 触发插件
plugin:
# 应当触发的接口operationId
operationId: analyze
# 思考过程,对触发有帮助
thoughts: 这是一个帮修改润色小学生作文的需求
# 请求参数填写 如果是在parameter中的参数,放在第一层级即可
requestArguments: # 请求插件的参数
query: "微笑多彩的小贝壳 XXX小学2022年度最美少年刘东东 个人宣传资料 刘东东是武功县普集镇中心小学五(1)班的一名学生,今年12岁,在班级担任班长,大队委员,英语课代表等职务。几年来,在老师的精心教导和培育下,在学习上、生活上有了很大进步。
在家里,她尊敬长辈,孝敬老人,独立自强,热爱劳动。奶奶的眼睛看东西很模糊,她会充当奶奶的眼睛,帮奶奶熬中药,端饭菜端,帮奶奶收拾东西,陪奶奶散步、聊天,只要姥姥有需要,她跑前跑后,都不觉得累。生活中,她从未有过多的要求,不挑吃穿,不乱花零用钱;父母平时工作忙,无法辅导功课,她每天自觉完成作业,温习功课;生活教会了她做饭、淘米、炒菜、洗碗、擦地板、洗衣服,每天完成功课后主动干家务。
在学校里,她是一名挺懂事的"小大人",老师和同学都很信任她。作为班长,她能够处处以身作则,为同学树立了榜样,在带头搞好学习和维护班级团结,对老师交给的任务,总是做得有条不紊,是老师的好帮手。学习上,上学从不迟到或早退,上课专心听课,独立思考,认真完成各科作业,主动帮助学习有困难的同学,把自己的学习经验和方法传达给他们,是同学们的好伙伴,上学期被评为"优秀大队干部"。
她是一枚小贝壳,是老师的海洋,给了她斑斓的色彩,成长的路是艰辛而漫长的,希望她用汗水收获自己人生路的彩虹。"
- context: # 对话历史
- role: user
content: 如何修改润色小学生作文
- role: bot
# 触发插件
plugin:
# 无需触发
thoughts: 我不需要使用以上工具
- context: # 对话历史
- role: user
content: 词云图是什么
- role: bot
# 触发插件
plugin:
# 无需触发
thoughts: 用我不需要使用以上工具
- context: # 对话历史
- role: user
content: 修改润色小学生作文,文件地址为 https://www.erniebotplugins.cn:8082/analyze/essay/polishing
- role: bot
# 触发插件
plugin:
# 应当触发的接口operationId
operationId: analyze
# 思考过程,对触发有帮助
thoughts: 这是一个修改润色小学生作文需求,用户指定了文件的地址,只需提取文件地址即可
# 请求参数填写 如果是在parameter中的参数,放在第一层级即可
requestArguments: # 请求插件的参数
fileUrl: https://www.erniebotplugins.cn:8082/analyze/essay/polishing
3.5 register.py
发布文件,主要是:
- 跨域设置
- ai-plugin.json 发布
- openapi.yaml 发布
- example.yaml 发布
- msg_content.yaml 发布
- 发布地址端口
python
#!/usr/env python3
# -*- coding: UTF-8 -*-
from flask import Flask, request, send_file, make_response
from flask_cors import CORS
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "https://yiyan.baidu.com"}})
@app.route("/ai-plugin.json")
async def pluginManifest():
host = request.host_url
with open("ai-plugin.json", encoding="utf-8") as f:
text = f.read().replace("PLUGIN_HOST", host)
return text, 200, {"Content-Type": "application/json"}
@app.route("/openapi.yaml")
async def openapiSpec():
host = request.host_url
with open("openapi.yaml", encoding="utf-8") as f:
text = f.read().replace("PLUGIN_HOST", host)
return text, 200, {"Content-Type": "text/yaml"}
@app.route("/example.yaml")
async def exampleSpec():
host = request.host_url
with open("example.yaml", encoding="utf-8") as f:
text = f.read().replace("PLUGIN_HOST", host)
return text, 200, {"Content-Type": "text/yaml"}
@app.route("/msg_content.yaml")
async def msgContentSpec():
host = request.host_url
with open("msg_content.yaml", encoding="utf-8") as f:
text = f.read().replace("PLUGIN_HOST", host)
return text, 200, {"Content-Type": "text/yaml"}
if __name__ == '__main__':
app.run(debug=True, host='127.0.0.1', port=8022)
3.6 发布服务
- 进入文心一言官网 www.yiyan.baidu.com
- 自动进入插件管理页面 yiyan.baidu.com/pluginSubmi...
- 填写服务地址
- 鉴权 输入aistudio 页面鉴权token即可。
4.服务提供
该服务是插件的服务提供者,需要有自己的服务器,或者通过aistudio部署服务 ,此次部署在自己的服务器上,www.erniebotplugins.cn:8081 。
4.1 导入必须包
python
from flask import Flask, request, send_file, make_response
from flask_cors import CORS
import json
import time
import datetime
4.2 跨域设置
为什么需要跨域呢?如果返回值涉及图片等文件,没有跨域则不能访问。
python
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "https://yiyan.baidu.com"}})
4.3 作文润色功能实现
- 由于没开通文件上传功能,暂时以文本输入
- 返回值为prompt+作文输入
python
# 获取当前时间
now = datetime.datetime.now()
# 格式化输出当前时间
rec_time = now.strftime("%Y-%m-%d-%H:%M:%S")
output_file = f'作文-接收{rec_time}.txt'
def make_json_response(data, status_code=200):
response = make_response(json.dumps(data), status_code)
response.headers["Content-Type"] = "application/json"
return response
@app.route('/analyze/essay/polishing', methods=['POST'])
async def analyzeWordCloud():
request_data = request.get_json()
query = request_data.get("query")
text = query
# 作文润色
prompt = "您是一位非常出色的语文老师,请利用你丰富的知识来修改润色文章," \
"同时要求您在保证文章通顺的前提下,将错别字、病句、病词等修改为正确、通顺的句子,要求尽可能保留原文风格,最后给出作为批改意见," \
f"下面是文章:【{text}】"
# API返回字段"prompt"有特殊含义:开发者可以通过调试它来调试输出效果
return make_json_response({"prompt": prompt})
4.3 作文润色功能实现
进度报告
python
def event_stream():
json_data1 = {"errCode": "statistics", "actionName": "进行作文润色", "actionContent": "作文润色完成"}
yield f"data:{json.dumps(json_data1, ensure_ascii=False)}\n\n"
time.sleep(5)
json_data2 = {"errCode": "generate", "actionName": "正在生成作文评语", "actionContent": "作文评语生成完成"}
yield f"data:{json.dumps(json_data2, ensure_ascii=False)}\n\n"
time.sleep(5)
json_data_result = {"errCode": "output", "actionName": "正在输出作文和作文评语",
"actionContent": "作文和作文评语输出完成",
"result": url,
"prompt": "作文润色完成,下面是输出:, 以下是一个例子: 比如result是 "}
yield f"data:{json.dumps(json_data_result, ensure_ascii=False)}\n\n"
return app.response_class(event_stream(), mimetype='text/event-stream')
4.4 服务启动
- 绑定ip,0.0.0.0代表所有ip,需要注意的是127.0.0.1不可,该回环地址仅可以本地访问。
- ssl_context,设定SSL证书
- port, 设定开启的端口
- 特别需要注意的是端口需要服务器防火墙开放
python
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', ssl_context=('erniebotplugins.cn_bundle.crt', 'erniebotplugins.cn.key'),
port=8082)
4.5 服务完全文件
该服务是插件的服务提供者,需要有自己的服务器,或者通过aistudio部署服务 ,此次部署在自己的服务器上,www.erniebotplugins.cn:8081 。
python
from flask import Flask, request, send_file, make_response
from flask_cors import CORS
import json
import time
import datetime
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "https://yiyan.baidu.com"}})
# 获取当前时间
now = datetime.datetime.now()
# 格式化输出当前时间
rec_time = now.strftime("%Y-%m-%d-%H:%M:%S")
output_file = f'作文-接收{rec_time}.txt'
url = "https://www.erniebotplugins.cn:8081/read_image/alice_cloud.png"
def make_json_response(data, status_code=200):
response = make_response(json.dumps(data), status_code)
response.headers["Content-Type"] = "application/json"
return response
@app.route('/analyze/essay/polishing', methods=['POST'])
async def analyzeWordCloud():
request_data = request.get_json()
query = request_data.get("query")
text = query
# 作文润色
prompt = "您是一位非常出色的语文老师,请利用你丰富的知识来修改润色文章," \
"同时要求您在保证文章通顺的前提下,将错别字、病句、病词等修改为正确、通顺的句子,要求尽可能保留原文风格,最后给出作为批改意见," \
f"下面是文章:【{text}】"
# API返回字段"prompt"有特殊含义:开发者可以通过调试它来调试输出效果
return make_json_response({"prompt": prompt})
def event_stream():
json_data1 = {"errCode": "statistics", "actionName": "进行作文润色", "actionContent": "作文润色完成"}
yield f"data:{json.dumps(json_data1, ensure_ascii=False)}\n\n"
time.sleep(5)
json_data2 = {"errCode": "generate", "actionName": "正在生成作文评语", "actionContent": "作文评语生成完成"}
yield f"data:{json.dumps(json_data2, ensure_ascii=False)}\n\n"
time.sleep(5)
json_data_result = {"errCode": "output", "actionName": "正在输出作文和作文评语",
"actionContent": "作文和作文评语输出完成",
"result": url,
"prompt": "作文润色完成,下面是输出:, 以下是一个例子: 比如result是 "}
yield f"data:{json.dumps(json_data_result, ensure_ascii=False)}\n\n"
return app.response_class(event_stream(), mimetype='text/event-stream')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', ssl_context=('erniebotplugins.cn_bundle.crt', 'erniebotplugins.cn.key'),
port=8082)