تصور کنید سیستمی دارید که منتظر دستور شما نمیماند، بلکه خودش تصمیم میگیرد چه چیزی را پژوهش کند، بودجهی تحقیق را مدیریت میکند و تا رسیدن به پاسخ متوقف نمیشود. اگر هنوز از CRMهایی استفاده میکنید که فقط برای ذخیرهی دادههای دستی ساخته شدهاند، باید بدانید که دوران «ورودیهای انسانی» در حال پایان است.
به نقل از مستندات پروژه، trycompai/crm یک CRM عاملمحور (Agentic) و متنباز است که رابطهی سنتی بین نرمافزار و هوش مصنوعی را وارونه کرده است. فلسفه این پروژه این است: «یک عامل پژوهشی بادوام، محصول اصلی است و پایگاهداده صرفاً جایی است که عامل یادداشتهای خود را در آن مینویسد». اکثر CRMهای مدرن در واقع همان پایگاهدادههایی هستند که یک رابط کاربری برای وارد کردن دادهها توسط انسان دارند؛ حتی نسخههای تقویتشده با AI هم فقط یک چتبات ساده به آن رابطه چسباندهاند. در هر دو حالت، فشار اصلی روی دوش انسان است تا حقیقت را پیدا کرده و تایپ کند.
این سیستم اما عامل (Agent) — شبیه به کارمندی که هم دسترسی به ابزار دارد و هم قدرت تصمیمگیری برای پیشبرد پروژه — را بازیگر اصلی قرار داده است. این عامل روی استقرار، زمانبندی و صف کاری مستقل خود اجرا میشود. این یعنی سیستم منتظر یک درخواست (Request) نمیماند. خودش تصمیم میگیرد مرحله بعدی پژوهش چیست، پیگیریهای لازم را رزرو میکند، از بودجه پژوهش هزینه میکند و تنها زمانی که بودجه تمام شود، متوقف میشود. هیچ بخشی از این فرآیند مدل «درخواست-پاسخ» (Request-Response) نیست؛ به این معنا که اگر مرورگر خود را ببندید، عامل همچنان در پسزمینه به کار ادامه میدهد.
این قابلیت به این دلیل ممکن شده که عامل بر بستر eve ساخته شده است؛ چارچوب Vercel برای عاملهای بادوام که اولویت را به سیستم فایل (Filesystem-first) میدهد. در این ساختار، جلسات (Sessions) حتی پس از بازنشر (Redeployment) زنده میمانند و کار دقیقاً از همان نقطهای که متوقف شده بود، از سر گرفته میشود.
مدل هوشمندی مبتنی بر شواهد
این سیستم بر یک قاعدهی سختگیرانه استوار است: هیچگاه دربارهی یک شخص گمانه پرداز نباشد. برای جلوگیری از توهم (Hallucination) — یا همان «توهم قطعیت» که در مدلهای زبانی بزرگ (LLM) رایج است — عامل اجازه ندارد از امتیازات اطمینان (Confidence Scores) برای ارزیابی کار خود استفاده کند. توسعهدهندگان اشاره کردهاند که اگر از یک مدل بخواهید میزان اطمینان خود را درجهبندی کند، این کار را انجام میدهد، اما در جهتی اشتباه میکند که خود را مفیدتر نشان دهد.
به همین دلیل، سیستم به جای پیشبینی، بر یک دفترچه شواهد (Ledger of Evidence) و یک مدل قیمتگذاری برای آن شواهد تکیه میکند:
- شواهد قوی: دادههای تأییدشده و مستند (مانند
crm.signature-blockیاgithub.account-identity) که مستقیماً در رکورد نهایی نوشته میشوند. - شواهد ضعیف: یافتههای تأییدنشده که بهعنوان «پیشنهاد» علامت میخورند تا در نهایت یک انسان آنها را بررسی و تثبیت کند.
این رویکرد از مشکل «دادههای با اطمینان غلط» جلوگیری میکند. یک حقیقت غلط درباره مشتری بسیار بدتر از یک فیلد خالی است، زیرا هیچکس متوجه اشتباه نمیشود. با استفاده از دفترچه شواهد، عامل تضمین میکند که رکورد نهایی بر اساس مشاهده (Observation) است، نه پیشبینی (Prediction). این اهمیت نظارت انسانی بر خروجیهای هوش مصنوعی را یادآور میکند، چرا که برخی تحلیلها نشان میدهند نظارت دقیق انسانی میتواند نرخ شکست در جذب مشتری توسط عاملها را بهطور چشمگیری کاهش دهد.

معماری فنی و پشته تکنولوژی
این پروژه یک monorepo با Turborepo است که روی Bun اجرا شده و توسط Vercel مستقر میشود. یک قانون طلایی و بنیادین در اینجا وجود دارد: هوشمندی هرگز نباید در لایهی API زندگی کند (جزئیات این مورد در docs/api.md آمده است). API ساخته شده با NestJS صرفاً گزارش میدهد که اتفاقی افتاده است — مثلاً یک رشته گفتگو وارد شده (Ingested)، یک شرکت ایجاد شده یا یک شرکتکننده ناشناخته است — و با نوشتن یک ردیف در صف، این خبر را اعلام میکند. سپس عامل آن ردیف را اجاره (Lease) کرده و تصمیم میگیرد معنای این اتفاق چیست. این طراحی از ریسک «لغزش تطبیق هویت» جلوگیری میکند؛ مشکلی که طبق گفته نویسندگان، زمانی رخ داد که یک تطبیقدهنده (Matcher) شروع کرد به متصل کردن هر کارفرمایی در کره زمین به یک شخص!

اجزای کلیدی این پشته عبارتاند از:
- Frontend: استفاده از Next.js App Router با shadcn/ui و nuqs برای مدیریت وضعیت مبتنی بر URL. این امر تضمین میکند که فیلترها، مرتبسازیها و نماهای صفحه در URL ذخیره شوند و هر نما به یک لینک قابل اشتراک تبدیل شود.
- API: استفاده از NestJS با nestjs-trpc برای ارتباطات با ایمنی نوع (Type-safe). انواع Router از روی مسیرهای NestJS تولید میشوند و ایمنی نوع را از ردیف Prisma تا سلول جدول تضمین میکنند.
- Data: پایگاهداده Prisma با Postgres (Neon) و کش مشترک اختیاری Redis (Upstash). همچنین از Vercel Blob برای آینهسازی (Mirror) عکسهای پروفایل استفاده شده تا در صورت حذف شدن منبع اصلی، عکسها باقی بمانند.
- Auth: سیستم Better Auth که دسترسی را منحصراً به کاربران گوگل (از طریق یک لیست سفید در متغیرهای محیطی) محدود میکند. مدل احرازاول ساده است: اگر در لیست هستید، میتوانید همه چیز را ببینید.

مکانیسمهای دقیق عامل
ابزارها و مهارتها
قابلیتهای عامل به سه دستهی ابزار (Tools)، مهارت (Skills) و زمانبندی (Schedules) تقسیم میشوند که همگی بهعنوان «فایل» مدیریت میشوند. ۱۸ ابزار طراحی شدهاند، از جمله:
read_crm_history: استخراج دادهها از گفتگوها و جلسات خودتانsearch_crm: پرسوجو از پایگاهداده داخلیidentify_contact: resolves کردن هویتهای پرسونای مخاطبانresearch_person: پژوهش عمیق در پروفایلهای فردیenrich_company: جمعآوری دادهها در سطح شرکتrecord_fact: ثبت دادههای تأییدشده در CRMschedule_recheck: تعیین یک تاریخ آینده برای اینکه عامل دوباره سراغ یک سرنخ (Lead) برود
علاوه بر این، ۴ «مهارت» متنی (Prose-based) وجود دارد که عامل آنها را بهعنوان کدهای نسخهبندی شده میخواند: evidence.md (شواهد)، identity-matching.md (تطبیق هویت)، data-boundaries.md (مرزهای داده) و writing-a-brief.md (نوشتن گزارش). این رویکرد مستندسازی منطق عامل در فایلهای متنی، مشابه متدهایی است که پروژههایی مانند Grepathy برای جلوگیری از «پوسیدگی کد» و مبهم شدن تصمیمات AI به کار میبرند.
محیط ایزوله (Sandbox) و نردههای ایمنی
برای جلوگیری از خروج غیرمجاز دادهها (Data Exfiltration)، عامل در یک Sandbox با سیاست «بستن تمام خروجیها» (deny-all egress) فعالیت میکند. این محیط هیچ دسترسی شبکهای و هیچ URL مستقیم به پایگاهداده ندارد. نویسندگان تأکید میکنند که یک پوسته (Shell) که دارای اعتبارنامهها (Credentials) و دسترسی خروجی باشد، «شبیه به ابزار جاسوسی» است، اما پوستهای که هیچکدام را نداشته باشد، صرفاً یک پردازشگر متن است. این طراحی تضمین میکند که یک دستور Shell نمیتواند بهطور اتفاقی متن ایمیل یک مشتری را به یک سرور خارجی ارسال کند.

تعاملات خارجی کاملاً خارج از Sandbox مدیریت میشوند:
web_fetchدر زمان اجرای برنامه (App Runtime) اجرا میشود.web_searchدر سمت ارائهدهندهی مدل اجرا میشود.- در محیط تولید از Vercel Sandbox و در محیط محلی از Docker یا microsandbox استفاده میشود.
فعال کردن Sandbox است که مدل را از یک «فراخواننده ابزار» ساده به موجودیتی تبدیل میکند که میتواند پرونده (Dossier) نگه دارد، پروفایل فعلی را با نسخه ماه پیش مقایسه (Diff) کند و در یک رشته متن، با استفاده از grep به دنبال امضای ایمیل بگردد. این Sandbox یک محیط bash را فراهم میکند که دارای ابزارهایی مثل grep و glob و یک دایرکتوری /workspace است.

گردشکار عملیاتی و زمانبندی
عامل زمانبندی خود را از طریق dispatch.ts مدیریت میکند. بهجای استفاده از عبارتهای سنتی Cron، از منطق dueAt در فایل lib/tasks.ts استفاده میکند. ردیفها با استفاده از دستور FOR UPDATE SKIP LOCKED اجاره میشوند؛ این کار اجازه میدهد چندین Dispatcher بدون تداخل و همپوشانی، کارهای مجزا را مدیریت کنند. اگر یک اجرا (Run) متوقف یا کشته شود، ردیف مربوطه پس از انقضای زمان اجاره، آزاد میشود.
وقتی عامل نیاز به ارزیابی مجدد یک مخاطب دارد، تابع schedule_recheck را فراخوانی میکند و باید یک دلیل مشخص ارائه دهد. این دلیل برای نماینده انسانی قابل مشاهده است. فلسفه در اینجا است: عاملی که نتواند توضیح دهد چرا ۱۴ روز دیگر بازمیگردد، در واقع دلیلی برای بازگشت ندارد و فقط یک مقدار پیشفرض را اجرا میکند.
تعامل کاربر و شفافیت
کاربران میتوانند با عامل صحبت کنند و کار آن را در لحظه (Real-time) ببینند. هر مخاطب، شرکت و معامله دارای یک زبانه عامل (Agent tab) است. این بخش، تمام مراحلی که عامل طی میکند، سرنخهایی که عامل تصمیم به حذفشان گرفته (به همراه استدلال) و پاسخهای جایگزین در مواقعی که عامل نمیتواند بین دو شخص مختلف تصمیم بگیرد را نمایش میدهد.
گفتگوها بادوام هستند و با رفرش مرورگر پاک نمیشوند. رکوردها بهجای چسبیدن به ابتدای یک پیام، در یک توکن امضاشده (Signed Token) جابهجا میشوند. برای فعالسازی این ارتباط، کاربران باید متغیر AGENT_BRIDGE_SECRET را در هر دو فرآیند یکسان تنظیم کنند. در غیر این صورت، زبانه گزارش میدهد که پیکربندی نشده است، هرچند عامل همچنان برنامه زمانی خود را اجرا میکند.
یکپارچهسازی و استقرار
تمامی منابع خارجی اختیاری هستند. سیستم بهگونهای طراحی شده که حتی بدون هیچ API Key هم کار کند و فقط بر اساس read_crm_history امضاهای ایمیل را تحلیل کند؛ چرا که امضای ایمیل بهترین مدرک ممکن است زیرا هیچ فروشندهای نمیتواند پاسخی را که از آدرس شخص ارسال شده، بفروشد. در ابتدای هر جلسه، به عامل گفته میشود که این نصب (Install) چه کلیدهایی را در اختیار دارد تا بهجای شکست خوردن در فراخوانیها یکییکی، بهطور مؤثر برنامه ریزی کند. این لیست در هنگام استارت چاپ میشود (مثلاً: [agent] on LinkedIn (RAPIDAPI_KEY)).
با افزودن کلیدها، قابلیتهای بیشتری باز میشوند:
PERPLEXITY_API_KEY: پژوهش وب با ذکر منابع و ارجاعات.RAPIDAPI_KEY: شناسایی هویت از طریق پروفایل لینکدین.CONTEXT_DEV_API_KEY: دریافت لوگو، صنعت و شبکههای اجتماعی شرکتها از طریق دامنه.
جزئیات پیکربندی و راهاندازی
برای استقرار، این سیستم به سه محیط مستقل (اپلیکیشن Next.js، API در NestJS و عامل) و یک پایگاهداده Postgres نیاز دارد. برای جلوگیری از حلقههای تغییر مسیر (Redirect loops)، هر سه باید روی DATABASE_URL و BETTER_AUTH_SECRET یکسان توافق داشته باشند. اگر این دو روی زیردامنههای مختلف از یک دامنه مادر باشند، AUTH_COOKIE_DOMAIN باید روی دامنه مادر تنظیم شود. علاوه بر این، یک Scheduler باید با استفاده از CRON_SECRET به مسیر POST /internal/sync/google اشاره کند تا همگامسازی صندوق ورودی (Mailbox sync) فعال بماند.
راهاندازی برای توسعهدهندگان مستلزم Bun و Docker است. مراحل به شرح زیر است:
۱. کلون کردن مخزن و اجرای bun install.
۲. اجرای docker compose up -d برای راهاندازی Postgres روی پورت ۵۴۳۲.
۳. اجرای bun run db:deploy برای اعمال مهاجرتهای پایگاهداده و bun run db:seed برای ایجاد یک خط لوله دمو باورپذیر.
۴. اجرای bun run dev برای استارت اپلیکیشن روی پورت ۳۰۰۰ و API روی پورت ۳۰۰۱.
چهار متغیر محیطی ضروری عبارتاند از:
BETTER_AUTH_SECRET: تولید شده توسطopenssl rand -base64 32.ALLOWED_SIGN_IN: پشتیبانی از دامنههای خاص (مثلacme.com) یا ایمیلهای مشخص.GOOGLE_CLIENT_IDوGOOGLE_CLIENT_SECRET.
برای تنظیم OAuth گوگل، باید یک اپلیکیشن Web در کنسول گوگل ایجاد کرده و URL بازگشت http://localhost:3001/api/auth/callback/google را اضافه کنید. هر دو APIهای Gmail و Calendar باید فعال باشند. برای کاربران Google Workspace، تنظیم صفحه رضایت (Consent screen) روی حالت Internal، دسترسی را فقط به سازمان محدود میکند.
قوانین کدبیس و مشارکت
پروژه از سه قانون سختگیرانه پیروی میکند که در محل اجرای کد مستند شدهاند:
۱. هوشمندی خارج از API است: API فقط اتفاقات را گزارش میدهد و عامل معنای آنها را تصمیم میگیرد. این کار از «لغزش» در تطبیق هویتها جلوگیری میکند.
۲. تمرکز UI: پکیج packages/ui تنها منبع استایلهاست و هیچ تغییر استایل در محل فراخوانی (Call site) مجاز نیست.
۳. عدم استفاده از سازمانها (No Organizations): سیستم عمداً تکمستأجری (Single-tenant) است. نویسندگان معتقدند ستون organizationId که همیشه یک مقدار ثابت دارد، یک ستون، ایندکس و بررسی دسترسی تکراری است که هیچ ارزشی در هنگام بررسی کد اضافه نمیکند.
برای توسعهدهندگان، دستورات متنوعی در monorepo وجود دارد: bun run check-types برای TSC، bun run lint از طریق Biome، و bun run --filter=api trpc:generate برای بازتولید انواع AppRouter. چون گوگل تنها نقطه ورود است، دستور bun run dev:session برای نوشتن دستی ردیفهای جلسه و چاپ کوکی جهت تستهای محلی (غیر تولیدی) استفاده میشود.
مشارکت در پروژه تشویق میشود، بهویژه از طریق پاراگرافهای نوشته شده توسط انسان، نه درخواستهای Pull Request تولید شده توسط عاملهای AI. مسائل امنیتی بهصورت خصوصی از طریق SECURITY.md مدیریت میشوند و پروژه تحت لایسنس MIT منتشر شده است.
گام بعدی شما
- اگر توسعهدهنده هستید، مخزن GitHub پروژه را کلون کرده و با استفاده از
bun run db:seedساختار دادههای عاملمحور را بررسی کنید. - معماری «جداسازی هوشمندی از API» را در پروژههای خود پیلا کنید تا از لغزش منطقی در مقیاس بالا جلوگیری کنید.
- برای تجربه پژوهش خودگردان، کلیدهای Perplexity و RapidAPI را به سیستم متصل کرده و تفاوت دادههای استنباطی با دادههای مستند را بسنجید.
اما تأمین سختافزاری برای اجرای چنین عاملهای بادوامی در مقیاس بزرگ، چالشهای متفاوتی دارد — به تحلیل ما درباره استراتژیهای کاهش هزینه استنتاج مراجعه کنید.




گفتگو