使用function call格式化输出比较不稳定,因为大模型可能无法将内容和工具的描述匹配在一起,导致无法调用工具。
提示词
在prompt中明确指定大模型用 json
格式输出,明确 json
的 key
和 value
,这样方便从中固定地提取数据
prompt = 请你根据title中的标题,主要阅读content中的内容,总结出其中的非技术知识点关键词
用json格式输出,key是"知识点",values是由技术知识点组成的list,list中的每个元素是一个str
加载json
获取到对话结果后,用异常捕获尝试 json.loads
,其中使用 replace("\n", "")
是因为大模型为了输出美观,可能会添加 \n
,但是我们不需要回车,否则无法直接转化为 python 中的 dict
。
try:
response.replace("\n", "")
types = json.loads(response)
types = types['知识点']
print(types)
except:
types = None
print(response)
代码
下面是完整代码,因为大模型长度有限,所以一次传给它一小段文本,通过for循环遍历。需要很仔细的设计好异常捕获机制,否则程序运行不到结尾。
import traceback
from transformers import AutoTokenizer, AutoModelForCausalLM
import json
import os
modelPath = "/mnt/workspace/chatglm3-6b"
def chat(model, tokenizer, message, history, system):
messages = []
if system is not None:
messages.append(system)
if history is not None:
for his in history:
user, assistant = his
messages.append({"role": "user", "content": user})
messages.append({"role": "assistant", 'metadata': '', "content": assistant})
# print(messages)
try:
response,_ = model.chat(tokenizer, message, messages, max_length=2048, top_p=0.9, temperature=0.6, repetition_penalty=1.1, do_sample=True)
return response
except Exception:
print("error")
return None
def loadTokenizer():
tokenizer = AutoTokenizer.from_pretrained(modelPath, use_fast=False, trust_remote_code=True)
return tokenizer
def loadModel():
model = AutoModelForCausalLM.from_pretrained(modelPath, device_map="auto", trust_remote_code=True).cuda()
model = model.eval()
# print(model)
return model
def main():
model = loadModel()
tokenizer = loadTokenizer()
types_all = set()
count = 0
for blog in blogs:
count += 1
if count == 5:
break
message1 = f'''
请你根据title中的标题,主要阅读content中的内容,总结出其中的非技术知识点关键词
用json格式输出,key是"知识点",values是由技术知识点组成的list,list中的每个元素是一个str
""
{blog}
""
'''
history = []
system = {
"role": "system",
"content": "你面对的是一份由网友提供的公司面试经历,title表示文章标题,content表示文章内容",
}
response = chat(model, tokenizer, message1, None, system)
print('here\'s the result')
# print(response)
try:
response.replace("\n", "")
types = json.loads(response)
types = types['知识点']
print(types)
except:
types = None
print(response)
if types is list:
for t in types:
types_all.add(t)
with open("types.txt", "a") as f:
f.writelines(f"{item}\n" for item in types_all)
if __name__ == "__main__":
main()
结果
如图中所示,这样可以提取出面试经验中的关键词