|
1 | | -from typing import Union, Optional |
| 1 | +from typing import Union, Optional, Sequence |
| 2 | +from dataclasses import dataclass |
2 | 3 |
|
3 | 4 |
|
4 | 5 | RECOGNIZE_INTENTION_PROMPT = """你是一个任务决策助手,能够将理解用户意图并决策采取最合适的行动,尽可能地以有帮助和准确的方式回应人类, |
|
64 | 65 | ''' |
65 | 66 |
|
66 | 67 |
|
| 68 | +GENERAL_INTENTION_PROMPT = """## 背景 |
| 69 | +作为智能助手,您需要根据用户询问判断其主要意图,以确定接下来的行动。 |
| 70 | +
|
| 71 | +## 任务 |
| 72 | +找出最相关的意图,包括以下{num}种: |
| 73 | +{intention} |
| 74 | +
|
| 75 | +## 输出格式 |
| 76 | +最相关意图对应的数字(第一个意图对应数字1){extra}。 |
| 77 | +{example} |
| 78 | +## 用户询问 |
| 79 | +""" |
| 80 | + |
| 81 | + |
| 82 | +@dataclass |
| 83 | +class IntentionInfo: |
| 84 | + description: str |
| 85 | + name: Optional[str] = None |
| 86 | + tag: Optional[str] = None |
| 87 | + |
| 88 | + def __post_init__(self): |
| 89 | + marks = '.。,,;;::??\t\n ' |
| 90 | + self.description = self.description.replace('{', '{{').replace('}', '}}').strip(marks) |
| 91 | + |
| 92 | + if self.name: |
| 93 | + self.name = self.name.replace('{', '{{').replace('}', '}}').strip(marks) |
| 94 | + |
| 95 | + def __str__(self): |
| 96 | + if self.name: |
| 97 | + return f'{self.name}:{self.description}' |
| 98 | + return self.description |
| 99 | + |
| 100 | + |
67 | 101 | def get_intention_prompt( |
68 | | - background: str, intentions: Union[list, tuple], examples: Optional[dict]=None, |
| 102 | + intentions: Sequence[IntentionInfo], |
| 103 | + examples: Optional[dict[str, Union[IntentionInfo, Sequence[IntentionInfo]]]]=None, |
69 | 104 | allow_multiple_choice=False |
70 | 105 | ) -> str: |
71 | 106 | nums_zh = ('一', '两', '三', '四', '五', '六', '七', '八', '九', '十') |
72 | | - marks = '.。,,;;::??\t\n' |
73 | 107 |
|
74 | 108 | intention_num = len(intentions) |
75 | | - num_zh = nums_zh[intention_num - 1] if intention_num <= 10 else intention_num |
76 | | - prompt = f'##背景##\n{background}\n\n##任务##\n找出最相关的意图,包括以下{num_zh}种:\n' |
77 | | - |
78 | | - for i, val in enumerate(intentions): |
79 | | - if isinstance(val, (list, tuple)): |
80 | | - k, v = val |
81 | | - cur_intention = '{}. {}:{};\n'.format(i + 1, k, v.strip(marks)) |
82 | | - else: |
83 | | - cur_intention = '{}. {};\n'.format(i + 1, val.strip(marks)) |
84 | | - prompt += cur_intention |
| 109 | + intention_num_zh = nums_zh[intention_num - 1] if intention_num <= len(nums_zh) else intention_num |
| 110 | + |
| 111 | + intentions_str, intention2idx = '', dict() |
| 112 | + for i, intention_info in enumerate(intentions): |
| 113 | + end_mark = '。' if i == intention_num - 1 else ';' |
| 114 | + intentions_str += '{}. {}{}\n'.format(i + 1, intention_info, end_mark) |
| 115 | + intention2idx[str(intention_info)] = i + 1 |
85 | 116 |
|
86 | | - temp = ',若存在多个意图都是最相关的,请用","分开' if allow_multiple_choice else '' |
87 | | - prompt += f'\n##输出格式##\n最相关意图对应的数字(第一个意图对应数字1){temp}。\n\n' |
| 117 | + extra = ',若存在多个意图都是最相关的,请用","分开' if allow_multiple_choice else '' |
88 | 118 |
|
| 119 | + example_str = '' |
89 | 120 | if examples: |
90 | | - prompt += '##示例##\n' |
91 | | - intention_idx_map = {k[0]: idx + 1 for idx, k in enumerate(intentions)} |
92 | | - for query, ans in examples.items(): |
93 | | - if not isinstance(ans, (list, tuple)): |
94 | | - ans = [ans] |
95 | | - ans = ','.join([str(intention_idx_map[x]) for x in ans]) |
96 | | - prompt += f'问题:{query}\n回答:{ans}\n\n' |
| 121 | + example_str += '\n## 示例\n' |
| 122 | + for query, label in examples.items(): |
| 123 | + if isinstance(label, IntentionInfo): |
| 124 | + label = [label] |
| 125 | + label = ','.join([str(intention2idx[str(x)]) for x in label]) |
| 126 | + example_str += f'问题:{query}\n回答:{label}\n' |
97 | 127 |
|
98 | | - prompt += '##用户询问##\n问题:{query}\n回答:' |
| 128 | + prompt = GENERAL_INTENTION_PROMPT.format( |
| 129 | + num=intention_num_zh, |
| 130 | + intention=intentions_str[:-1], |
| 131 | + extra=extra, |
| 132 | + example=example_str |
| 133 | + ) |
| 134 | + |
| 135 | + prompt += '问题:{query}\n回答:' |
99 | 136 | return prompt |
100 | 137 |
|
101 | 138 |
|
102 | | -INTENTIONS_CONSULT_WHICH = [ |
103 | | - ('整体计划查询', '用户想要获取某个问题的答案,或某个解决方案的完整流程(步骤)。'), |
104 | | - ('下一步任务查询', '用户询问某个问题或方案的特定步骤,通常会提及“下一步”、“具体操作”等'), |
105 | | - ('闲聊', '用户询问的内容与当前的技术问题或解决方案无关,更多是出于兴趣或社交性质的交流。') |
106 | | -] |
107 | | -INTENTIONS_CONSULT_WHICH_CODE = { |
108 | | - '整体计划查询': 'allPlan', |
109 | | - '下一步任务查询': 'nextStep', |
110 | | - '闲聊': 'justChat' |
111 | | -} |
112 | | -CONSULT_WHICH_PROMPT = get_intention_prompt( |
113 | | - '作为智能助手,您的职责是根据用户询问的内容,精准判断其背后的意图,以便提供最恰当的服务和支持。', |
114 | | - INTENTIONS_CONSULT_WHICH, |
115 | | - { |
116 | | - '如何组织一次活动?': '整体计划查询', |
117 | | - '系统升级的整个流程是怎样的?': '整体计划查询', |
118 | | - '为什么我没有收到红包?请告诉我方案': '整体计划查询', |
119 | | - '听说你们采用了新工具,能讲讲它的特点吗?': '闲聊' |
120 | | - } |
| 139 | +INTENTION_ALLPLAN = IntentionInfo( |
| 140 | + description='用户想要获取某个问题的答案,或某个解决方案的完整流程(步骤)。', |
| 141 | + name='整体计划查询', tag='allPlan' |
| 142 | +) |
| 143 | +INTENTION_NEXTSTEP = IntentionInfo( |
| 144 | + description='用户询问某个问题或方案的特定步骤,通常会提及“下一步”、“具体操作”等。', |
| 145 | + name='下一步任务查询', tag='nextStep' |
| 146 | +) |
| 147 | +INTENTION_CHAT = IntentionInfo( |
| 148 | + description='用户询问的内容与当前的技术问题或解决方案无关,更多是出于兴趣或社交性质的交流。', |
| 149 | + name='闲聊', tag='justChat' |
| 150 | +) |
| 151 | +INTENTION_EXECUTE = IntentionInfo( |
| 152 | + description='用户在使用某平台、服务、产品或功能时遇到了问题,或者要求完成某一需要执行的任务,或者明确声明要执行某一流程或游戏', |
| 153 | + name='执行' |
| 154 | +) |
| 155 | +INTENTION_QUERY = IntentionInfo( |
| 156 | + description='用户的主要目的是获取信息而非执行任务(比如:怎么向银行申请贷款),或只是简单闲聊。', |
| 157 | + name='询问' |
| 158 | +) |
| 159 | +INTENTION_NOMATCH = IntentionInfo( |
| 160 | + description='与上述意图都不匹配,属于其他类型的询问意图。' |
121 | 161 | ) |
122 | 162 |
|
123 | | -INTENTIONS_WHETHER_EXEC = [ |
124 | | - ('执行', '用户在使用某平台、服务、产品或功能时遇到了问题,或者明确声明要执行某一流程或游戏。'), |
125 | | - ('询问', '用户的主要目的是获取信息,或只是简单闲聊。') |
126 | | -] |
| 163 | +INTENTIONS_WHETHER_EXEC = (INTENTION_EXECUTE, INTENTION_QUERY) |
127 | 164 | WHETHER_EXECUTE_PROMPT = get_intention_prompt( |
128 | | - '作为智能助手,您需要根据用户询问判断其主要意图,以便提供最恰当的服务和支持。', |
129 | | - INTENTIONS_WHETHER_EXEC, |
130 | | - { |
131 | | - '为什么我的优惠券使用失败?': '执行', |
132 | | - '公司团建怎么申请?': '询问', |
133 | | - '开始玩游戏。': '执行' |
| 165 | + intentions=INTENTIONS_WHETHER_EXEC, |
| 166 | + examples={ |
| 167 | + '为什么我的优惠券使用失败?': INTENTION_EXECUTE, |
| 168 | + '如何向银行贷款?': INTENTION_QUERY, |
| 169 | + '开始玩游戏。': INTENTION_EXECUTE, |
| 170 | + '帮我看一下今天的天气怎么样': INTENTION_EXECUTE |
134 | 171 | } |
135 | 172 | ) |
136 | 173 |
|
137 | | -DIRECT_CHAT_PROMPT = """##背景## |
138 | | -作为智能助手,您的职责是根据自身专业知识回答用户询问,以便提供最恰当的服务和支持。 |
139 | | -
|
140 | | -##任务## |
141 | | -基于您所掌握的领域知识,对用户的提问进行回答。 |
142 | | -
|
143 | | -##注意事项## |
144 | | -1. 请尽量从客观的角度来回答问题,内容符合事实、有理有据。 |
145 | | -2. 内容尽量简洁。 |
146 | | -
|
147 | | -##用户询问## |
148 | | -询问:{query} |
149 | | -回答: |
150 | | -""" |
| 174 | +INTENTIONS_CONSULT_WHICH = (INTENTION_ALLPLAN, INTENTION_NEXTSTEP, INTENTION_CHAT) |
| 175 | +CONSULT_WHICH_PROMPT = get_intention_prompt( |
| 176 | + intentions=INTENTIONS_CONSULT_WHICH, |
| 177 | + examples={ |
| 178 | + '如何组织一次活动?': INTENTION_ALLPLAN, |
| 179 | + '系统升级的整个流程是怎样的?': INTENTION_ALLPLAN, |
| 180 | + '为什么我没有收到红包?请告诉我方案': INTENTION_ALLPLAN, |
| 181 | + '听说你们采用了新工具,能讲讲它的特点吗?': INTENTION_CHAT |
| 182 | + } |
| 183 | +) |
0 commit comments