forked from hesabix/arc
355 lines
25 KiB
Markdown
355 lines
25 KiB
Markdown
# سناریوی حافظهٔ واحد دستیار حسابیکس
|
||
|
||
**تاریخ:** ۱۴۰۵/۰۵/۲۹ (۱۹ اوت ۲۰۲۶)
|
||
**وضعیت:** فاز ۰–۲ پیاده شد (کیوریتور LLM، استور واحد، شیت یکپارچه، تلگرام) — فاز ۳ بازیابی معنایی و فاز ۴ HITL هدف موکول
|
||
**مرجع ممیزی:** [`AI_AGENT_SYSTEM_AUDIT.md`](AI_AGENT_SYSTEM_AUDIT.md) (`MEM-01`، `MEM-02`)
|
||
**رقیب مرجع:** ChatGPT Memory + Custom Instructions، Claude Project instructions، Gemini saved info
|
||
**دامنه:** چت درونبرنامه، صوت، تلگرام؛ ذخیره per `(user_id, business_id)`
|
||
|
||
این سند جایگزین دو مسیر موازی فعلی (دستورات همیشگی + حقایق regex) با **یک سیستم حافظهٔ هوشمند** است. یادگیری به عبارت، کلیدواژه یا regex وابسته نیست. پس از هر پاسخ موفق، یک مدل سبک تصمیم میگیرد چه چیزی ارزش ماندن بین جلسات را دارد.
|
||
|
||
تا وقتی فاز ۳–۴ کامل شود، Recall زمینه/هدف با تازگی و همپوشانی واژه است نه embedding.
|
||
|
||
---
|
||
|
||
## ۱. مسئله به زبان محصول
|
||
|
||
کاربر در جلسهٔ A میگوید نامش علی است، یا «گزارشها را خلاصه و جدولی بده»، یا «پروژهٔ جاری نسیمکالاست». جلسهٔ B باید اینها را بداند **بدون اینکه تاریخچهٔ جلسهٔ A در پرامپت ریخته شود**.
|
||
|
||
امروز:
|
||
|
||
| لایه | هست؟ | چرا برای سطح جهانی کافی نیست |
|
||
|------|------|------------------------------|
|
||
| تاریخچهٔ جلسه | بله | فقط همان `session_id`؛ جلسهٔ جدید صفر است |
|
||
| دستورات همیشگی | بله | فقط اگر کاربر دستی در شیت بنویسد |
|
||
| حقایق یادگرفته | جدول و UI هست | استخراج با regex و هر ۶ پیام؛ «اسم من علی است» جا نمیماند |
|
||
| ابزار `upsert_memory_item` | ثبت شده | از فیلتر ابزار (~۴۸ تا) معمولاً حذف میشود؛ ایجنت حسابداری نباید ذهن حافظه باشد |
|
||
| دانشنامه / بینش / خلاصهٔ جلسه | جدا هستند | نباید با حافظهٔ شخص قاطی شوند |
|
||
|
||
سطح جهانی یعنی سه کار همزمان: **نوشتن هوشمند**، **خواندن مرتبط**، **کنترل شفاف کاربر** — نه لیست عبارتهای جادویی.
|
||
|
||
---
|
||
|
||
## ۲. اصول غیرقابل مذاکره
|
||
|
||
1. **معنا، نه عبارت.** هیچ الگوی زبانی («یادت باشه»، «اسم من» و …) شرط یادگیری نیست. مدل کیوریتور از روی نوبت قضاوت میکند.
|
||
2. **یک محصول حافظه.** کاربر یک «حافظهٔ دستیار» میبیند. دستورات همیشگی و حقایق یادگرفته دو منبع داخلیاند، دو قابلیت جدا نیستند.
|
||
3. **ایجنت حسابداری ≠ کیوریتور حافظه.** حلقهٔ چت ابزار دامنه را میزند و به کاربر جواب میدهد. بعد از اتمام نوبت، یک عملیات سبک جدا (`memory_curate`) حافظه را بهروز میکند. یادگیری را به tool-calling داخل حلقهٔ ۱۰۰ millابزاری نسپاریم.
|
||
4. **پایدار در برابر گذرا.** حافظه برای هویت، ترجیح، قرارداد کاری و زمینهٔ پایدار است. عدد فاکتور امروز، ماندهٔ لحظهای و خروجی tool در حافظه نمیماند؛ آنها ابزار و بینشاند.
|
||
5. **کاربر صاحب حافظه است.** هر آیتم قابل دیدن، ویرایش، حذف و «دیگر یاد نگیر» است. کیوریتور حق بازنویسی دستورات دستنویس کاربر را ندارد مگر خود کاربر در گفتگو صریحاً سیاست را عوض کند.
|
||
6. **محدودهٔ tenant.** کلید حافظه `(user_id, business_id)` است. بین کسبوکارها نشت نمیکند.
|
||
7. **کمحرفی در چت.** پاسخ کاربر با «یادداشت شد» شلوغ نمیشود مگر کاربر صریحاً خواسته باشد چیزی را به خاطر بسپارد. یادگیری پیشفرض بیصداست؛ شفافیت در شیت حافظه و رویداد اختیاری UI است.
|
||
8. **هزینهٔ کنترلشده.** کیوریتور مدل light است (مثل عنوان جلسه و خلاصهٔ تاریخچه)، بدون ابزار، خروجی ساختیافته، ورودی کوتاه.
|
||
|
||
---
|
||
|
||
## ۳. مدل مفهومی — یک حافظه، چند لایهٔ معنایی
|
||
|
||
کاربر یک صفحه میبیند: **آنچه دستیار دربارهٔ شما و این کسبوکار میداند.**
|
||
|
||
درون سیستم، هر رکورد یک **آیتم حافظه** با کلید پایدار است (نه slug متن آزاد).
|
||
|
||
| `kind` | چه کسی مینویسد | اولویت در پرامپت | مثال |
|
||
|--------|------------------|------------------|------|
|
||
| `instruction` | فقط کاربر (شیت یا گفتگوی صریح «از این به بعد همیشه…») | بالاترین؛ الزامآور | «مبالغ را تومان بگو؛ لحن رسمی» |
|
||
| `identity` | کیوریتور یا بذر پروفایل حساب | همیشه ارسال | نام خطاب، نقش در کسبوکار |
|
||
| `preference` | کیوریتور | همیشه اگر فعال | سبک گزارش، زبان، سطح جزئیات |
|
||
| `context` | کیوریتور | بازیابی مرتبط | نام پروژه/برند داخلی، اصطلاح |
|
||
| `goal` | کیوریتور؛ هدف عددی بهتر با تأیید | مرتبط با سوال مالی | هدف فروش ماهانه |
|
||
| `constraint` | کیوریتور یا کاربر | همیشه اگر فعال | «این الگو را تکرار نکن» (از فیدبک منفی) |
|
||
|
||
`ai_business_memories.content` در مهاجرت همان مجموعهٔ `kind=instruction` است.
|
||
`ai_memory_items` بقیهٔ kindها را نگه میدارد. API و UI یک payload واحد برمیگردانند.
|
||
|
||
### ۳.۱ آنچه حافظه نیست
|
||
|
||
| منبع | نقش | داخل حافظه؟ |
|
||
|------|-----|-------------|
|
||
| پیامهای جلسه | کارِ کوتاهمدت | خیر — مگر کیوریتور عصارهٔ پایدار بکشد |
|
||
| خلاصهٔ تاریخچهٔ همان جلسه | بودجهٔ توکن | خیر |
|
||
| بینش KPI (`ai_insight_service`) | دادهٔ لحظهای کسبوکار | خیر |
|
||
| دانشنامه / RAG | اسناد | خیر |
|
||
| نتیجهٔ tool | حقیقت دیتابیس همین حالا | خیر |
|
||
|
||
قانون کیوریتور: اگر با یک tool در نوبت بعد قابل بازیابی است و فردا عوض میشود، حافظه نیست.
|
||
|
||
### ۳.۲ بذر هویت از پروفایل
|
||
|
||
اگر کاربر در حسابیکس `first_name`/`last_name` دارد و هنوز `identity.preferred_name` خالی است، یک آیتم بذر با `source=profile` ساخته میشود. اگر در گفتگو نام دیگری برای خطاب بگوید، کیوریتور همان کلید را بهروز میکند (`source=curator`)؛ پروفایل حساب عوض نمیشود.
|
||
|
||
---
|
||
|
||
## ۴. معماری هدف
|
||
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ Memory Store (واحد) │
|
||
│ instruction + items + keys پایدار │
|
||
└──────────────┬──────────────────────┘
|
||
│
|
||
┌────────────────────┼────────────────────┐
|
||
▼ ▼ ▼
|
||
Recall Compiler Curator (light LLM) User UI / API
|
||
قبل از هر نوبت چت بعد از هر پاسخ موفق یک شیت واحد
|
||
انتخاب مرتبط JSON patch مشاهده/ویرایش/حذف
|
||
```
|
||
|
||
دو عملیات هوش مصنوعی جدا:
|
||
|
||
| عملیات | زمان | مدل | ابزار | خروجی |
|
||
|--------|------|-----|-------|--------|
|
||
| `Recall` | ساخت system prompt | بدون LLM در فاز ۱؛ فاز ۲ embedding/رتبه | — | بلوک حافظه برای `semi_static` |
|
||
| `Curate` | پس از persist پاسخ | `AI_OPERATION_MEMORY_CURATE` ∈ light | هیچ | patch: upsert / update / delete / noop |
|
||
|
||
حلقهٔ چت اصلی **تغییر نمیکند** جز اینکه بعد از commit پاسخ، curator زمانبندی شود و قبل از نوبت بعد recall از استور واحد بخواند.
|
||
|
||
---
|
||
|
||
## ۵. سناریوی نوبت — از پیام کاربر تا جلسهٔ بعد
|
||
|
||
### ۵.۱ قبل از فراخوانی مدل چت (Recall)
|
||
|
||
1. استور حافظه برای `(user, business)` خوانده میشود.
|
||
2. **همیشه** در پرامپت میآیند (سقف کاراکتر جدا):
|
||
- همهٔ `instruction`
|
||
- `identity` فعال
|
||
- `preference` و `constraint` فعال
|
||
3. **انتخابی** (سقف جدا، مثلاً ۱۲ آیتم):
|
||
- `context` و `goal` مرتبط با سوال جاری
|
||
- فاز ۱: تازگی + سقف؛ فاز ۲: شباهت معنایی با سوال
|
||
4. خروجی همان لایهٔ `semi_static.memory` است تا prompt cache نشکند مگر حافظه واقعاً عوض شده باشد.
|
||
5. به مدل چت گفته میشود: این بلوک زمینهٔ پایدار است؛ عدد لحظهای را از tool بگیر؛ خودت حافظه را در این نوبت ننویس.
|
||
|
||
### ۵.۲ حین پاسخ (ایجنت)
|
||
|
||
ایجنت مثل امروز کار میکند. ابزارهای حافظه از حلقهٔ پیشفرض **حذف میشوند** تا با کیوریتور رقابت نکنند.
|
||
|
||
تنها استثنا: اگر کاربر در همین پیام بخواهد حافظه را مدیریت کند («چی دربارهٔ من میدانی؟»، «این را از حافظه پاک کن»، «از این به بعد همیشه جدول بده»)، intent معنایی — نه لیست کلمه — ابزارهای حافظه را به `forced_names` اضافه میکند. تشخیص این intent با **خود مدل چت + یک دستهٔ ابزار `memory` در allowlist وقتی سوال از جنس حافظه است** انجام میشود، یا با خروجی ساختیافتهٔ کیوریتور در نوبت بعد. برای پاسخ فوری «چی میدانی؟» دستهٔ memory باید بتواند در همان نوبت در ابزارها باشد.
|
||
|
||
قاعدهٔ عملی:
|
||
|
||
- سوال کاری (فاکتور، موجودی، گزارش) → ابزار حافظه در حلقه نیست؛ curator بعد از پاسخ مینویسد.
|
||
- سوال دربارهٔ خود حافظه → `get_user_memory` / حذف / بهروزرسانی instruction در همان نوبت مجاز است.
|
||
|
||
### ۵.۳ بعد از پاسخ موفق (Curate) — هستهٔ هوشمندی
|
||
|
||
وقتی پاسخ دستیار persist شد (استریم یا غیر استریم، متن یا صوت، در صورت امکان تلگرام):
|
||
|
||
1. Job پسزمینه با queue معتبر (نه `asyncio.create_task` شکننده).
|
||
2. Skip فقط ساختاری، نه زبانی:
|
||
- پاسخ خالی / خطا / لغو
|
||
- نوبت فقط تأیید نوشتن بدون محتوای جدید کاربر
|
||
- سهمیهٔ روزانهٔ light تمام شده
|
||
3. ورودی کیوریتور (کوتاه):
|
||
- ۱ تا ۲ نوبت اخیر (متن کاربر + متن نهایی دستیار؛ بدون JSON ابزار)
|
||
- فهرست فشردهٔ حافظهٔ موجود: `key`, `kind`, `content` تا ۱۲۰ کاراکتر
|
||
- سیاست «چه چیزی حافظه است / نیست» از prompt سیِد `aux.memory_curate`
|
||
4. مدل light با JSON schema، `max_tokens` پایین، temperature پایین، بدون tool.
|
||
5. اعتبارسنجی قطعی روی خروجی (اینجا دیگر مدل نیست):
|
||
- kind مجاز، طول محتوا، کلید پایدار با namespace
|
||
- ممنوعیت راز (توکن، رمز، کلید API) با فیلتر قطعی روی محتوا نه روی گفتگوی کاربر
|
||
- `instruction` فقط اگر `actor=user_explicit`
|
||
- عدم ذخیرهٔ عدد تراکنشی / شناسهٔ سند بهعنوان حقیقت پایدار
|
||
6. اعمال patch: upsert با کلید پایدار (مثلاً `identity.preferred_name` نه slug متن).
|
||
7. متریک: `memory_curate_noop` / `applied` / `rejected` / `failed`.
|
||
8. رویداد اختیاری SSE یا فیلد در پاسخ بعدی: `memory_updates[]` برای UI («به خاطر سپرده شد: نام خطاب علی») — پیشفرض غیرمزاحم؛ در شیت مشخص.
|
||
|
||
کیوریتور **منتظر نوبت ششم نمیماند.** هر پاسخ موفق یک شانس یادگیری است. اگر چیزی برای ماندن نباشد، JSON خالی/`noop` است و استور دست نمیخورد.
|
||
|
||
### ۵.۴ جلسهٔ بعد
|
||
|
||
Recall همان استور را میخواند. نام، ترجیح و دستورات بدون تاریخچهٔ جلسهٔ قبل در پرامپت هستند.
|
||
|
||
---
|
||
|
||
## ۶. قرارداد کیوریتور (خروجی ساختیافته)
|
||
|
||
پرامپت کیوریتور در `ai_default_prompts` با کلید `aux.memory_curate` سیِد میشود تا ادمین بتواند سیاست را عوض کند، نه اینکه regex در کد سخت شود.
|
||
|
||
خروجی نمونه:
|
||
|
||
```json
|
||
{
|
||
"ops": [
|
||
{
|
||
"action": "upsert",
|
||
"key": "identity.preferred_name",
|
||
"kind": "identity",
|
||
"content": "کاربر ترجیح میدهد علی خطاب شود.",
|
||
"confidence": 0.86,
|
||
"user_explicit": false
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
`action`: `upsert` | `update` | `delete` | `noop`
|
||
|
||
قضاوت معنایی داخل پرامپت کیوریتور (خلاصهٔ سیاست، نه فهرست جمله):
|
||
|
||
- ارزش ماندن بین جلسات دارد اگر فردا بدون این جمله دستیار اشتباه خطاب کند یا سبک/قرارداد را از دست بدهد.
|
||
- ارزش ماندن ندارد اگر فقط برای همین سوال است، از دیتابیس با tool میآید، یا فردا کهنه میشود.
|
||
- اگر با آیتم موجود در تضاد است: بهروزرسانی همان کلید، نه ردیف جدید.
|
||
- اگر کاربر خواست فراموش شود: `delete` روی همان کلید.
|
||
- دستور همیشگی جدید فقط وقتی کاربر سیاست پایدار اعلام کرده، نه وقتی یک بار «این گزارش را جدولی بده».
|
||
|
||
کلیدهای پایدار پیشنهادی (قابل گسترش، نه بسته):
|
||
|
||
- `identity.preferred_name`
|
||
- `identity.role_in_business`
|
||
- `preference.report_style`
|
||
- `preference.amount_unit`
|
||
- `preference.language`
|
||
- `context.current_project`
|
||
- `context.internal_term.<slug>`
|
||
- `goal.sales_monthly`
|
||
- `constraint.avoid.<slug>`
|
||
- `instruction` → فقط از UI یا `user_explicit`
|
||
|
||
---
|
||
|
||
## ۷. ادغام محصولی دستورات و حقایق
|
||
|
||
وضعیت امروز دو سیستم موازی است. هدف یک سناریو است:
|
||
|
||
| سطح | قبل | بعد |
|
||
|-----|-----|-----|
|
||
| کاربر | دو بلوک جدا در شیت | یک حافظه: «سیاستهای من» + «آنچه یاد گرفتهام» بهعنوان بخش یک صفحه |
|
||
| API | `GET /memory` با `instructions` و `items` | همان endpoint، مدل واحد: `entries[]` با `kind`؛ فیلدهای قدیمی تا یک نسخه سازگار |
|
||
| ابزار مدل | ۵ function جدا + توضیح متناقض | ۳ عمل: `read_memory`, `upsert_memory_entry`, `delete_memory_entry` — فقط وقتی سوال از جنس حافظه است |
|
||
| پرامپت چت | دو متن چسبیده | یک بلوک compiled: سیاستها، سپس هویت، سپس ترجیح، سپس زمینهٔ بازیابیشده |
|
||
| یادگیری | regex + tool غیرقابلاتکا | فقط curator (+ بذر پروفایل) |
|
||
| فیدبک thumbs-down | آیتم `hint` خام | همان استور با `kind=constraint` از مسیر curator یا فیدبک، با سقف روزانه در Redis/DB |
|
||
|
||
`ai_memory_structured.py` (هدف فروش، واحد پول، …) دیگر JSON جدا روی `AIBusinessMemory` نیست؛ معادل کلیدهای پایدار است. فیلد `structured` در upsert حافظهٔ متنی deprecate میماند.
|
||
|
||
متن آزاد ۴۰۰۰ کاراکتری فقط برای **سیاستهای کاربر** میماند. کیوریتور آن را با گلولههای پراکنده پر نمیکند.
|
||
|
||
---
|
||
|
||
## ۸. تجربهٔ کاربر
|
||
|
||
شیت واحد «حافظهٔ دستیار»:
|
||
|
||
1. توضیح یک خط: دستیار بین گفتوگوها زمینهٔ پایدار را نگه میدارد؛ اعداد لحظهای از دادهٔ کسبوکار خوانده میشوند.
|
||
2. بخش سیاستها (instruction) — ویرایش آزاد، ذخیره دستی.
|
||
3. بخش یادگرفتهها — گروهبندی بر اساس kind، منبع (`profile` / `curator` / `user` / `feedback`)، ویرایش و حذف هر آیتم.
|
||
4. «پاک کردن همه» با تأیید.
|
||
5. اختیاری فاز ۲: سوییچ «یادگیری خودکار» per کاربر.
|
||
|
||
در چت:
|
||
|
||
- یادگیری عادی: بدون جملهٔ اضافه در پاسخ.
|
||
- اگر کاربر صریح خواست به خاطر بسپارد: یک جملهٔ کوتاه تأیید کافی است.
|
||
- منوی پیام: «این را به حافظه اضافه کن» / «این را فراموش کن» — بدون نیاز به عبارت خاص در متن.
|
||
|
||
---
|
||
|
||
## ۹. هزینه، سهمیه، پایداری job
|
||
|
||
- `AI_OPERATION_MEMORY_CURATE` عضو `LIGHT_AI_OPERATIONS`؛ مدل `light_model` پلن (همان مسیر عنوان جلسه).
|
||
- شارژ usage مثل `title` / `history_summary`؛ شکست curator پاسخ کاربر را خراب نمیکند.
|
||
- سقف روزانه جدا (`MAX_LLM_MEMORY_CURATE_PER_USER_DAY`)، در Redis/DB نه dict درونپرداز.
|
||
- ورودی حداکثر حدود ۲–۳k توکن؛ خروجی چند صد توکن.
|
||
- زمانبندی: همان الگوی title generation اما با worker/queue که بعد از برگشت از handler زنده بماند (رفع `MEM-02`).
|
||
- اگر light در دسترس نبود: آن نوبت skip؛ **fallback regex نداریم.** بذر پروفایل همچنان بدون LLM اعمال میشود.
|
||
|
||
---
|
||
|
||
## ۱۰. کانالها و مرزها
|
||
|
||
| کانال | Recall | Curate |
|
||
|-------|--------|--------|
|
||
| چت وب/اپ | بله | بله، بعد از persist |
|
||
| صوت روی همان session | بله | بله، روی متن نهایی |
|
||
| تلگرام | باید به همان استور وصل شود | بعد از پاسخ تلگرام، همان job |
|
||
| ایجنت ورکفلو / تیکت پشتیبانی | فقط اگر همان کاربر+کسبوکار باشد | خیر مگر کانال چت باشد |
|
||
|
||
اپراتور پشتیبانی حافظهٔ tenant کاربر نهایی را با حافظهٔ خودش قاطی نمیکند.
|
||
|
||
---
|
||
|
||
## ۱۱. تست و معیار پذیرش (سطح جهانی)
|
||
|
||
بدون مدل زنده (اجباری):
|
||
|
||
- JSON کیوریتور نامعتبر اعمال نمیشود.
|
||
- `instruction` بدون `user_explicit` نوشته نمیشود.
|
||
- کلید پایدار بهجای ردیف تکراری بهروز میشود.
|
||
- راز و شناسهٔ سند در validator رد میشود.
|
||
- Recall همیشه instruction+identity را میگذارد حتی اگر context خالی باشد.
|
||
- جلسهٔ جدید بدون تاریخچهٔ قدیم، آیتم ذخیرهشده را در بلوک پرامپت دارد (تست کامپایلر).
|
||
- ابزار حافظه در سوال «گزارش فروش» در allowlist نیست؛ در سوال «چی دربارهٔ من میدانی؟» هست.
|
||
|
||
با فیکسچر مدل (طلایی):
|
||
|
||
| نوبت | انتظار |
|
||
|------|--------|
|
||
| «اسم من را علی صدا کن» سپس جلسهٔ جدید «سلام» | `identity.preferred_name`؛ پرامپت جلسهٔ بعد شامل علی |
|
||
| «این ماه فروش چقدر بود؟» | noop حافظه؛ عدد در استور نیست |
|
||
| «از این به بعد گزارشها را جدولی بده» | `preference.report_style` یا instruction اگر سیاست کلی باشد |
|
||
| «اسم پروژهمان نسیمکالاست» سپس سوال نامرتبط و بعد «وضعیت پروژه چیست؟» | `context.current_project` بازیابی میشود |
|
||
| «دیگر اسمم را به خاطر نیاور» | delete کلید هویت |
|
||
| thumbs-down با توضیح سبک | `constraint` بدون آلودهکردن instruction |
|
||
|
||
پذیرش محصول:
|
||
|
||
- کاربر در شیت یک فهرست واحد میبیند.
|
||
- پس از معرفی نام در جلسهٔ اول، جلسهٔ دوم بدون تکرار نام، خطاب درست است.
|
||
- هیچ وابستگی به وجود واژهٔ «یادت باشه» در تست طلایی نیست.
|
||
|
||
---
|
||
|
||
## ۱۲. فاز اجرا
|
||
|
||
| فاز | محتوا | خروج |
|
||
|-----|--------|------|
|
||
| **۰ — قرارداد** | مدل `entries`، کلید پایدار، compiler پرامپت واحد، API سازگار عقبرو، حذف regex از مسیر اصلی | استور واحد؛ رفتار یادگیری هنوز کامل نیست |
|
||
| **۱ — Curator** | `aux.memory_curate`، operation light، job بعد از هر پاسخ، validator، متریک، بذر پروفایل | سناریوی نام و ترجیح بدون عبارت جادویی |
|
||
| **۲ — محصول واحد** | شیت یکپارچه، رویداد «به خاطر سپرده شد»، ابزارهای سهتایی فقط برای intent حافظه، تلگرام | UX سطح ChatGPT |
|
||
| **۳ — Recall هوشمند** | embedding یا رتبه برای context/goal وقتی تعداد آیتم زیاد است | پرامپت شلوغ نمیشود |
|
||
| **۴ — HITL هدف** | `goal` حساس با پیشنمایش تأیید؛ سوییچ یادگیری خودکار | ممیزی MEM-01/۲ بسته شود |
|
||
|
||
فاز ۰–۱ باید با هم به production بروند؛ در غیر این صورت UI واحد با یادگیری کر میماند یا کیوریتور روی دو مدل ذهنی قدیمی مینویسد.
|
||
|
||
---
|
||
|
||
## ۱۳. نقشهٔ فایلها (پیادهسازی بعدی)
|
||
|
||
| کار | فایلهای اصلی |
|
||
|-----|----------------|
|
||
| استور و compiler | `ai_memory_service.py`, `ai_memory_item_service.py` |
|
||
| کیوریتور | سرویس جدید `ai_memory_curator.py`؛ جایگزینی منطق regex در `extract_learned_candidates` |
|
||
| job | `ai_memory_hooks.py` — queue بهجای create_task شکننده |
|
||
| routing | `ai_constants.py`, `ai_model_service.py` |
|
||
| پرامپت | `ai_default_prompts.py` → `aux.memory_curate` |
|
||
| ابزار | `ai_function_extensions_memory.py`, `ai_tool_intent.py` (دستهٔ memory) |
|
||
| چت | `adapters/api/v1/ai/chat.py` بعد از persist |
|
||
| تزریق پرامپت | `ai_service.py` / `format_memory_for_prompt` |
|
||
| UI | `ai_chat_memory_sheet.dart` |
|
||
| تست | `test_ai_memory_service.py` + تست curator/compiler جدید |
|
||
|
||
Regex فعلی فقط تا شروع فاز ۱ بهعنوان کد مرده/تست سازگاری میماند؛ مسیر production آن را صدا نمیزند.
|
||
|
||
---
|
||
|
||
## ۱۴. ضدالگوها (عمداً انجام نمیدهیم)
|
||
|
||
- ریختن N جلسهٔ قبلی در context بهجای حافظه.
|
||
- وادار کردن ایجنت حسابداری به `upsert_memory_item` در هر نوبت فروش.
|
||
- فهرست جملات فارسی برای «تشخیص نام».
|
||
- یکی کردن دانشنامه با حافظهٔ شخص.
|
||
- ذخیرهٔ KPI بینش داخل memory items.
|
||
- پر کردن دستورات همیشگی توسط مدل.
|
||
- Fallback regex وقتی مدل light قطع است (سکوت بهتر از حقیقت غلط است).
|
||
- دو UI یا دو API برای «دستور» و «حقیقت» بهعنوان محصول جدا.
|
||
|
||
---
|
||
|
||
## ۱۵. تصمیمهای قفلشده
|
||
|
||
1. یادگیری = کیوریتور بعد از پاسخ، نه regex و نه ابزار داخل حلقهٔ پیشفرض.
|
||
2. محصول = یک حافظه با چند `kind`؛ دستورات همیشگی `kind=instruction` با اولویت الزامآور.
|
||
3. Recall فاز ۱ قاعدهای (اولویت kind + سقف)؛ فاز ۳ معنایی.
|
||
4. کلید پایدار اجباری است تا ادغام و فراموشی ممکن باشد.
|
||
5. این سند مرجع اجراست؛ MEM-01 و MEM-02 پس از فاز ۲–۴ در ممیزی `انجامشده` میشوند.
|