109 lines
3.3 KiB
Python
109 lines
3.3 KiB
Python
import json
|
||
import time
|
||
import re
|
||
from traceback import print_exc
|
||
from appPublic.dictObject import DictObject
|
||
from appPublic.httpclient import *
|
||
from appPublic.jsonConfig import getConfig
|
||
from appPublic.log import info, debug, warning, error, exception, critical
|
||
|
||
def search(request, env):
|
||
params_kw = env.get(params_kw)
|
||
prompt = params_kw.prompt
|
||
f = params_kw.search_func
|
||
|
||
def get_json_text(json_str):
|
||
pattern = r'json(.*?)```'
|
||
match = re.search(pattern, json_str, re.DOTALL)
|
||
if match:
|
||
return match.group(1).strip()
|
||
else:
|
||
return json_str
|
||
|
||
def clear_dict(dic):
|
||
d = { k:v for k,v in dic.items() if v not in [ 'undefined', '' ] }
|
||
ret = {}
|
||
for k ,v in d.items():
|
||
if isinstance(v, dict):
|
||
v = clear_dict(v)
|
||
if v != {}:
|
||
ret.update({k:v})
|
||
else:
|
||
ret.update({k:v})
|
||
return ret
|
||
|
||
async def _llmchat(prompt):
|
||
hc = HttpClient()
|
||
config = getConfig()
|
||
model = config.definitions.search_model
|
||
url = config.definitions.search_url
|
||
syscontent = config.definitions.search_syscontent
|
||
headers = {
|
||
"Content-Type":"application/json"
|
||
}
|
||
|
||
messages = [
|
||
{
|
||
"role":"system",
|
||
"content":syscontent
|
||
},
|
||
{
|
||
"role":"user",
|
||
"content":prompt
|
||
}
|
||
]
|
||
body = {
|
||
"model":model,
|
||
"stream":False,
|
||
"messages":messages
|
||
}
|
||
data = json.dumps(body)
|
||
t1 = time.time()
|
||
resp = await hc.request(url, 'POST', headers=headers,
|
||
data=data, response_type=RESPONSE_JSON)
|
||
t2 = time.time()
|
||
resp = DictObject(resp)
|
||
info(f'{resp.message.content=}, cost={t2 - t1}')
|
||
text = resp.message.content
|
||
jtxt = get_json_text(text)
|
||
if jtxt is None:
|
||
return None
|
||
j = DictObject(**json.loads(jtxt))
|
||
j.time_cost = t2 - t1
|
||
j = clear_dict(j)
|
||
info(f'return data={j}========')
|
||
|
||
return j
|
||
|
||
async def llmchat2json(prompt):
|
||
"""
|
||
用大语言模型将用户输入转化为查询条件的json对象, 需要在项目的config.json文件中的definitions属性中
|
||
定义以下变量
|
||
"search_model":"qwen2:7b",
|
||
"search_url":"http://localhost:11434/api/chat",
|
||
"search_syscontent":"将用户输入转换成算力和云服务器查询的json数据json格式为{ \"requestType\": \"resourceQuery\", \"queryParameters\": { \"resourceType\": \"undefined\", \"region\": \"undefined\", \"gpuModel\": \"undefined\", \"gpuCount\": 0, \"cpuModel\": \"undefined\", \"cpuCount\": \"undefined\", \"memorySizeGB\": \"undefined\", \"storageType\": \"undefined\", \"storageCapacityGB\": \"undefined\",\"bandwidthMbps\": \"undefined\",\"priceRange\": { \"min\": \"undefined\", \"max\": \"undefined\"}, \"availabilityZone\": \"undefined\" }}, 保持数据中原有语言,只需返回json数据内容
|
||
,输入中没有的属性省略"
|
||
其中:search_model定义了用于转化查询的大模型名字
|
||
search_url是提供大模型对话服务的url, 我们使用本地部署的开源大模型,所以不用定义apikey
|
||
search_syscontent是一段给大模型的约束文本,要求大模型按要求回复信息
|
||
输入参数:prompt 用户输入的查询条件
|
||
返回:查询条件的json, 如果出错,返回None
|
||
"""
|
||
try:
|
||
x = await _llmchat(prompt)
|
||
return x
|
||
except Exception as e:
|
||
exception(f'{e=}')
|
||
return None
|
||
|
||
if __name__ == '__main__':
|
||
import sys
|
||
if len(sys.argv) < 2:
|
||
print(f'Usage:\n{sys.argv[0]} search_text')
|
||
sys.exit(1)
|
||
prompt= sys.argv[1]
|
||
config = getConfig('.')
|
||
loop = asyncio.get_event_loop().run_until_complete(llmchat(prompt))
|
||
print('here')
|
||
|