# راه‌اندازی سرویس هوش مصنوعی — راهنمای دقیق برای داخل ایران

نسخه: ۱۴۰۵/۰۵/۱۱ — سند مرجع پیکربندی کلید و آدرس سرویس.

---

## ۱. چرا خطای «سرویس هوش مصنوعی پیکربندی نشده است» رخ می‌دهد؟

این پیام فقط و فقط یک معنا دارد: تابع `getKeyProfiles()` در
`src/lib/llm-keys.server.ts` هیچ کلیدی در `process.env` پیدا نکرده است.

نکتهٔ مهم: تابع `orderedProfilesForRequest()` کلیدهای در حال «خنک‌سازی» را هم
به انتهای صف اضافه می‌کند:

```ts
return [...ready, ...cooling];
```

بنابراین **محدودیت سهمیه هرگز باعث این پیام نمی‌شود**. اگر این پیام را دیدید،
مسئله همیشه «کلید خوانده نشده» است، نه «سهمیه تمام شده».

### دو علت رایج

| علت                        | نشانه                                 | راه‌حل                                |
| -------------------------- | ------------------------------------- | ------------------------------------- |
| فایل `.env` وجود ندارد     | خطا در همان اولین بسته (بستهٔ ۱ از N) | `cp .env.example .env` و پر کردن کلید |
| اجرا با `npm` به‌جای `bun` | `.env` هست ولی خوانده نمی‌شود         | با `bun run dev` اجرا کنید            |

`bun` فایل `.env` را خودکار داخل `process.env` می‌ریزد. اگر ناچار به استفاده از
`npm` هستید، متغیرها را دستی در محیط قرار دهید یا از `dotenv-cli` استفاده کنید.

---

## ۲. سه مسیر استفاده از داخل ایران

دامنه‌های `googleapis.com`، `api.openai.com`، `openrouter.ai` و `api.groq.com`
درخواست‌های آی‌پی ایران را رد می‌کنند. سه راه‌حل واقعی وجود دارد:

### مسیر الف — درگاه واسط ایرانی (توصیه‌شده؛ بدون نیاز به تغییر مسیر شبکه)

این سرویس‌ها داخل ایران میزبانی می‌شوند، رابط سازگار با OpenAI دارند، با ریال
شارژ می‌شوند و خودشان به مدل‌های خارجی وصل می‌شوند. فقط دو خط از `.env` عوض
می‌شود.

**آوالای (AvalAI):**

```
LLM_API_KEY=aa-...
LLM_BASE_URL=https://api.avalai.ir/v1
LLM_PROVIDER=avalai
LLM_MODEL_PRO=gemini-2.5-pro
LLM_MODEL_FREE=gemini-2.5-flash
LLM_MODEL_FALLBACK=gemini-2.5-flash
```

**گیلاس (Gilas):**

```
LLM_API_KEY=...
LLM_BASE_URL=https://api.gilas.io/v1
LLM_PROVIDER=gilas
LLM_MODEL_PRO=gpt-4o
LLM_MODEL_FREE=gpt-4o-mini
LLM_MODEL_FALLBACK=gpt-4o-mini
```

**لیارا (Liara AI):** آدرس پایه در پنل کاربری، ذیل همان سرویس هوش مصنوعی که
می‌سازید نمایش داده می‌شود و برای هر حساب متفاوت است. همان آدرس را عیناً در
`LLM_BASE_URL` بگذارید. اگر به `/v1` ختم نمی‌شود، آن را دست‌کاری نکنید؛ کتابخانه
خودش `/chat/completions` را به انتهای آن اضافه می‌کند.

شناسهٔ دقیق مدل‌ها را از فهرست مدل‌های همان درگاه بردارید. نام مدل اشتباه،
خطای ۴۰۴ می‌دهد و در ظاهر شبیه قطعی سرویس دیده می‌شود.

### مسیر ب — واسط اختصاصی روی سرور خارج

اگر کلید مستقیم گوگل یا OpenAI دارید و نمی‌خواهید درگاه واسط تجاری بگیرید، یک
واسط سبک روی یک سرور مجازی خارج از کشور بالا بیاورید (مثلاً Nginx با
`proxy_pass` به `https://generativelanguage.googleapis.com/v1beta/openai/`) و
آدرس همان سرور را در `LLM_BASE_URL` بگذارید. کلید در `.env` سمت شماست و فقط
ترافیک از سرور واسط عبور می‌کند.

```
LLM_API_KEY=<کلید گوگل>
LLM_BASE_URL=https://<دامنهٔ سرور شما>/v1beta/openai
LLM_MODEL_PRO=gemini-2.5-flash
```

مزیت: هزینه فقط اجارهٔ سرور. عیب: نگهداری سرور و ریسک قطعی به عهدهٔ شماست.

### مسیر ج — اجرای کل برنامه روی سرور خارج

چون فراخوانی مدل **سمت سرور** انجام می‌شود (فایل‌های `*.server.ts`) و نه در
مرورگر کاربر، اگر خودِ برنامه روی سروری خارج از ایران اجرا شود، هیچ محدودیتی
برای اتصال به مدل وجود ندارد و کاربر ایرانی فقط با رابط کاربری کار می‌کند.
برای نسخهٔ عرضهٔ عمومی، این پایدارترین گزینه است.

---

## ۳. استفاده از دو کلید هم‌زمان (استخر کلید)

اپ از failover خودکار پشتیبانی می‌کند. کلید دوم را این‌گونه بگذارید:

```
LLM_FALLBACK_API_KEY=...
LLM_FALLBACK_BASE_URL=https://api.gilas.io/v1
LLM_FALLBACK_MODEL_PRO=gpt-4o
LLM_FALLBACK_MODEL_FREE=gpt-4o-mini
```

رفتار سامانه هنگام خطا (`src/lib/llm-keys.server.ts`):

| خطا                      | مدت خنک‌سازی کلید |
| ------------------------ | ----------------- |
| ۴۰۲ (اتمام اعتبار)       | ۶ ساعت            |
| ۴۰۱ / ۴۰۳ (کلید نامعتبر) | ۱۲ ساعت           |
| ۴۲۹ روزانه               | ۳ ساعت            |
| ۴۲۹ نرخ درخواست          | ۱۰ دقیقه          |

تا وقتی کلید اول در خنک‌سازی است، کلید دوم کار را ادامه می‌دهد و پس از پایان
مهلت، خودکار به کلید اول برمی‌گردد.

---

## ۴. تست بدون هیچ کلیدی

```
DEMO_MODE=true
```

خروجی نمونهٔ قطعی با مهر «داده نمونه — فاقد اعتبار حقوقی» تولید می‌شود. فقط
برای راستی‌آزمایی مسیرهای کاری. **برای لایحهٔ واقعی به‌هیچ‌وجه قابل استناد
نیست.** توجه کنید که نبودِ کلید هرگز به‌طور خودکار دادهٔ نمونه تولید نمی‌کند؛
این حالت فقط با همین پرچم صریح فعال می‌شود.

---

## ۵. توصیهٔ عملی برای اولین اجرا

تحلیل کامل، اسناد را به بسته‌های چندتایی می‌شکند و برای هر بسته یک فراخوان
سنگین می‌فرستد، به‌علاوهٔ یک فراخوان «ادغام نهایی». با ده فایل، دست‌کم ۱۱
درخواست پشت سر هم ارسال می‌شود.

روی طرح‌های رایگان که سقفشان ۵ تا ۱۵ درخواست در دقیقه است، این کار به خطای
۴۲۹ می‌خورد. برای اولین تست با **دو یا سه سند کوچک** شروع کنید.

خبر خوب: بسته‌های موفق checkpoint می‌شوند. اگر تحلیل در میانهٔ راه شکست، دکمهٔ
«تلاش مجدد» از همان بستهٔ ناتمام ادامه می‌دهد و کار از صفر تکرار نمی‌شود.

---

## ۶. هشدار امنیتی

فایل `.env` **هرگز** نباید داخل بستهٔ منتشرشده یا مخزن کد قرار بگیرد. در
`.gitignore` پوشش داده شده و از بستهٔ نهایی نیز حذف می‌شود. کلیدهایی که در
نسخه‌های ۱ تا ۴ منتشر شده بودند باید ابطال و جایگزین شوند.
