یک گفتوگو7 از 37
در درسِ «[نگه داشتنِ تاریخچه](keeping-the-history)» فهرستِ messages تمامِ حافظهی گفتوگو بود، و mini در هر نوبت به آن اضافه میکند. اشکالی در این کد (پاسخی که دو بار اضافه شده، نتیجهی ابزاری که گم شده) چیزی را فوراً خراب نمیکند. بعدتر سر درمیآورد، به شکلِ خطای گیجکنندهای از API، یا مدلی که انگار رشتهی کار از دستش در رفته. یک بررسیِ کوچک، پیش از هر درخواست، اشکال را همانجا که پیش میآید پیدا میکند.
تابعِ check_history(messages) را بنویسید. فهرست را همانطور میگیرد که API میگیرد: هر پیام یک دیکشنری با یک role و یک content، که محتوا یا رشته است یا فهرستی از بلوکها. بلوکها یک type دارند: "text"، "thinking"، "tool_use" (با یک id) یا "tool_result" (با یک tool_use_id). دو تای اول را در درسِ «[خواندنِ پاسخ](reading-the-reply)» دیدید. بخشِ بعد از این بخش دربارهی دو تای دیگر است. فعلاً همین کافی است بدانید که وقتی مدل ابزاری میخواهد، پیامِ user بعدی باید برای هر فراخوانی یک نتیجه داشته باشد، با همان شناسه.
پیامها را به ترتیب بررسی کنید و اولین اشکالی را که پیدا میکنید برگردانید:
1. نقشِ ناشناخته. نقشی غیر از "user" یا "assistant": problem at I: unknown role R، که I جای پیام (از ۰) است و R نقشِ آن. (پرامپت سیستمی پیام نیست؛ پارامترِ خودش را دارد.)
2. پیامِ اول باید از user باشد: problem at 0: the first message must be from the user.
3. نقشها به نوبت میآیند. پیامی با همان نقشِ پیامِ قبلی: problem at I: two R messages in a row.
4. در یک پیامِ user، هر نتیجهی ابزار باید جوابِ فراخوانیای باشد که در پیامِ assistant درست پیش از آن آمده: problem at I: result for unknown tool call ID. نتیجهها را به ترتیبی که آمدهاند بررسی کنید.
5. در همان پیامِ user، هر فراخوانی از پیامِ قبل باید نتیجهاش را داشته باشد: problem at I: no result for tool call ID، با بررسیِ فراخوانیها به ترتیب.
بعد از حلقه، تاریخچه باید با یک پیامِ user تمام شود، چون مدل به همان جواب میدهد: problem at I: the last message must be from the user، که I آخرین جاست. اگر هیچ اشکالی نبود، OK برگردانید.
برای نمونه، این تاریخچه (پاسخی که اشتباهی دو بار اضافه شده):
``json
[
{"role": "user", "content": "Hi!"},
{"role": "assistant", "content": "Hello!"},
{"role": "assistant", "content": "Hello!"},
{"role": "user", "content": "Bye"}
]
`
این را میدهد: problem at 2: two assistant messages in a row.
<details>
<summary>یک راهنمایی</summary>
فهرستی از شناسههای فراخوانیِ ابزار در پیامِ assistant قبلی نگه دارید (بعد از هر پیامِ user خالی). در یک پیامِ user، tool_use_id بلوکهای tool_result آن را با این فهرست مقایسه کنید، از هر دو طرف. تابعِ کمکیِ blocks()` محتوای رشتهای را به فهرست تبدیل میکند، پس هیچوقت لازم نیست خودتان رشته بودن را بررسی کنید.
</details>
ورود برای امتحان این تمرین.