180 lines
7.4 KiB
Python
Raw Normal View History

2024-11-17 12:11:11 +08:00
import os
2024-12-20 12:32:06 +08:00
import time
2024-11-16 14:24:58 +08:00
import requests
2024-12-04 15:32:42 +08:00
from ratelimit import sleep_and_retry, limits
from flask_app.general.llm.大模型通用函数 import get_total_tokens
2024-12-04 15:32:42 +08:00
@sleep_and_retry
@limits(calls=2, period=1) # tpm=300万每秒最多调用4次,目前两个服务器分流就是2次
2024-12-20 17:24:49 +08:00
def doubao_model(full_user_query, need_extra=False):
"""
对于429错误一共尝试三次前两次等待若干时间再发起调用第三次换模型
:param full_user_query:
:param need_extra:
:return:
"""
2024-11-16 16:14:53 +08:00
print("call doubao...")
2024-11-16 14:24:58 +08:00
# 相关参数
url = "https://ark.cn-beijing.volces.com/api/v3/chat/completions"
2024-12-05 16:53:11 +08:00
doubao_api_key = os.getenv("DOUBAO_API_KEY")
2024-11-16 14:24:58 +08:00
2024-12-04 13:36:53 +08:00
# 定义主模型和备用模型
2024-12-19 12:25:29 +08:00
models = {
"pro_32k": "ep-20241119121710-425g6", # 豆包Pro 32k模型
"pro_128k": "ep-20241119121743-xt6wg" # 128k模型
}
# 判断用户查询字符串的长度
2024-12-20 17:24:49 +08:00
token_count = get_total_tokens(full_user_query)
if token_count > 31500:
selected_model = "pro_128k" # 如果长度超过32k直接使用128k模型
2024-12-19 12:25:29 +08:00
else:
selected_model = "pro_32k" # 默认使用32k模型
2024-12-19 12:25:29 +08:00
2024-12-04 13:36:53 +08:00
# 请求头
2024-11-16 14:24:58 +08:00
headers = {
"Content-Type": "application/json",
2024-12-05 16:53:11 +08:00
"Authorization": "Bearer " + doubao_api_key
2024-11-16 14:24:58 +08:00
}
2024-12-19 12:25:29 +08:00
max_retries_429 = 3 # 针对 429 错误的最大重试次数
2024-12-20 12:32:06 +08:00
max_retries_other = 1 # 针对其他错误的最大重试次数
2024-12-04 13:36:53 +08:00
attempt = 0
2024-12-20 12:32:06 +08:00
response = None # 确保 response 被定义
2024-12-19 12:25:29 +08:00
2024-12-20 12:32:06 +08:00
while True:
2024-12-04 13:36:53 +08:00
# 请求数据
data = {
"model": models[selected_model],
2024-12-04 13:36:53 +08:00
"messages": [
{
"role": "user",
"content": full_user_query
}
],
"temperature": 0.2
}
try:
response = requests.post(url, headers=headers, json=data) # 设置超时时间为10秒
response.raise_for_status() # 如果响应状态码不是200将引发HTTPError
2024-12-20 17:24:49 +08:00
# 获取响应 JSON
response_json = response.json()
# 获取返回内容
content = response_json["choices"][0]["message"]["content"]
# 获取 completion_tokens
completion_tokens = response_json["usage"].get("completion_tokens", 0)
# 根据 need_extra 返回不同的结果
if need_extra:
return content, completion_tokens
else:
return content
2024-12-04 13:36:53 +08:00
except requests.exceptions.RequestException as e:
2024-12-20 12:32:06 +08:00
# 获取状态码并处理不同的重试逻辑
status_code = response.status_code if response is not None else None
print(f"请求失败,状态码: {status_code}")
print("请求失败,完整的响应内容如下:")
2024-12-20 17:24:49 +08:00
if response is not None:
print(response.text) # 打印原始的响应内容,可能是 JSON 格式,也可能是其他格式
2024-12-20 12:32:06 +08:00
# 如果是 429 错误
if status_code == 429:
if attempt < max_retries_429:
wait_time=1
if attempt == 0:
wait_time = 3
elif attempt == 1:
wait_time = 6
elif attempt == 2:
# 第三次重试时切换模型
alternative_model = "pro_128k" if selected_model == "pro_32k" else "pro_32k"
print(f"状态码为 429切换模型从 {selected_model}{alternative_model} 并重试...")
selected_model = alternative_model
wait_time = 0 # 立即重试,无需等待
print(f"等待 {wait_time} 秒后重试...")
if wait_time > 0:
time.sleep(wait_time)
2024-12-20 12:32:06 +08:00
else:
print(f"状态码为 429已达到最大重试次数 {max_retries_429} 次。")
break # 超过最大重试次数,退出循环
2024-12-04 13:36:53 +08:00
else:
2024-12-20 12:32:06 +08:00
# 针对其他错误
if attempt < max_retries_other:
print("非 429 错误,等待 1 秒后重试...")
time.sleep(1)
else:
print(f"非 429 错误,已达到最大重试次数 {max_retries_other} 次。")
break # 超过最大重试次数,退出循环
attempt += 1 # 增加重试计数
2024-12-19 12:25:29 +08:00
2024-12-20 12:32:06 +08:00
# 如果到这里,说明所有尝试都失败了
print(f"请求失败,已达到最大重试次数。")
2024-12-20 17:24:49 +08:00
if need_extra:
return None, 0
else:
return None
2024-11-16 14:24:58 +08:00
if __name__ == "__main__":
txt_path = r"output.txt"
pdf_path_1 = "D:/bid_generator/task_folder/9a447eb0-24b8-4f51-8164-d91a62edea25/tmp/bid_format.pdf"
2024-11-17 12:11:11 +08:00
pdf_path_2 = r"C:\Users\Administrator\Desktop\货物标\output1\竞争性谈判文件_procurement.pdf"
2024-11-16 14:24:58 +08:00
prompt_template = '''
任务解析采购文件提取采购需求并以JSON格式返回
要求与指南
1. 精准定位运用文档理解能力找到文件中的采购需求部分
2. 系统归属若货物明确属于某个系统则将其作为该系统的二级键
3. 非清单形式处理若未出现采购清单则从表格或文字中摘取系统和货物信息
4. 软件需求对于软件应用需求列出系统模块构成并作为系统键值的一部分
5. 系统功能若文中提及系统功能则在系统值中添加'系统功能'二级键不展开具体内容
6. 完整性确保不遗漏系统内的货物也不添加未提及的内容
输出格式
1.JSON格式最外层键名为'采购需求'
2.嵌套键名为系统或货物名称与原文保持一致
3.键值应为空对象{{}}仅返回名称
4.不包含'说明''规格''技术参数'等列内容
5.层次关系用嵌套键值对表示
6.最后一级键内值留空或填'未知'如数量较多或未知内容
特殊情况处理
同一层级下同名但采购要求不同的货物'货物名-编号'区分编号从1递增
示例输出结构
{{
"采购需求": {{
"交换机-1": {{}},
"交换机-2": {{}},
"门禁管理系统": {{
// 可包含其他货物或模块
}},
"交通监控视频子系统": {{
"系统功能": {{}},
"高清视频抓拍像机": {{}},
"补光灯": {{}}
}},
"LED全彩显示屏": {{}}
// 其他系统和货物
}}
}}
文件内容已包含{full_text}
注意事项
1.严格按照上述要求执行确保输出准确性和规范性
2.如有任何疑问或不确定内容请保留原文描述必要时使用'未知'标注
'''
2024-11-17 12:11:11 +08:00
# processed_filepath = convert_pdf_to_markdown(pdf_path_2) # 转markdown格式
2024-11-17 16:29:02 +08:00
# processed_filepath = pdf2txt(pdf_path_2) #纯文本提取
# user_query=generate_full_user_query(processed_filepath,prompt_template)
user_query="一年有多少天?"
res=doubao_model(user_query)
# res=get_total_tokens("hh我是天才")
2024-11-16 14:24:58 +08:00
print(res)
# print("--------------------")
# print(user_query)