an explicit 'draw it' request without topic words gets the whole diagram catalog (tutor-v8-asked-figure)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 03:34:12 +03:30
parent 731dea9bb1
commit a8cd681d65
4 changed files with 34 additions and 4 deletions

View File

@@ -177,6 +177,23 @@ def follow_up_hint_for(question: str, previous: str) -> str:
return '\n'.join([FOLLOW_UP_HINT, _HEAD, *parts])
# «شکلش رو بکش» بی‌هیچ کلمه‌ی موضوعی (و بی‌سوالِ شکل‌دارِ قبلی): نمی‌دانیم کدام بخش،
# پس کلِ کاتالوگ می‌رود (~۱٬۹۰۰ توکن). نادر است، چون بیشترِ درخواست‌ها کلمه‌ی موضوعی دارند.
# مرزِ پیش از کلمه لازم است: «مشکل» و «بپرسم» نباید درخواستِ شکل شمرده شوند.
_ASK_FIGURE = re.compile(r'(?<![\u0600-\u06FF])(?:شکل|رسم|بکش|تصویر)')
ASKED_HINT = (
'دانش‌آموز شکل خواسته: اگر مسئله شکلی دارد، در پایانِ پاسخ بلوکِ <diagram>…</diagram> را '
'طبقِ این قالب بگذار؛ اگر ندارد، کوتاه بگو که این مسئله شکل ندارد.'
)
def asked_hint_for(question: str) -> str:
"""درخواستِ صریحِ شکل وقتی هیچ بخشی از کاتالوگ با سوال (یا سوالِ قبلی) نخورد."""
if not _ASK_FIGURE.search(question or ''):
return ''
return '\n'.join([ASKED_HINT, DIAGRAM_SPEC])
def hint_for(question: str) -> str:
"""یادآوری و فقط آن بخش‌هایی از کاتالوگ که به همین سوال می‌خورند؛ سوالِ بی‌شکل → ''."""
text = question or ''

View File

@@ -38,7 +38,7 @@ _RAW_MARKUP = re.compile(r'\\[A-Za-z(\[]|\$|\*\*|^\s*#{1,6}\s|^\s*\|\s*:?-{3,}',
# بشود گفت «کدام نسخه‌ی پرامپت جوابِ بهتری می‌داد» — بدونِ این، همه‌ی فیدبک‌ها
# در یک کاسه می‌ریزند و مقایسه‌ی نسخه‌ها ممکن نیست. کشِ پاسخ هم با همین نسخه
# کلید می‌خورد، پس جوابِ نسخه‌ی قبلی بعد از دیپلوی دوباره سرو نمی‌شود.
PROMPT_VERSION = 'tutor-v7-diagram-kit'
PROMPT_VERSION = 'tutor-v8-asked-figure'
_PRIMARY = {'اول', 'دوم', 'سوم', 'چهارم', 'پنجم', 'ششم'}
_MIDDLE = {'هفتم', 'هشتم', 'نهم'}
@@ -184,7 +184,8 @@ def _user_prompt(question: str, contexts: list[str], focus: str = '',
asked = (f'{asked}\n(این ادامه‌ی گفتگوست؛ سوالِ قبلیِ دانش‌آموز: «{previous[:300]}». '
'اگر به آن مربوط است، همان مسئله را با تغییرِ خواسته‌شده حل کن.)')
shape_hint = (diagram_mod.hint_for(f'{question}\n{focus}')
or diagram_mod.follow_up_hint_for(question, previous))
or diagram_mod.follow_up_hint_for(question, previous)
or diagram_mod.asked_hint_for(question))
if shape_hint:
asked = f'{asked}\n\n{shape_hint}'
slash_rule = primary and '/' in question

View File

@@ -130,7 +130,7 @@ class DiagramThroughTheApiTests(TestCase):
message = Message.objects.get(role='assistant', conversation__user_id=self.user.id)
self.assertEqual(message.diagram, done['diagram'])
self.assertEqual(message.prompt_version, 'tutor-v7-diagram-kit')
self.assertEqual(message.prompt_version, 'tutor-v8-asked-figure')
history = self.client.get(f'/api/ai/conversations/{done["conversationId"]}/messages').json()
self.assertEqual(history['messages'][-1]['diagram']['kind'], 'plane')
self.assertIsNone(history['messages'][0]['diagram'])
@@ -352,6 +352,16 @@ class FollowUpHintTests(SimpleTestCase):
self.assertIn(DIAGRAM_HINT, last)
self.assertNotIn(FOLLOW_UP_HINT, last)
def test_explicit_request_without_topic_words_gets_the_whole_catalog(self):
from .services.diagram import ASKED_HINT, DIAGRAM_SPEC, asked_hint_for
from .services.generation import build_messages
last = build_messages('یه باغچه ۵ در ۸ متره، شکلش رو برام بکش', None, 'ششم')[-1]['content']
self.assertIn(ASKED_HINT, last)
self.assertIn(DIAGRAM_SPEC, last)
for q in ('مشکل دارم با این سوال', 'می‌خوام یه سوال بپرسم', '۳۴۵ × ۱۲'):
self.assertEqual(asked_hint_for(q), '', q)
class ThirdRoundTests(SimpleTestCase):
"""از چتِ واقعی با gpt-4.1-mini (۲۰۲۶-۰۹-۲۹): خط، چندضلعیِ منتظم، زاویه‌ی خارجی، کسرِ کلمه‌ای."""