Skip to content

Commit b134971

Browse files
authored
russian prompt and augmentation generation (#127)
* russian prompt and augmentation generation * added metaclass, moved files
1 parent 4645706 commit b134971

File tree

2 files changed

+130
-34
lines changed

2 files changed

+130
-34
lines changed

autointent/generation/utterances/basic/chat_template.py

Lines changed: 129 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,62 @@ def __call__(self, intent_data: Intent, n_examples: int) -> list[Message]:
1818
"""Generate examples for this intent."""
1919

2020

21-
class SynthesizerChatTemplate(BaseSynthesizer):
21+
class BaseSynthesizerChatTemplate(BaseSynthesizer):
22+
"""Base chat template for generating additional examples for a given intent."""
23+
24+
_MESSAGES_TEMPLATE: ClassVar[list[Message]] = []
25+
_INTENT_NAME_LABEL: ClassVar[str] = "Intent name"
26+
_EXAMPLE_UTTERANCES_LABEL: ClassVar[str] = "Example Utterances"
27+
_GENERATE_INSTRUCTION: ClassVar[str] = "Please generate {n_examples} more examples for the provided intent class.\n"
28+
29+
def __init__(
30+
self,
31+
dataset: Dataset,
32+
split: str,
33+
extra_instructions: str | None = None,
34+
max_sample_utterances: int | None = None,
35+
) -> None:
36+
"""Initialize the chat template with dataset, split, and optional instructions."""
37+
if extra_instructions is None:
38+
extra_instructions = ""
39+
40+
self._messages = deepcopy(self._MESSAGES_TEMPLATE)
41+
42+
if self._messages:
43+
self._messages[0]["content"] = self._messages[0]["content"].format(extra_instructions=extra_instructions)
44+
45+
self.dataset = dataset
46+
self.split = split
47+
self.max_sample_utterances = max_sample_utterances
48+
49+
def __call__(self, intent_data: Intent, n_examples: int) -> list[Message]:
50+
"""Generate a list of messages to request additional examples for the given intent."""
51+
filtered_split = self.dataset[self.split].filter(lambda sample: sample[Dataset.label_feature] == intent_data.id)
52+
sample_utterances = filtered_split[Dataset.utterance_feature]
53+
54+
if self.max_sample_utterances is not None and len(sample_utterances) > self.max_sample_utterances:
55+
sample_utterances = random.sample(sample_utterances, k=self.max_sample_utterances)
56+
57+
return [
58+
*self._messages,
59+
self._create_final_message(intent_data, n_examples, sample_utterances),
60+
]
61+
62+
def _create_final_message(self, intent_data: Intent, n_examples: int, sample_utterances: list[str]) -> Message:
63+
content = f"{self._INTENT_NAME_LABEL}: {intent_data.name}\n\n" f"{self._EXAMPLE_UTTERANCES_LABEL}:\n"
64+
65+
if sample_utterances:
66+
numbered_utterances = "\n".join(f"{i+1}. {utt}" for i, utt in enumerate(sample_utterances))
67+
content += numbered_utterances + "\n\n"
68+
69+
content += self._GENERATE_INSTRUCTION.format(n_examples=n_examples)
70+
return Message(role=Role.USER, content=content)
71+
72+
73+
class SynthesizerChatTemplate(BaseSynthesizerChatTemplate):
2274
"""Chat template for generating additional examples for a given intent class."""
2375

24-
__messages: ClassVar[list[Message]] = [
76+
_MESSAGES_TEMPLATE: ClassVar[list[Message]] = [
2577
Message(
2678
role=Role.USER,
2779
content=(
@@ -97,38 +149,81 @@ class SynthesizerChatTemplate(BaseSynthesizer):
97149
),
98150
]
99151

100-
def __init__(
101-
self,
102-
dataset: Dataset,
103-
split: str,
104-
extra_instructions: str | None = None,
105-
max_sample_utterances: int | None = None,
106-
) -> None:
107-
"""Initialize."""
108-
if extra_instructions is None:
109-
extra_instructions = ""
110-
111-
self._messages = deepcopy(self.__messages)
112-
113-
msg = self._messages[0]
114-
msg["content"] = msg["content"].format(extra_instructions=extra_instructions)
115152

116-
self.dataset = dataset
117-
self.split = split
118-
self.max_sample_utterances = max_sample_utterances
153+
class SynthesizerChatTemplateRussian(BaseSynthesizerChatTemplate):
154+
"""Russian language template for generating additional intent examples."""
119155

120-
def __call__(self, intent_data: Intent, n_examples: int) -> list[Message]:
121-
"""Generate additional examples for the provided intent class."""
122-
filtered_split = self.dataset[self.split].filter(lambda sample: sample[Dataset.label_feature] == intent_data.id)
123-
sample_utterances = filtered_split[Dataset.utterance_feature]
124-
if self.max_sample_utterances is not None:
125-
sample_utterances = random.sample(sample_utterances, k=self.max_sample_utterances)
126-
return [
127-
*self._messages,
128-
Message(
129-
role=Role.USER,
130-
content=f"Intent name: {intent_data.name}\n\n"
131-
f"Example Utterances:\n{sample_utterances}\n\n"
132-
f"Please generate {n_examples} more examples for the provided intent class.\n",
156+
_MESSAGES_TEMPLATE: ClassVar[list[Message]] = [
157+
Message(
158+
role=Role.USER,
159+
content=(
160+
"Вам будет предоставлен набор примеров высказываний и название общей темы (интент). "
161+
"Ваша задача - сгенерировать дополнительные примеры, соответствующие этому интенту.\n\n"
162+
"Правила:\n"
163+
"- Можно менять значения слотов в похожих высказываниях\n"
164+
"- Можно создавать совершенно другие формулировки для того же интента\n"
165+
"- Если название интента отсутствует, определите его из примеров\n"
166+
"- Если примеры отсутствуют, используйте только название интента\n"
167+
"{extra_instructions}\n\n"
168+
"Название интента: заказ_пиццы\n\n"
169+
"Примеры высказываний:\n"
170+
"1. Хочу заказать большую пиццу с пепперони\n"
171+
"2. Можно среднюю пиццу с сыром и оливками?\n"
172+
"3. Привезите маленькую вегетарианскую пиццу по моему адресу\n\n"
173+
"Пожалуйста, сгенерируй еще 3 примера для этого интента."
133174
),
134-
]
175+
),
176+
Message(
177+
role=Role.ASSISTANT,
178+
content=(
179+
"1. Мне нужна большая пицца Маргарита\n"
180+
"2. Можно гавайскую пиццу среднего размера с дополнительным ананасом?\n"
181+
"3. Доставьте маленькую пиццу с курицей барбекю на дом"
182+
),
183+
),
184+
Message(
185+
role=Role.USER,
186+
content=(
187+
"Название интента: бронирование_отеля\n\n"
188+
"Примеры высказываний:\n"
189+
"1. Нужно забронировать номер в Москве на две ночи\n\n"
190+
"Пожалуйста, сгенерируй еще 2 примера для этого интента."
191+
),
192+
),
193+
Message(
194+
role=Role.ASSISTANT,
195+
content=("1. Забронируйте люкс в Санкт-Петербурге на выходные\n" "2. Ищу номер с видом на море в Сочи"),
196+
),
197+
Message(
198+
role=Role.USER,
199+
content=(
200+
"Название интента:\n\n"
201+
"Примеры высказываний:\n"
202+
"1. Какая сегодня погода?\n\n"
203+
"Пожалуйста, сгенерируй еще 2 примера для этого интента."
204+
),
205+
),
206+
Message(
207+
role=Role.ASSISTANT,
208+
content=("1. Какой прогноз на завтра?\n" "2. Будет ли дождь в субботу?"),
209+
),
210+
Message(
211+
role=Role.USER,
212+
content=(
213+
"Название интента: запись_на_прием\n\n"
214+
"Примеры высказываний:\n\n"
215+
"Пожалуйста, сгенерируй еще 3 примера для этого интента."
216+
),
217+
),
218+
Message(
219+
role=Role.ASSISTANT,
220+
content=(
221+
"1. Нужно записаться к врачу на следующую неделю\n"
222+
"2. Хочу назначить встречу с парикмахером на пятницу\n"
223+
"3. Свободно ли время в пятницу утром для визита?"
224+
),
225+
),
226+
]
227+
_INTENT_NAME_LABEL = "Название интента"
228+
_EXAMPLE_UTTERANCES_LABEL = "Примеры высказываний"
229+
_GENERATE_INSTRUCTION = "Пожалуйста, сгенерируй {n_examples} дополнительных примеров для этого интента.\n"

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ ignore = [
116116
"ISC001", # implicit string concatenation
117117
"ERA001", # commented code
118118
"FBT", # boolean trap
119+
"RUF001", # ambiguous unicode character
119120
]
120121

121122
[tool.ruff.lint.per-file-ignores]

0 commit comments

Comments
 (0)