ビジネス・スタートアップ
CRM: オープンソース、エージェントファーストCRM
CRM: An open-source, agentic-first CRM (github.com)
要約
このCRMは、従来のデータベース中心のアプローチとは異なり、「エージェント」を最優先する設計が特徴です。エージェントは自律的にタスクをこなし、情報を収集・整理し、人間が介入する必要のある部分のみを提示します。これにより、人間はより重要な業務に集中でき、データの一貫性と信頼性を高めることを目指しています。
全文翻訳
CRM
オープンソース、エージェントファーストCRM。
耐久性のあるリサーチエージェントが製品です。データベースは単に書き留める場所です。
エージェント · スタック · クイックスタート · 設定 · デプロイ · 貢献
これは何ですか
ほとんどのCRMは、その前にフォームがあるデータベースです。AI搭載のCRMは、そのフォームの横にチャットボックスを追加します。どちらも、真実を見つけ出し、それを書き留めるという実際の作業を、他にやるべきことがある人間に任せています。これは逆の順序で構築されています。エージェントはCRMの機能ではなく、CRMはエージェントがメモを保持する場所です。独自のデプロイメントで、独自のスケジュールで、独自のワークキューに対して実行されます。次に何を見るかを決定し、独自のフォローアップを予約し、リサーチ予算を使い、予算が尽きたら停止します。要求-応答の性質のものは何もありません。ブラウザを閉じても継続します。
APIには意図的に知性は全くありません。
NestJSは、スレッドが取り込まれた、会社が作成された、参加者が不明である — といったイベントを、キューに行を書き込むことによって報告します。エージェントはその行をリースし、その意味を決定します。エンリッチメントAPIを呼び出すNestサービスはバグとして扱われ、docs/api.mdにはそれがルールとなった障害が説明されています。エージェント自体が決して破らないルール:人のことについて推測しない。どのツールも信頼度スコアを受け入れません。なぜなら、自身の確実性を評価するように求められたモデルは、有用に見える方向に間違った評価をするからです。ツールは、観察したこと(crm.signature-block、github.account-identity)を報告し、レジャーが証拠を価格付けします。強力な証拠は記録に書き込まれます。弱い証拠は、人間が解決する提案になります。顧客に関する自信を持って間違った事実は、空白のフィールドよりも悪いのです。なぜなら、誰もそれが間違っているとわからないからです。
設計上、シングルテナントで内部的です。
サインインはGoogleで、許可リストは1つの環境変数であり、アクセスできる全員がすべてを見ることができます。それが認証モデル全体です — 実際の顧客データを指し示す前にSECURITY.mdを参照してください。
スクリーンショット
セールス — フィルター、ソート、ページングはURLにあり、ビューはリンクです。
連絡先 — これらのほとんどはメールボックスの同期によって作成されたもので、手入力されたものではありません。
会社 — ロゴ、業界、所在地は自動的に到着します。
概要 — あなた自身またはチーム全体の概要は、URLで切り替えられます。
エージェント
apps/agentは独自のデプロイメントで、eve — Vercelのファイルシステムファーストの耐久性のあるエージェント用フレームワーク — 上に構築されています。ツールはファイル、スキルはマークダウンファイル、スケジュールはファイル、ランタイムが耐久性のある部分を処理します:再デプロイを生き延びるセッション、停止した場所から再開する作業。
18個の作成済みツール:read_crm_history、search_crm、identify_contact、research_person、enrich_company、record_fact、schedule_recheck…
4つのスキル:evidence.md、identity-matching.md、data-boundaries.md、writing-a-brief.md — エージェントが読み込むプロセ、コードのようにバージョン管理されるもの。
1つのスケジュール:dispatch.ts、これは何も決定しません。Dueのものをリースし、行ごとにセッションを開始します。
サンドボックス
bash、grep、glob、および/workspace、すべて拒否するEgress付き
それは自己実行します。lib/tasks.tsはワークキューです:claimDueはFOR UPDATE SKIP LOCKEDでリースされた行を取得するため、2つのディスパッチャーは分離された作業を行い、終了した実行はリースが期限切れになると行を解放します。「N分ごとに、最も古い10件の連絡先」のようなものは、cron式ではなく、タスクのdueAtに配置する必要があります。エージェントが誰かに再度見たい場合、schedule_recheckを呼び出して理由を伝え — その理由は担当者に表示されます。なぜなら、14日後に戻ってくる理由を言えないエージェントは理由を持たず、デフォルトを持っているからです。
すべての外部ソースはオプションであり、それらがなくても実行できるように設計されています。APIキーが全くなくても動作します:read_crm_historyは、あなた自身のスレッド、会議、署名ブロックを読み取ります。これは無料であり、最高の証拠です — データベンダーは、相手のアドレスからの返信をあなたに販売することはできません。各キーは、さらに1つの場所を開きます。セッションの開始時に、このインストールがどのキーを持っているかが伝えられるため、失敗した呼び出しごとにギャップを発見するのではなく、実際に持っているものに基づいて計画を立て、起動時にリストを表示します:[agent] on LinkedIn (RAPIDAPI_KEY) [agent] off Web research (PERPLEXITY_API_KEY) [agent] off Company brand data (CONTEXT_DEV_API_KEY)
サンドボックスにはネットワークもデータベースもありません。それをオンにすることがモデルにシェルを与えること — ツール呼び出し側と、記録を保持し、今月のプロファイルを先月と比較し、スレッドをgrepして署名ブロックを取得できるものの違いです。deny-all egressは費用がかかりません。なぜなら、web_fetchはアプリランタイムで実行され、web_searchはモデルプロバイダーで実行されるからです。除去されるのは、顧客のメール本文がシェルコマンドを通じて流出する唯一の経路です。そのルールのもう半分は不在です:サンドボックスには決してDATABASE_URLが与えられません。認証情報とEgressを持つシェルは、内部ツールであっても流出の形状をしていますが、それらを持たないシェルはテキストプロセッサです。それに話しかけ、それが働くのを見ることができます。
すべての連絡先、会社、セールスにはAgentタブがあります — それが取るステップ、それが破棄するリードとその理由、そして2人の間で決定できない場合にその場で回答された質問です。会話は耐久性があり、リロードを生き延びます。レコードはメッセージの前にボルトで固定されるのではなく、署名されたトークンで移動します。AGENT_BRIDGE_SECRETを両方のプロセスで同じ値に設定してオンにします。それがない場合、タブは設定されていないと報告し、エージェントは独自のスケジュールで実行を続行します。docs/agent.mdは完全な書き込みです。
スタック
Bun上のTurborepoモノレポ、Vercelにデプロイ。
エージェント:eve — 耐久性のあるセッション、ツール、スキル、スケジュール、サンドボックス
モデル:Vercel AI Gateway — プロバイダーSDKなし、Vercel上のOIDCはキー管理なし
サンドボックス:Vercel Sandbox(本番環境)、Dockerまたはローカルのmicrosandbox
フロントエンド:Next.js App Router · shadcn/ui · URL状態用のnuqs
API:NestJS with nestjs-trpc — HTTP、認証、tRPC、Google同期
データ:Prisma · Postgres (Neon) · オプションRedis (Upstash)
認証:Better Auth、Googleのみ、1つの許可リスト
ファイル:Vercel Blob — プロファイル画像をミラーリングし、ソースが消えても生き残るようにする
ツール:Biome · すべてのTypeScript
アプリはtRPC経由でAPIと通信し、ルーターの型はNestJSルーターから生成されるため、フロントエンドはPrisma行からテーブルセルまで型安全です。リストの状態(フィルター、ソート、ページ)はURLにあり、アドレスバーをコピーするとビューが再現されます。
レイアウト
Path
apps/agent:リサーチエージェント — ツール、スキル、スケジュール、サンドボックス
apps/app:Next.jsフロントエンド · :3000
apps/api:NestJS API — HTTP、認証、tRPC、Google同期 · :3001
packages/db:Prismaスキーマ、マイグレーション、共有Postgresクライアント
packages/auth:Better Auth設定とサインイン許可リスト
packages/ui:shadcn/uiコンポーネント、Tailwindテーマ
packages/env:ルート.envを見つけてロードする
コードベースが従う3つのルール
スタイルガイドではなく、作業が行われる場所で記述されています:
知性はAPIに決して存在しない(docs/api.md)。Nestは何かが起こったことを報告します。エージェントがその意味を決定します。アイデンティティマッチャーの2つのコピーは、一方が地球上のすべての雇用者を一致させるまで漂流しました。
packages/uiはUIの唯一の情報源です(docs/design.md)。呼び出しサイトでのスタイルのオーバーライドはありません。
組織はありません。シングルテナント、意図的です。常に同じ値を持つorganizationIdは、列、インデックス、およびレビュー時に実際のもののようになる購入をしない権限チェックです。
クイックスタート
BunとDockerが必要です。
git clone https://github.com/trycompai/crm.git && cd crm
bun install
docker compose up -d # Postgres on :5432
cp .env.example .env # then fill in the four values below
bun run db:deploy # apply migrations
bun run db:seed # optional: a believable pipeline to look at
bun run dev
アプリはlocalhost:3000、APIはlocalhost:3001で実行されます。
4つの値
.envを開き、これらを設定します。ファイル内の他のすべてはオプションでコメントアウトされています。
Variable
What to put in it
BETTER_AUTH_SECRET
openssl rand -base64 32
ALLOWED_SIGN_IN
あなたのメールドメイン、例:acme.com。または1つのアドレス、例: