首先,要告诉大模型做什么
- 描述的侧重要讲清楚有哪些实体,以及实体之间的关系
- 这可以帮助大模型理解语义
任务描述+强调+用户输入
以强调的方式引导大模型明白自己的意图
# 任务描述
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称,月费价格,月流量。
根据用户输入,识别用户在上述三种属性上的需求是什么。
"""
# 用户输入
input_text = """
办个100G的套餐。
"""
# prompt 模版。instruction 和 input_text 会被替换为上面的内容
prompt = f"""
{instruction}
用户输入:
{input_text}
"""
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv(filename="env.txt"))
from tpf.llm.openai import chat
# 调用大模型
response = chat(prompt)
print(response)
根据用户的输入,可以识别出以下需求:
1. **月流量**:用户希望选择一个100G的流量套餐。
2. **月费价格**:用户没有明确提到对月费价格的要求,因此无法确定。
3. **名称**:用户没有提到具体的套餐名称。
总结:用户的主要需求是选择一个月流量为100G的套餐。
|
# 任务描述
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称,月费价格,月流量。
根据用户输入,识别用户在上述三种属性上的需求是什么。
"""
# 用户输入
input_text = """
办个100G的套餐。
"""
# 输出格式
output_format = """
以 JSON 格式输出
"""
# 加入输出格式
prompt = f"""
{instruction}
{output_format}
用户输入:
{input_text}
"""
# 调用大模型
response = chat(prompt, response_format="json_object")
print(response)
{
"需求": {
"名称": "100G套餐",
"月费价格": null,
"月流量": "100G"
}
}
|
使用表达式 描述/表达 条件
# 任务描述增加了字段的英文标识符
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称(name),月费价格(price),月流量(data)。
根据用户输入,识别用户在上述三种属性上的需求是什么。
"""
# 输出格式增加了各种定义、约束
output_format = """
以JSON格式输出。
1. name字段的取值为string类型,取值必须为以下之一:经济套餐、畅游套餐、无限套餐、校园套餐 或 null;
2. price字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型
3. data字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型或string类型,string类型只能是'无上限'
4. 用户的意图可以包含按price或data排序,以sort字段标识,取值为一个结构体:
(1) 结构体中以"ordering"="descend"表示按降序排序,以"value"字段存储待排序的字段
(2) 结构体中以"ordering"="ascend"表示按升序排序,以"value"字段存储待排序的字段
输出中只包含用户提及的字段,不要猜测任何用户未直接提及的字段,不输出值为null的字段。
"""
# 用户输入
input_text = "办个100G以上的套餐"
# 加入输出格式
prompt = f"""
{instruction}
{output_format}
用户输入:
{input_text}
"""
# 调用大模型
response = chat(prompt, response_format="json_object")
print(response)
{
"data": {
"operator": ">=",
"value": 100
}
}
以上 解释为 >=
值解释为 100
|
# 任务描述增加了字段的英文标识符
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称(name),月费价格(price),月流量(data)。
根据用户输入,识别用户在上述三种属性上的需求是什么。
"""
# 输出格式增加了各种定义、约束
output_format = """
以JSON格式输出。
1. name字段的取值为string类型,取值必须为以下之一:经济套餐、畅游套餐、无限套餐、校园套餐 或 null;
2. price字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型
3. data字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型或string类型,string类型只能是'无上限'
4. 用户的意图可以包含按price或data排序,以sort字段标识,取值为一个结构体:
(1) 结构体中以"ordering"="desc"表示按降序排序,以"value"字段存储待排序的字段
(2) 结构体中以"ordering"="asc"表示按升序排序,以"value"字段存储待排序的字段
输出中只包含用户提及的字段,不要猜测任何用户未直接提及的字段,不输出值为null的字段。
"""
examples = """
便宜的套餐:{"sort":{"ordering"="ascend","value"="price"}}
有没有不限流量的:{"data":{"operator":"==","value":"无上限"}}
流量大的:{"sort":{"ordering"="descend","value"="data"}}
100G以上流量的套餐最便宜的是哪个:{"sort":{"ordering"="ascend","value"="price"},"data":{"operator":">=","value":100}}
月费不超过200的:{"price":{"operator":"<=","value":200}}
就要月费180那个套餐:{"price":{"operator":"==","value":180}}
经济套餐:{"name":"经济套餐"}
土豪套餐:{"name":"无限套餐"}
"""
def query(instruction,output_format,examples,input_text):
#增加示例
prompt = f"""
{instruction}
{output_format}
例如:
{examples}
用户输入:
{input_text}
"""
return prompt
# 用户输入
input_text = "200元以下,流量大的套餐有啥"
prompt=query(instruction,output_format,examples,input_text)
# 调用大模型
response = chat(prompt, response_format="json_object")
print(response)
{"price":{"operator":"<=","value":200},"sort":{"ordering":"desc","value":"data"}}
input_text = "50元左右,流量在100G左右的套餐有哪些"
prompt=query(instruction,output_format,examples,input_text)
# 调用大模型
response = chat(prompt, response_format="json_object")
print(response)
因为模板中没有对近似做处理,所以它直接判断为等于==
{
"price": {
"operator": "==",
"value": 50
},
"data": {
"operator": "==",
"value": 100
}
}
|
前面的例子中,将近似表达为==不合适
对prompt进行修改,调整如下
# 任务描述增加了字段的英文标识符
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称(name),月费价格(price),月流量(data)。
根据用户输入,识别用户在上述三种属性上的需求是什么。
"""
# 输出格式增加了各种定义、约束
output_format = """
以JSON格式输出。
1. name字段的取值为string类型,取值必须为以下之一:经济套餐、畅游套餐、无限套餐、校园套餐 或 null;
2. price字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型
3. data字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型或string类型,string类型只能是'无上限'
4. 用户的意图可以包含按price或data排序,以sort字段标识,取值为一个结构体:
(1) 结构体中以"ordering"="desc"表示按降序排序,以"value"字段存储待排序的字段
(2) 结构体中以"ordering"="asc"表示按升序排序,以"value"字段存储待排序的字段
(3) 如果流程或价格出现左右,大概的修饰,增加fluctuation字段,其值为20%, 意味着可以波动20%
输出中只包含用户提及的字段,不要猜测任何用户未直接提及的字段,不输出值为null的字段。
"""
examples = """
便宜的套餐:{"sort":{"ordering"="ascend","value"="price"}}
有没有不限流量的:{"data":{"operator":"==","value":"无上限"}}
流量大的:{"sort":{"ordering"="descend","value"="data"}}
100G以上流量的套餐最便宜的是哪个:{"sort":{"ordering"="ascend","value"="price"},"data":{"operator":">=","value":100}}
月费不超过200的:{"price":{"operator":"<=","value":200}}
就要月费180那个套餐:{"price":{"operator":"==","value":180}}
流量在100G左右的套餐: {"price":{"operator":"==","value":100,"fluctuation":20%}
经济套餐:{"name":"经济套餐"}
土豪套餐:{"name":"无限套餐"}
"""
def query(instruction,output_format,examples,input_text):
#增加示例
prompt = f"""
{instruction}
{output_format}
例如:
{examples}
用户输入:
{input_text}
"""
return prompt
input_text = "50元左右,流量在100G左右的套餐有哪些"
prompt=query(instruction,output_format,examples,input_text)
# 调用大模型
response = chat(prompt, response_format="json_object")
print(response)
{
price":{"operator":"==","value":50,"fluctuation":"20%"},
"data":{"operator":">=","value":100,"fluctuation":"20%"}
}
自然语言与代码 就建立起来联系了
|
多轮对话在上告诉大模型 上下文环境
将对话历史放入prompt中就可以做到这一点
# 任务描述增加了字段的英文标识符
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称(name),月费价格(price),月流量(data)。
根据用户输入,识别用户在上述三种属性上的需求是什么。
"""
# 输出格式增加了各种定义、约束
output_format = """
以JSON格式输出。
1. name字段的取值为string类型,取值必须为以下之一:经济套餐、畅游套餐、无限套餐、校园套餐 或 null;
2. price字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型
3. data字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型或string类型,string类型只能是'无上限'
4. 用户的意图可以包含按price或data排序,以sort字段标识,取值为一个结构体:
(1) 结构体中以"ordering"="desc"表示按降序排序,以"value"字段存储待排序的字段
(2) 结构体中以"ordering"="asc"表示按升序排序,以"value"字段存储待排序的字段
(3) 如果流程或价格出现左右,大概的修饰,增加fluctuation字段,其值为20%, 意味着可以波动20%
输出中只包含用户提及的字段,不要猜测任何用户未直接提及的字段,不输出值为null的字段。
"""
examples = """
便宜的套餐:{"sort":{"ordering"="ascend","value"="price"}}
有没有不限流量的:{"data":{"operator":"==","value":"无上限"}}
流量大的:{"sort":{"ordering"="descend","value"="data"}}
100G以上流量的套餐最便宜的是哪个:{"sort":{"ordering"="ascend","value"="price"},"data":{"operator":">=","value":100}}
月费不超过200的:{"price":{"operator":"<=","value":200}}
就要月费180那个套餐:{"price":{"operator":"==","value":180}}
流量在100G左右的套餐: {"price":{"operator":"==","value":100,"fluctuation":20%}
经济套餐:{"name":"经济套餐"}
土豪套餐:{"name":"无限套餐"}
"""
# 多轮对话示例
examples_chat = """
客服:有什么可以帮您
用户:100G套餐有什么
{"data":{"operator":">=","value":100}}
客服:有什么可以帮您
用户:100G套餐有什么
客服:我们现在有无限套餐,不限流量,月费300元
用户:太贵了,有200元以内的不
{"data":{"operator":">=","value":100},"price":{"operator":"<=","value":200}}
客服:有什么可以帮您
用户:便宜的套餐有什么
客服:我们现在有经济套餐,每月50元,10G流量
用户:100G以上的有什么
{"data":{"operator":">=","value":100},"sort":{"ordering"="asc","value"="price"}}
客服:有什么可以帮您
用户:100G以上的套餐有什么
客服:我们现在有畅游套餐,流量100G,月费180元
用户:流量最多的呢
{"sort":{"ordering"="desc","value"="data"},"data":{"operator":">=","value":100}}
"""
def query(instruction,output_format,examples,examples_chat,context):
#增加示例
prompt = f"""
{instruction}
{output_format}
例如:
{examples}
多轮对话示例:
{examples_chat}
{context}
"""
return prompt
input_text = "哪个便宜"
# 多轮对话上下文
context = f"""
客服:有什么可以帮您
用户:有什么100G以上的套餐推荐
客服:我们有畅游套餐和无限套餐,您有什么价格倾向吗
用户:{input_text}
"""
prompt=query(instruction,output_format,examples,examples_chat,context)
# 调用大模型
response = chat(prompt, response_format="json_object")
print(response)
{"data":{"operator":">=","value":100},"sort":{"ordering":"asc","value":"price"}}
|
deepseek-r1:1.5b
from openai import OpenAI
def chat_ollama(prompt, response_format="text", model='deepseek-r1:1.5b',temperature=0):
client = OpenAI(
base_url='http://localhost:11434/v1/',
api_key='key',#必需但可以随便填写
)
response = client.chat.completions.create(
model=model,
messages=[{'role': 'user','content': prompt,}],
temperature=temperature, # 模型输出的随机性,0 表示随机性最小
# 返回消息的格式,text 或 json_object
response_format={"type": response_format},
)
if response.choices is None:
err_msg = response.error["message"]
raise Exception(f"{err_msg}")
return response.choices[0].message.content # 返回模型生成的文本
response = chat_ollama(prompt="工作学习多久应该休息一下")
print(response)
think
嗯,我现在在想,工作和学习需要多长时间才能休息一下。这个问题听起来有点复杂,但我觉得可以从几个方面来考虑。
首先,我可能需要了解自己的工作内容。如果工作量很大,比如每天都要处理很多数据或者完成大量的任务,那么休息的时间可能会更长一些。相反,如果工作比较简单,只需要完成一个小项目,可能不需要长时间的休息时间。
然后,我应该考虑自己的身体状况。如果我最近有健康问题,比如肌肉酸痛、疲劳或者睡眠不足,那休息的时间可能比平时要多一些。反之,如果我的身体状态很好,可能可以更轻松地进行工作和学习。
还有,工作和学习的时间安排也很重要。如果我每天都有很多任务要做,即使不休息,也可能感到疲惫。而如果我有足够的时间来休息,可能会更有精力继续工作下去。
另外,个人习惯也是一个因素。有些人喜欢长时间的休息,比如在周末或者节假日的时候,可能更倾向于长时间地放松和恢复。而其他人可能更倾向于在工作间隙休息,这样可以更好地应对工作压力。
还有,工作和学习的内容本身也会影响休息时间。如果任务比较简单或容易完成,可能不需要长时间的休息;但如果任务很复杂或需要花费很多时间来解决,那么休息的时间可能会更长一些。
我还应该考虑自己的心理状态。如果我在工作中感到焦虑或者压力大,可能需要更多的休息时间来缓解这些情绪。而如果我感到轻松和愉悦,可能不需要长时间的休息。
另外,工作和学习的时间长度也是一个因素。如果任务量很大,即使休息了一段时间,也可能无法有效恢复,这时候可能需要更长的时间才能恢复到原来的状态。
还有,个人兴趣和习惯也很重要。如果我喜欢在特定的时间进行工作或学习,那么可能需要调整自己的时间安排,避免长时间的休息,以免影响到自己的专注力。
最后,我应该考虑是否有其他因素会影响休息时间,比如任务量、身体状况、心理状态等。如果有这些方面的问题,可能需要采取一些措施来改善,比如制定更详细的计划、保持良好的睡眠习惯或者寻求专业的帮助。
总的来说,工作和学习的休息时间取决于很多因素,包括个人的工作内容、身体状况、个人习惯以及心理状态。了解自己并根据实际情况调整自己的休息时间和安排,可能会让我在工作中更加高效,生活也更加轻松。
think
根据你的思考过程,以下是分步骤的解释:
1. **了解工作内容**:首先明确每天的工作任务量和复杂程度。简单任务可能不需要长时间休息,而复杂任务则需要更长的时间。
2. **评估身体状况**:检查最近的身体状态,包括肌肉酸痛、疲劳情况以及睡眠质量。健康状况好的人可以休息更多时间,反之则需要更多的休息时间。
3. **考虑个人习惯**:观察你的工作和学习习惯,是否喜欢长时间休息或在特定时间段进行活动。调整时间安排以适应自己的习惯。
4. **心理状态**:评估当前的心理压力和情绪。如果感到焦虑或疲惫,可能需要更长的休息时间来缓解压力。
5. **任务复杂程度**:根据任务的难度,决定休息的时间长度。简单任务可以轻松完成,而复杂任务则可能需要更多时间恢复。
6. **综合因素**:结合身体状况、工作内容和心理状态,制定合理的休息计划。例如,如果工作量大且身体不适,可能需要更长的休息时间。
7. **调整计划**:根据上述分析,调整工作和学习的时间安排,确保在休息期间能够有效地恢复精力,继续高效地完成任务。
通过以上步骤,你可以更好地平衡工作与休息,提高工作效率并享受更好的生活。
针对前面补充的例子,使用deepseek1.5b效果如下
from openai import OpenAI
from tpf.llm import chat_ollama
# 任务描述增加了字段的英文标识符
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称(name),月费价格(price),月流量(data)。
根据用户输入,识别用户在上述三种属性上的需求是什么。
"""
# 输出格式增加了各种定义、约束
output_format = """
以JSON格式输出。
1. name字段的取值为string类型,取值必须为以下之一:经济套餐、畅游套餐、无限套餐、校园套餐 或 null;
2. price字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型
3. data字段的取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型或string类型,string类型只能是'无上限'
4. 用户的意图可以包含按price或data排序,以sort字段标识,取值为一个结构体:
(1) 结构体中以"ordering"="desc"表示按降序排序,以"value"字段存储待排序的字段
(2) 结构体中以"ordering"="asc"表示按升序排序,以"value"字段存储待排序的字段
(3) 如果流程或价格出现左右,大概的修饰,增加fluctuation字段,其值为20%, 意味着可以波动20%
输出中只包含用户提及的字段,不要猜测任何用户未直接提及的字段,不输出值为null的字段。
"""
examples = """
便宜的套餐:{"sort":{"ordering"="ascend","value"="price"}}
有没有不限流量的:{"data":{"operator":"==","value":"无上限"}}
流量大的:{"sort":{"ordering"="descend","value"="data"}}
100G以上流量的套餐最便宜的是哪个:{"sort":{"ordering"="ascend","value"="price"},"data":{"operator":">=","value":100}}
月费不超过200的:{"price":{"operator":"<=","value":200}}
就要月费180那个套餐:{"price":{"operator":"==","value":180}}
流量在100G左右的套餐: {"price":{"operator":"==","value":100,"fluctuation":20%}
经济套餐:{"name":"经济套餐"}
土豪套餐:{"name":"无限套餐"}
"""
def query(instruction,output_format,examples,input_text):
#增加示例
prompt = f"""
{instruction}
{output_format}
例如:
{examples}
用户输入:
{input_text}
"""
return prompt
input_text = "50元左右,流量在100G左右的套餐有哪些"
prompt=query(instruction,output_format,examples,input_text)
# 调用大模型
response = chat_ollama(prompt, response_format="json_object")
print(response)
{
"name":"经济套餐",
"price":{"operator":"==","value":50,"fluctuation":20},
"data":{"operator":"==","value":100}
}
这是GPT-4o-mini的返回结果
{
price":{"operator":"==","value":50,"fluctuation":"20%"},
"data":{"operator":">=","value":100,"fluctuation":"20%"}
}
== deepseek1.5解释的更好,但少了fluctuation
|
这里的优化方法是增加示例
针对近似的描述,原prompt模板只有一个示例
流量在100G左右的套餐: {"price":{"operator":"==","value":100,"fluctuation":20%}
然后每次运行,针对deepseek返回的结果,增加补充说明示例,即有针对性的增加示例
流量在100G左右的套餐: {"price":{"operator":"==","value":100,"fluctuation":20%}
流量在200G左右的套餐: {"price":{"operator":"==","value":200,"fluctuation":20%}
30元左右,流量在10G左右的套餐有哪些:{price":{"operator":"==","value":30,"fluctuation":"20%"},"data":{"operator":"==","value":10,"fluctuation":"20%"}
60元左右,流量在80G左右的套餐有哪些:{price":{"operator":"==","value":60,"fluctuation":"20%"},"data":{"operator":"==","value":80,"fluctuation":"20%"}
当示例增加到四个时,才返回想要的结果
{
"name":"经济套餐",
"price":{"operator":"==","value":50,"fluctuation":"20%"},
"data":{"operator":"==","value":100,"fluctuation":"20%"}
}
deepseek-r1的不稳定性
deepseek-r1:1.5b
deepseek-r1:8b
相同的数据反复运行,并不是每次都会返回期望它返回的结果,它有时返回{},即空的json字典
deepseek-r1:14b每次都有结果,但偶尔还是有一定波动性
input_text = "50元左右,流量在100G左右的套餐有哪些"
prompt=query(instruction,output_format,examples,input_text)
# 调用大模型
response = chat_ollama(prompt, response_format="json_object",model='deepseek-r1:14b')
print(response)
{
"price": {
"operator": "==",
"value": 50,
"fluctuation": "20%"
},
"data": {
"operator": "==",
"value": 100,
"fluctuation": "20%"
}
}
14b 8G显卡响应时间11秒多 ,不像1.5b 1-6秒就返回结果了,
1.5b大部分情况下1秒多就返回结果了
折中方法,
- 如果1.5b返回为空,或者特定任务必须有值的字段为空了,则再调用14b
- 有空时,多调用几次,比较3次内某个字段有值即可中断循环;
在该prompt的优化过程中,并不是没有考虑逻辑的优化,
比如fluctuation字段是data/price的字段,按逻辑应该放在2,3的步骤上
但实际上效果不佳
不如增加丰富的示例效果好
- 示例的增加也是根据每次的运行的结果有针对性增加的
|
|