选择需要调用的模型,每个模型的详细信息中会有API示例(deepseek-r1),需要做的就是申请自己的API key就行了,过程中可能需要实名认证

python中安装OpenAI SDK:pip install openai

安装后如果出现ImportError,可能是python的版本低了,升级下版本。当前测试环境是Python 3.9.7,openai==1.63.0。

1.单轮对话

#!/usr/bin/env python3
# -*-coding:utf-8 -*-

from openai import OpenAI

api_key = "sk-xxx"	# 替换

prompt = """
如果你是一名地址NER标注工程师,需要从以下提供的地址情报和文本情报生成该POI地址的主点、分区、楼栋、单元号、楼层、户室号、和描述信息。
注意以下poi为充电桩场景,分区、楼栋、单元号、户室号、和描述信息出现在楼层之后提取,出现在楼层之前不提取。
提取格式要求:
1)主点:一般为xxx停车场、xxx车库、xxx地库。例如万达广场(广阳店)地下停车场。
2)分区:大写数字/大写字母/方向文字/原值+区,如一区/A区/东区。
3)楼栋:阿拉伯数字/大写字母+栋/幢/号楼。
4)单元号:阿拉伯数字/大写字母+单元/座。
5)楼层:地上楼层:阿拉伯数字+层;地下楼层:B+阿拉伯数字+层;无法确认地上或地下:原值+层,如:1层/B1层/LG层。
6)户室号:xx室,不包括xx号,xx商铺。
7)描述信息:具体车位号或者重要参照物和引导方位关键词或其他引导性信息,如1101车位附近/入口向东50m/红色柱子附近。
每个实体提取结果用“实体名:提取值”格式返回,没有提取值的用空字符串代替。不同实体之间按照主点、分区、楼栋、单元号、楼层、户室号、描述信息的顺序,使用“|||”分隔。
重点强调注意最终仅返回以下示例格式结果即可:“主点:万达广场地下停车场|||分区:|||楼栋:|||单元号:|||楼层:B2层|||户室号:|||描述信息:08通道E018”。不需要额外的解释信息。
情报信息:POI名称:森通智达充电站(财富广场地下站)|||地址情报:深圳市福田区深南大道7002号财富广场地下车库负二层264、276、299、307车位|||文本情报:
"""
client = OpenAI(
    api_key=api_key,
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

completion = client.chat.completions.create(
    model="deepseek-r1",
    messages=[
        {'role': 'user', 'content': prompt}
    ]
)

print(f"{'-' * 20}思维链{'-' * 20}")
print(completion.choices[0].message.reasoning_content)

print(f"{'-' * 20}最终结果{'-' * 20}")
print(completion.choices[0].message.content)

--------------------思维链--------------------
好的,我现在需要处理用户提供的地址信息,并按照要求提取各个实体。首先,用户给的情报是森通智达充电站(财富广场地下站),地址在深圳市福田区深南大道7002号财富广场地下车库负二层264、276、299、307车位。文本情报似乎没有额外信息,可能为空。

首先看主点。根据规则,主点通常是停车场、车库或地库。地址中提到“财富广场地下车库”,所以主点应该是“财富广场地下车库”。注意POI名称中的“地下站”可能也指地下车库,但主点应来自地址情报中的明确部分,所以确定主点为财富广场地下车库。

接下来是分区。规则是分区出现在楼层之后才能提取。地址里楼层是负二层,之后的部分是车位号,没有提到分区,所以分区留空。

楼栋和单元号。地址中没有出现楼栋或单元号的信息,比如“X栋”或“X单元”,所以这两项都为空。

楼层部分。地址明确给出“负二层”,根据规则,地下楼层用B+数字,所以这里应该转成B2层。注意用户强调如果是地下楼层,格式是B加数字,所以正确转换。

户室号。规则是xx室,而地址中是车位号,属于描述信息,所以户室号为空。

描述信息需要提取车位号。地址中有264、276、299、307车位,所以描述信息应该把这些列出来,用逗号分隔。

检查一遍是否符合所有规则,尤其是分区、楼栋等是否在楼层之后出现。这里车位号是在楼层之后,但属于描述信息,没问题。确认所有提取项正确无误,没有遗漏。
--------------------最终结果--------------------
主点:财富广场地下车库|||分区:|||楼栋:|||单元号:|||楼层:B2层|||户室号:|||描述信息:264、276、299、307车位

deepseek的文本处理能力确实不错,实际业务中Qwen2.5-7B + SFT微调的效果没有直接上deepseek-r1的效果好,重点在于构建合适的prompt。

2.多轮对话

在单轮对话的基础上,保存每次的历史对话上下文。

user:用户,用于描述用户的输入或问题。
assistant:助手、模型本身,描述模型生成的回复部分。

#!/usr/bin/env python3
# -*-coding:utf-8 -*-

from openai import OpenAI

api_key = "sk-xxx"

prompt = """
如果你是一名地址NER标注工程师,需要从以下提供的地址情报和文本情报生成该POI地址的主点、分区、楼栋、单元号、楼层、户室号、和描述信息。
注意以下poi为充电桩场景,分区、楼栋、单元号、户室号、和描述信息出现在楼层之后提取,出现在楼层之前不提取。
提取格式要求:
1)主点:一般为xxx停车场、xxx车库、xxx地库。例如万达广场(广阳店)地下停车场。
2)分区:大写数字/大写字母/方向文字/原值+区,如一区/A区/东区。
3)楼栋:阿拉伯数字/大写字母+栋/幢/号楼。
4)单元号:阿拉伯数字/大写字母+单元/座。
5)楼层:地上楼层:阿拉伯数字+层;地下楼层:B+阿拉伯数字+层;无法确认地上或地下:原值+层,如:1层/B1层/LG层。
6)户室号:xx室,不包括xx号,xx商铺。
7)描述信息:具体车位号或者重要参照物和引导方位关键词或其他引导性信息,如1101车位附近/入口向东50m/红色柱子附近。
每个实体提取结果用“实体名:提取值”格式返回,没有提取值的用空字符串代替。不同实体之间按照主点、分区、楼栋、单元号、楼层、户室号、描述信息的顺序,使用“|||”分隔。
重点强调注意最终仅返回以下示例格式结果即可:“主点:万达广场地下停车场|||分区:|||楼栋:|||单元号:|||楼层:B2层|||户室号:|||描述信息:08通道E018”。不需要额外的解释信息。
情报信息:POI名称:森通智达充电站(财富广场地下站)|||地址情报:深圳市福田区深南大道7002号财富广场地下车库负二层264、276、299、307车位|||文本情报:
"""

# 保存所有对话的上下文
messages = [{'role': 'user', 'content': prompt}]

client = OpenAI(
    api_key=api_key,
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)

completion = client.chat.completions.create(
    model="deepseek-r1",
    messages=messages
)
print(f"{'+' * 20}第一轮对话{'+' * 20}")
print(f"{'-' * 20}思维链{'-' * 20}")
print(completion.choices[0].message.reasoning_content)
print(f"{'-' * 20}最终结果{'-' * 20}")
print(completion.choices[0].message.content)


# 上一轮模型的回答
messages.append({'role': 'assistant', 'content': completion.choices[0].message.content})
# 本轮新的问题
messages.append({'role': 'user', 'content': '上一个问题是什么,简述问题本身即可,不用重新回答'})
completion = client.chat.completions.create(
    model="deepseek-r1",
    messages=messages
)
print(f"{'+' * 20}第二轮对话{'+' * 20}")
print(f"{'-' * 20}思维链{'-' * 20}")
print(completion.choices[0].message.reasoning_content)
print(f"{'-' * 20}最终结果{'-' * 20}")
print(completion.choices[0].message.content)

++++++++++++++++++++第一轮对话++++++++++++++++++++
--------------------思维链--------------------
好的,我需要处理用户提供的地址和文本情报,提取出主点、分区、楼栋、单元号、楼层、户室号和描述信息。首先看POI名称是“森通智达充电站(财富广场地下站)”,地址情报是“深圳市福田区深南大道7002号财富广场地下车库负二层264、276、299、307车位”。

主点通常是指停车场、车库或地库,所以这里应该是财富广场地下车库。地址中提到负二层,所以楼层是B2层。后面的车位号264、276、299、307属于描述信息,所以描述信息填这些车位。

接下来检查其他字段是否有内容。分区、楼栋、单元号和户室号在地址中没有出现,所以留空。根据规则,出现在楼层之后的部分才提取,这里车位号在楼层之后,所以正确。确认每个实体的提取是否符合要求,比如楼层是否正确格式,描述信息是否包含车位号。最后按照格式排列,用|||分隔,没有的留空。
--------------------最终结果--------------------
主点:财富广场地下车库|||分区:|||楼栋:|||单元号:|||楼层:B2层|||户室号:|||描述信息:264、276、299、307车位
++++++++++++++++++++第二轮对话++++++++++++++++++++
--------------------思维链--------------------
好的,我现在需要处理用户的上一个问题。首先,用户当前的问题是在询问上一个问题是什么,并且要求简要描述问题本身,不需要重新回答。

首先,我要回忆一下之前的对话历史。用户之前给了一个关于地址NER标注的任务,要求从提供的地址情报和文本情报中提取多个实体,如主点、分区、楼栋等,并按照特定格式返回结果。用户还提供了一个例子,以及情报信息,然后助手给出了正确的提取结果。

现在用户的新问题是询问上一个问题是什么,只需简述问题本身。我需要确定用户的具体需求,可能是在确认之前的问题内容,或者需要回顾之前的任务要求,但根据当前问题,用户不需要重新回答,只需要知道上一个问题的内容。

接下来,我需要回顾对话历史中的上一个问题。用户之前的请求是要求作为地址NER标注工程师,根据给定的情报信息生成特定格式的实体提取结果。用户特别强调了格式要求和示例,并提供了具体的情报信息,包括POI名称、地址情报和文本情报。然后助手正确提取了主点、楼层和描述信息,其他字段为空。

现在用户的问题是关于“上一个问题是什么”,我需要用中文简短地描述上一个问题的内容,而不需要重复之前的回答。需要确保回答准确,符合用户的要求,避免添加额外信息或解释。

确认用户的需求后,我应该用简洁的语言概述上一个问题,即用户请求根据充电桩场景的地址和文本情报提取特定实体,并按照格式返回结果。不需要提及之前的回答内容或具体提取的实体值,只说明任务本身即可。

最后,检查回答是否符合要求:是否简述问题本身,是否使用中文,是否避免额外信息。确认无误后,给出答案。
--------------------最终结果--------------------
上一个问题是要求根据提供的充电桩场景地址情报和文本情报,按照特定格式提取主点、分区、楼栋、单元号、楼层、户室号及描述信息,并返回结构化结果。

以上根据文档实现的一个简单调用,调用默认都是非流式的,一次性返回最终结果,实际业务中这种方式较常见,但可能会因为生成的结果内容比较多而超时或者占内存。流式的是模型边生成结果边返回,具体实现方式可以参考文档示例。

参考文档

完整的开发流程参考:https://help.aliyun.com/zh/model-studio/developer-reference
错误码排查:https://help.aliyun.com/zh/model-studio/developer-reference/error-code

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐