目录
前言
本篇章节适用于多任务的服务器模拟操作,通过使用fastapi和celery框架实现分布式请求,关于ai模拟操作则是通过设定AI角色样式来进行模拟真人进行内容的回答。
本篇章只会涉及到两个模型,都是国内模型。
全模态模型:qwen3-omin-flash
聊天模型:qwen3-max
可以的话先去申请相关的api-key来获取模型请求,防止项目无法操作。
环境安装
python 3.9+< ,>3.12 即需要python环境处于3.9+以上的运行环境,并处于3.12以下的运行环境
安装的模块包
pip install openai #openai模块
pip install uvicorn
pip install fastapi #安装fastapi框架
pip install celery #安装celery分布式框架
pip install redis #安装redis服务支持
pip install mariktdown #安装mariktdown文件识别框架
大抵就是这些,那么接下来就是对文件的简单处理了,与内容生成了。
实现思路

文字解析一下吧,就是当文件上传请求创建的时候进行task创建,然后进行文档解析,解析出来的文本拼接promt统一请求ai,然后让ai模拟角色进行内容的输出。
代码实现
首先要理解,核心代码就是md的使用,就是图片文件的解析,和提示词的拼接,其实就没什么内容了。
也就是官方文档这几句话,使用大语言模型的视觉能力进行文档内容的解析。
from markitdown import MarkItDown
from openai import OpenAI
client = OpenAI()
md = MarkItDown(llm_client=client, llm_model="gpt-4o", llm_prompt="optional custom prompt")
result = md.convert("example.jpg")
print(result.text_content)
创建一个类进行fastapi,openai的设置还有对话请求的设置。
这里就不过多赘述了
import os
import celery
from dotenv import load_dotenv
class Setting_config:
def openai_config(self):
"""
该函数主要是用来创建openai对象
:return:
"""
from openai import OpenAI
from dotenv import load_dotenv
import os
load_dotenv()
return OpenAI(
api_key= os.getenv("OPENAI_API_KEY"),
base_url= os.getenv("OPENAI_API_BASE_URL"),
max_retries= 3,
timeout= 60,
)
def fastapi_config(self):
"""
该函数是用来创建fastapi对象的
并且设置了跨域请求的中间键
:return:
"""
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
# 创建FastAPI实例
app = FastAPI()
# 设置跨域cors
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
return app
def file_extension_suffix(self,file_path):
"""
该函数主要是用来获取文件的后缀名
:param file_path:
:return:
"""
import os
return os.path.split(file_path)[1].split( ".")[1]
def file_read(self,file_path):
"""
该函数主要是用来处理文件解析的
:param file_path:
:return:
"""
from markitdown import MarkItDown
md = MarkItDown()
text = ""
try:
suffix = self.file_extension_suffix(file_path)
if suffix in ["md","doc","docx","pdf","xsxl","txt","text"]:
result = md.convert(file_path)
res_text = result.text_content
for line in res_text.split("\n"):
text += line + "\n"
return text
elif suffix in ["png","jpg","jpeg"]:
import os
from dotenv import load_dotenv
load_dotenv()
client = self.openai_config()
md = MarkItDown(llm_client=client, llm_model=os.getenv("OPENAI_AI_MODEL"),
llm_prompt="请描述该图片的内容")
result = md.convert(file_path)
res_text = result.text_content
for line in res_text.split("\n"):
text += line + "\n"
return text
else:
return {"code":400,"message":f"目前不支持{{suffix}}类型文件"}
except Exception as e:
return {"code":400,"message":"文件不存在或者文件读取失败!"}
这个类定义很简单的,主要是涉及fastapi的中间键,openai的设置,和文件的解析设置。
然后创建该有的task任务流程。
@cl.task(name="file_read_task")
def file_read_task(file_path,request_dict):
"""
该函数主要是用来处理文件解析任务
:return:
"""
start_time = time.time()
print("开始执行文件解析任务")
# 将字典转换回 Request_model 对象(使用相对导入以避免包路径问题)
from ..Fastapi.setting.Class import Request_model
request = Request_model(**request_dict)
from ..setting_config import Setting_config
text = Setting_config().file_read(file_path)
print("文件解析任务执行完毕")
from dotenv import load_dotenv
import os
load_dotenv()
client = Setting_config().openai_config()
# 安全获取person_info的属性
person_info = request.person_info
person_age = person_info.age_range if person_info else None
person_gender = person_info.gender if person_info else None
person_education = person_info.education if person_info else None
person_income = person_info.income if person_info else None
person_platform_usage = person_info.platform_useage if person_info else None
person_content_preference = person_info.content_preference if person_info else None
person_live_in = person_info.live_in if person_info else None
person_custom_traits = person_info.custom_traits if person_info else None
person_language = person_info.languange if person_info else None
talk = client.chat.completions.create(
model=os.getenv("OPENAI_AI_CHAT_MODEL"),
messages=[
{"role": "system", "content":
f"用户上传的文件内容{text}\n"
f"关于语言的设定'zh'为中文,'jp'为日语,'en'为英语,'kr'为韩语。\n"
f"你是一个{request.platform or '未知'}平台的用户,界面应用的语言是{request.ui_language or '未知'},"
f"你的画像是{person_age or '未知'}岁,性别是{person_gender or '未知'},受教育程度{person_education or '未知'},"
f"收入水平{person_income or '未知'},平台的使用情况{person_platform_usage or '未知'},内容偏好{person_content_preference or '未知'},"
f"居住地{person_live_in or '未知'},自定义个性化标签为{person_custom_traits or '未知'},使用的语言是{person_language or '未知'}的用户"
f"请你根据用户画像来模拟用户,然后再随机设定你的当前情绪,依据用户的语言来使用该语言来进行评价,评价文件的内容,给出一个评价,并给出一个建议,以及为什么做这样子的评价。"
},
],
)
end_time = time.time()
process_time = end_time-start_time
answer = talk.choices[0].message.content
start = time.localtime(start_time)
end = time.localtime(end_time)
start_time = time.strftime("%Y-%m-%d %H:%M:%S", start)
end_time = time.strftime("%Y-%m-%d %H:%M:%S", end)
return text,answer,start_time,end_time,process_time
最后创建相应fastapi的接口
@app.post("/post_file_chat")
async def response_model(request: str = Form(...),
file_path: UploadFile = File(..., alias="file_path")):
# 解析JSON字符串为Request_model对象
try:
request_data = json.loads(request)
request_model = Request_model(**request_data)
except json.JSONDecodeError as e:
return {
"error": "Invalid JSON format",
"message": str(e)
}
except Exception as e:
return {
"error": "Invalid request data",
"message": str(e)
}
file_location = f"{UPLOAD}/{uuid.uuid4().hex}_{file_path.filename}"
with open(file_location, "wb") as f:
while True:
chunk = await file_path.read(1024 * 1024)
if not chunk:
break
f.write(chunk)
# 将 Pydantic 模型转换为字典以便 Celery 序列化
request_dict = request_model.model_dump() if hasattr(request_model, 'model_dump') else request_model.dict()
res = file_read_task.delay(file_location, request_dict)
return {
"task_id": res.id,
"status": res.status,
"message": "任务已提交,请轮询获/task/{task_id}取结果",
"created_at_timestamp": time.time(),
}
@app.get("/task/{task_id}")
async def response_model(task_id:str):
res = AsyncResult(task_id, app=cl)
if res.state == "SUCCESS":
text, answer, start, end, duration = res.result
return {
"status": res.state,
"text": text, #图片描述
"answer": answer,
"created_at_timestamp": start,
"process_timestamp": f"{duration:.2f}秒",
"completed_timestamp": end,
}
return {"status":f"任务的状态为{res.state}"}
那么到这里基本也就演示完毕,那么这里就跑一下看看
需要先启动celery任务然后再启动fastapi。
启动指令
python -m celery -A 根目录下包含该task的py名称:celery worker -l info -P solo
测试结果演示
传递的参数参考
{
"platform": "小红书",
"max_users": 20,
"ui_language": "jp",
"person_info": {
"age_range": "18-25岁",
"gender": "女",
"education": "本科学历",
"income": "5k-6k",
"platform_usage": "一周5天,每天2小时",
"content_preference": [
"美妆,旅行,摄影"
],
"live_in": [
"中国湖南长沙市"
],
"custom_traits": "不被定义,快乐小女孩",
"language": "jp"
},
"versions": [
{
"version_text": "string",
"images": [
"string"
],
"videos": [
"string"
]
}
]
}
上传的图片
博主自己画的图片,请勿商用,记得注明来源




708

被折叠的 条评论
为什么被折叠?



