तकनीकी पाठकों के लिए
सेवा कैसे काम करती है
परिवार जिस चैट को पहले से इस्तेमाल करता है, MathTrail उसके और अभिभावक की Google Drive के बीच खड़ा है। हर सवाल चैट का मॉडल लिखता है, और सेवा तय करती है कि वह बच्चे तक पहुँचेगा या नहीं। यह एक ही प्रोग्राम है, जो खुद किसी मॉडल को कॉल नहीं करता और अनुरोधों के बीच कुछ भी नहीं रखता।
- Cloud Run पर एक Go बाइनरी
- स्टेटलेस
- कोई डेटाबेस नहीं
- अपनी कोई LLM कॉल नहीं
- MCP 2026-07-28 · MCP Apps
चैट क्लाइंट1 · क्लाइंट
- Claude
- ChatGPT
- दूसरे MCP Apps होस्ट
चैट का मॉडल सवाल लिखता है, और कार्ड उसे बच्चे को दिखाता है।
MCP · HTTPS पर टूल कॉल
Google Cloud पर MathTrail2 · रनटाइम
Cloud Run · एक Go बाइनरी · स्टेटलेस
कोर — सिर्फ़ गणना
- नियम
- रेटिंग
- जाँचें
- सॉल्वर
- सामग्री
उसके आसपास: OAuth, MCP सर्वर, कार्ड, सील करना, सीमाएँ।
Drive API v3 · अभिभावक के अपने टोकन से
Google Drive3 · स्टोरेज
MathTrail/mathtrail-profile.json
हर बच्चे की एक फ़ाइल, अभिभावक की अपनी Drive में — लंबे समय तक रखी जाने वाली इकलौती चीज़।
01
नक्शा
किसकी किससे बात होती है। न बच्चे की, न बड़े व्यक्ति की MathTrail से सीधी बात होती है — दोनों की बात चैट होस्ट से होती है। बीच वाले ब्लॉक में जो कुछ है, वह एक ही प्रोसेस का हिस्सा है, कोई अलग सेवा नहीं। कोई भी हिस्सा चुनें, तो दिखेगा कि वह क्या करता है और किससे जुड़ा है।
02
एक पाठ, कॉल-दर-कॉल
मॉडल और कार्ड एक ही टूल कॉल करते हैं और सच के एक ही स्रोत पर टिके हैं — अभिभावक की Drive में प्रोफ़ाइल की फ़ाइल। पाठ चलता रहे, इसके लिए उन्हें एक-दूसरे को कुछ बताने की ज़रूरत नहीं।
सवाल
- बड़ा व्यक्ति
- कार्ड
- होस्ट का मॉडल
- MathTrail
- Drive
1बड़ा व्यक्ति → होस्ट का मॉडल: “एक नया सवाल दें”
2होस्ट का मॉडल → MathTrail: next_task
कॉल शुरू होते ही होस्ट कार्ड दिखाता है: “अगला सवाल तैयार हो रहा है…”
सीमाएँ · नियम विषय, स्तर और कठिनाई चुनता है
3MathTrail → Drive: खुला अनुरोध लिखना
4MathTrail → होस्ट का मॉडल: अनुरोध खुला है — पैकेज लें
5होस्ट का मॉडल → MathTrail: get_package
6MathTrail → होस्ट का मॉडल: ब्रीफ़ · 3 संदर्भ सवाल · जाल · टेंपलेट · चित्रों के उदाहरण
मॉडल सवाल, Starlark सॉल्वर और खुद की जाँच लिखता है
7होस्ट का मॉडल → MathTrail: submit_task — ज़्यादा से ज़्यादा 3 कोशिशें
जाँचें · सॉल्वर को ठीक एक सही विकल्प मिलना चाहिए
8MathTrail → Drive: सवाल मौजूदा बन जाता है, उसका जवाब सीलबंद
9कार्ड → MathTrail: read_task — कार्ड हर 4 सेकंड में पूछता है
10MathTrail → कार्ड: टेक्स्ट · चित्र · पाँच विकल्प · संकेत — जवाब नहीं
हर कॉल Drive से प्रोफ़ाइल भी पढ़ती है — पढ़ने की ये कॉल यहाँ छोड़ दी गई हैं। इंतज़ार करने वाला कार्ड पैकेज कभी नहीं देखता: पैकेज के संदर्भ सवालों में उनके जवाब होते हैं। जब तक बच्चा हल करे, मॉडल prepare_task से अगला सवाल पहले से लिख लेता है, और जब अगला सवाल माँगा जाता है, तो next_task उसे तुरंत एक नए कार्ड पर रख देता है — इस इंतज़ार के बिना।
जवाब
- बड़ा व्यक्ति
- बच्चा
- कार्ड
- होस्ट का मॉडल
- MathTrail
- Drive
1बच्चा → कार्ड: C दबाना
2कार्ड → MathTrail: submit_answer — चैट की कोई बारी खर्च नहीं होती
सिर्फ़ पहला जवाब · सील अब खोली जाती है · θ और δ सिर्फ़ इस पर बदलते हैं कि जवाब सही है या नहीं
3MathTrail → Drive: रेटिंग और इतिहास लिखना
4MathTrail → कार्ड: सही या नहीं · C के पीछे का जाल · हल का चित्र · कदम · रेटिंग पहले → बाद में
कार्ड, सवाल की जगह, जवाब के विश्लेषण में बदल जाता है
5कार्ड → होस्ट का मॉडल: ui/update-model-context — एक पंक्ति, जो बड़े व्यक्ति के अगले संदेश के साथ पढ़ी जाती है
6बड़ा व्यक्ति → होस्ट का मॉडल: “एक खंभा ज़्यादा क्यों?”
7होस्ट का मॉडल → बड़ा व्यक्ति: ठीक इसी सवाल के बारे में जवाब देता है, कार्ड की बात को आगे बढ़ाते हुए
दबाते ही जवाब दर्ज हो जाता है, कुछ भी समझाए जाने से पहले, और कार्ड तुरंत जवाब के विश्लेषण में बदल जाता है। चैट की कोई बारी खर्च नहीं होती, और मॉडल कुछ नहीं बनाता। वह कार्ड की पंक्ति बड़े व्यक्ति के अगले संदेश के साथ पढ़ता है, और सवाल के बारे में पूछी गई बात का जवाब कार्ड को दोहराए बिना देता है। अगर होस्ट से मॉडल को भेजी गई पंक्ति खो जाए, तो मॉडल अपनी अगली कॉल पर छूटी बात जान लेता है।
साइन-इन
- अभिभावक का ब्राउज़र
- होस्ट
- MathTrail
- Drive
1होस्ट → MathTrail: POST /mcp, बिना टोकन
2MathTrail → होस्ट: 401 · मेटाडेटा कहाँ है
3होस्ट → अभिभावक का ब्राउज़र: /oauth/authorize खोलता है · PKCE S256
4अभिभावक का ब्राउज़र → MathTrail: authorize
अपनी सहमति स्क्रीन: कौन-सा क्लाइंट, और वह अभिभावक को कहाँ वापस भेजेगा
5अभिभावक का ब्राउज़र → Google: Google से साइन-इन · सिर्फ़ drive.file
6Google → अभिभावक का ब्राउज़र: वापस, Google के कोड के साथ
7अभिभावक का ब्राउज़र → MathTrail: /oauth/callback
8MathTrail → Google: कोड एक्सचेंज करना
9MathTrail → Drive: /about — यह Drive किसकी है?
यूज़र आईडी = Drive खाते का HMAC · Google के टोकन हमारे कोड में सीलबंद
10MathTrail → अभिभावक का ब्राउज़र: 302 · code = mt1.c.…
11अभिभावक का ब्राउज़र → होस्ट: कोड वापस सौंपता है
12होस्ट → MathTrail: /oauth/token · कोड + verifier
13MathTrail → होस्ट: ऐक्सेस 15 मि॰ · रीफ़्रेश 30 दिन
अभिभावक को सिर्फ़ एक बार साइन इन करना होता है। सेवा इस लेन-देन का कुछ भी नहीं रखती: अनुरोध सीलबंद स्टेट में जाता है, और Google के टोकन सीलबंद कोड में।
स्टेट मशीन के रूप में मौजूदा सवाल
“सिर्फ़ एक बार” वाला हर नियम प्रोफ़ाइल का एक फ़ील्ड है, जो पढ़ने, गणना और लिखने के उसी एक चक्र में जाँचा जाता है। इसके अलावा कहीं कुछ याद नहीं रखा जाता।
nonenext_taskब्रीफ़ तैयारrequestedsubmit_task ✓सीलबंद, सौंपा गयाissuedsubmit_answerएक बार दर्जanswered
requested ↺अस्वीकार, कोशिशें बाकी — हर अनुरोध पर तीन से ज़्यादा नहींrequested → noneतीन बार अस्वीकार, या अनुरोध खुलने के 15 मिनट बाद; दिन के सवाल खर्च नहीं होते, और तीन अस्वीकार दिन के एक नाकाम अनुरोध के रूप में गिने जाते हैंissued → requestedजवाब से पहले “अगला सवाल” — दर्ज होता है कि सवाल छोड़ा गया, रेटिंग वही रहती हैanswered ↺बाद का कोई भी जवाब — दूसरे टैब से या मॉडल से — पहला नतीजा ही वापस पाता है और कुछ नहीं लिखताanswered → requestedअगला सवाल, नए कार्ड पर; जिस सवाल का जवाब दिया जा चुका, वह अब मौजूदा नहींanswered → issuedअगला सवाल पहले से लिखा हुआ था — next_task उसे तुरंत नए कार्ड पर रख देता है, requested को छोड़करissued → noneसील अब खोली नहीं जा सकती — कुंजी दो बार बदल चुकी है; कुछ दर्ज नहीं होता
03
स्टेट कहाँ रहती है
स्टेट वाला सर्वर जो कुछ डेटाबेस में रखता, वह सब कोई और रखता है: चैट के पास रखे सीलबंद टोकन में, अभिभावक के ब्राउज़र की कुकी में, या अभिभावक की अपनी Drive में। सेवा को रीस्टार्ट करें या उसकी दूसरी कॉपी चलाएँ — कुछ भी नहीं खोता।
खुद MathTrail
कुछ नहीं
न खाते, न सेशन, न रजिस्ट्रेशन, न Google के टोकन। हर अनुरोध अपने साथ वह सब लाता है, जो उसे चाहिए।
चैट का टोकन स्टोर
सीलबंद टोकन, होस्ट के लिए अपारदर्शी
- ऐक्सेस टोकन
- 15 मि॰
- रीफ़्रेश टोकन
- 30 दिन, ≤ 90
इनमें Google के टोकन, सीमाओं के लिए एक अपारदर्शी यूज़र आईडी और साइन-इन वाला देश सील किए हुए हैं।
अभिभावक का ब्राउज़र
दो कुकियाँ, कोई सेशन नहीं
- मंज़ूर किए गए क्लाइंट
- 180 दिन
- साइन-इन की सुरक्षा (CSRF)
- 10 मि॰
इनके खो जाने पर एक और सहमति स्क्रीन आती है, या फिर से साइन इन करना होता है।
अभिभावक की Drive
लंबे समय तक रखी जाने वाली इकलौती चीज़
mathtrail-profile.json- मिटाए जाने तक
प्रोफ़ाइल, रेटिंग और मौजूदा सवाल, जिसका जवाब सीलबंद है। अभिभावक फ़ाइल खोल सकता है, और Drive उसका इतिहास रखती है।
Secret Manager
इंस्टेंस शुरू होते समय एक बार पढ़ा जाता है
- सील करने की कुंजियाँकुंजी बदलने के बाद भी पिछली कुंजी मानी जाती है
- 90 दिन
- Google का क्लाइंट सीक्रेट
- पिन किया हुआ
इंस्टेंस की मेमोरी
सिर्फ़ कैश: रीस्टार्ट पर मिट जाते हैं, और कुछ नहीं टूटता
- अनुरोधों की रफ़्तार के काउंटर
- मिनट
- प्रोफ़ाइल की फ़ाइल कहाँ है
- 10 मि॰
- क्लाइंटों के दस्तावेज़
- 5 मि॰ – 24 घं॰
v1 से जान-बूझकर बाहर
- डेटाबेस
- कतारें
- सेशन स्टोर
- साझा कैश
- तैयार सवालों का बैंक
- LLM API क्लाइंट
- REST और OpenAPI
04
प्रोफ़ाइल की फ़ाइल
एक बच्चा, एक JSON फ़ाइल: किसी सर्वर पर रखे किसी सच का कैश नहीं, बल्कि खुद सच। हर ब्लॉक की एक ऊपरी सीमा है, जो हर बार लिखते समय लागू होती है, इसलिए फ़ाइल कभी बेहिसाब नहीं बढ़ती: आम फ़ाइल लक्ष्य के भीतर रहती है, और अपनी सीमाओं के पास वाली फ़ाइल उससे आगे निकल जाती है। पुराने सवाल फ़िंगरप्रिंट के रूप में रखे जाते हैं, टेक्स्ट के रूप में नहीं।
फ़ाइल का आकार
≈ 61 KB / ≈ 79 KB
| ब्लॉक | इसमें क्या है | कौन लिखता है | आकार | |
|---|---|---|---|---|
| फ़िंगरप्रिंट | दिए जा चुके सवालों के ज़्यादा से ज़्यादा 200 स्केच, लगभग दोहराव की जाँच के लिए — न टेक्स्ट, न विषय, न तारीख | next_tasksubmit_task | 27 KB / 29 KB | |
| रेटिंग का इतिहास | हाल के हर जवाब से पहले θ और विषय का δ कहाँ थे, और जवाबों वाले आखिरी 7 दिनों में से हर दिन की शुरुआत में θ और हर विषय | submit_answer | 14 KB / 15 KB | |
| रेटिंग और विषय | θ और बच्चे ने कहाँ से शुरू किया; हर विषय के लिए: δ, जवाब, जिन जालों में जवाब फँसे, महारत और उसका स्तर | next_tasksubmit_tasksubmit_answer | 8 KB / 14 KB | |
| हाल के जवाब | आखिरी 20 जवाब और छोड़े गए सवाल — और कभी भी उन 5 जवाबों से कम नहीं, जिन्हें नियम पढ़ता है | next_tasksubmit_answer | 4 KB / 5 KB | |
| मौजूदा सवाल, सीलबंद | जवाब, हर गलत विकल्प के पीछे का जाल, हल और सॉल्वर — एक अपारदर्शी स्ट्रिंग | next_tasksubmit_tasksubmit_answer | 4 KB / 8 KB | |
| मौजूदा सवाल, खुला | कार्ड जो दिखाता है: टेक्स्ट, चित्र, पाँच विकल्प, संकेत — और जवाब के बाद, खुद जवाब | next_tasksubmit_tasksubmit_answer | 2 KB / 4 KB | |
| खुला अनुरोध | जब तक सवाल लिखा जा रहा हो: उसकी आईडी, ब्रीफ़, इस्तेमाल हुई कोशिशें और विषय किसने चुना | next_taskprepare_tasksubmit_task | 1.5 KB / 2 KB | |
| सेवा और बच्चा | स्कीमा का संस्करण, एक रैंडम UUID, रिविज़न; छद्म नाम, कक्षा, रुचियाँ, नोट्स; दिन के काउंटर | save_profileedit_profileहर बार लिखने पर | 0.6 KB / 1.5 KB |
पहले से लिखा गया सवाल मौजूदा सवाल के बगल में रहता है और लगभग उतनी ही जगह लेता है। फ़ाइल में क्या नहीं होता: पुराने सवालों के टेक्स्ट, बच्चे के जवाब देने तक खुले रूप में जवाब, अभिभावक का नाम बताने वाली कोई भी चीज़, और पड़ाव — पड़ाव दिखाते समय ही निकाले जाते हैं। Drive में शर्त के साथ लिखने की सुविधा नहीं है, इसलिए सेव करने से पहले फ़ाइल दोबारा पढ़ी जाती है, और अगर वह बदल गई हो, तो लिखना रोक दिया जाता है: दो टैब कभी चुपचाप एक-दूसरे का लिखा नहीं मिटाते।
05
सीलबंद — और कब तक के लिए
एक ही तंत्र दो काम करता है: वह साइन-इन को उन टोकनों में सील करता है जो चैट के पास रहते हैं, और सवाल के जवाब को — मौजूदा सवाल के और पहले से लिखे गए सवाल के — प्रोफ़ाइल में। हर सील में उसका मकसद दर्ज होता है, इसलिए ऐक्सेस टोकन रीफ़्रेश टोकन बनकर नहीं चल सकता, और सीलबंद जवाब किसी और चीज़ के रूप में भी नहीं।
एक टोकन, हिस्सा-दर-हिस्सा
mt1.a.kQ7fWx.5rJ0Yb2mQ8vK1nT4pXc9…
- mt1
- फ़ॉर्मैट का संस्करण
- मकसद
- c कोड · a ऐक्सेस · r रीफ़्रेश · d क्लाइंट · s स्टेट · k सहमति · t सवाल का जवाब
- कुंजी की आईडी
- खुद कुंजी से ली जाती है, इसलिए कुंजी बदलने का पता भी नहीं चलता
- सिफ़रटेक्स्ट
- XChaCha20-Poly1305, एक रैंडम 192-बिट nonce
यह JWT नहीं है: इसे सेवा के सिवा कोई नहीं पढ़ता, और अपारदर्शी स्ट्रिंग से कोई क्लेम लॉग में लीक नहीं हो सकता।
वैधता की अवधि, लघुगणकीय पैमाने पर
- ऑथराइज़ेशन कोड
60 से॰ - जारी साइन-इन
10 मि॰ - ऐक्सेस टोकन
15 मि॰ - रीफ़्रेश टोकन
30 दिन, आगे खिसकती, अधिक से अधिक 90 - सील करने की कुंजी
हर 90 दिन में बदली जाती है - मंज़ूर किए गए क्लाइंट
180 दिन
बिना स्टेट वाला सर्वर किसी कोड पर “इस्तेमाल हो चुका” का निशान नहीं लगा सकता, इसलिए कोड की समय-सीमा छोटी रखी जाती है। कुंजी बदलने के बाद भी पिछली कुंजी मानी जाती है, इसलिए कुंजी बदलने पर न कोई टोकन खोता है, न कोई सीलबंद जवाब।