مقالات

چگونه یک خط لوله هوش مصنوعی بومی با Jev و Clairic بسازیم.


ایمیل پشتیبانی وارد می‌شود: «NW-47790 را سفارش دهید، میله‌های چادر در شب اول شکستند، 389 دلار پرداخت کردند و امروز هر سنت را پس می‌خواهید یا در مورد شارژ اعتراض کنید».

برای انجام این کار، کد شما نیاز به پاسخ به چند سوال کوچک دارد. آیا این درخواست بازپرداخت است؟ چقدر فوری است؟ آیا یک شخص باید آن را مدیریت کند؟ شماره سفارش چیست؟ چقدر پول در کار است؟ این مشکل یکسان است چه از طریق صندوق ورودی پشتیبانی مرتب کنید یا یک ربات چت سفارشی بسازید که باید بفهمد هر مشتری چه می خواهد.

حرکت معمولی این است که کل ایمیل را به یک مدل چت با اعلانی که با «پاسخ‌ها در JSON» ختم می‌شود، ارسال کنید، سپس هر آنچه را که برمی‌گردد تأیید کنید. کار می کند، اما شما به مدلی پرداخت می کنید که برای نوشتن مقاله طراحی شده است تا پنج قسمت را پر کند، و حدس آن را در یک طرح کلی تحلیل می کنید.

مدل های System One فقط برای این نوع کار ساخته شده اند. در این آموزش، یک کانال صندوق پست پشتیبانی کوچک با دو مورد از این موارد ایجاد می کنیم: Jev از TypeSafe تصمیم گیری می کند و روحانی از Cloudflare ارزش ها را می خواند سپس TypeScript ساده پاسخ های آنها را به عمل تبدیل می کند. بدون مهندسی سریع برای فرمت های خروجی و بدون وصله JSON.

مدل های System One چیست؟

این نام از دانیل کانمن گرفته شده است فکر کردن، سریع و آهسته. سیستم 1 تفکر سریع و شهودی است که برای خواندن یک چهره یا علامت استفاده می کنید. سیستم 2 ظاهر آهسته و عمدی است که برای تقسیم های طولانی استفاده می کنید.

مدل System One یک مدل هوش مصنوعی است که زبان طبیعی را می‌فهمد اما متن تولید نمی‌کند. شما به آن کمک می کنید ( شرط) و مجموعه ای از سوالات ورودی و پاسخ های ورودی را با احتمالات برمی گرداند. هیچ متن رایگانی برای تجزیه وجود ندارد زیرا مدل فقط می تواند در قالبی که شما درخواست کرده اید پاسخ دهد.

این با درخواست مدل چت برای خروجی ساختاریافته متفاوت است. راهنمای SitePoint برای LLM Structured Output با طرحواره JSON نشان می دهد که چگونه یک مدل چت را محدود کرده و JSON آن را با Zod تأیید کنید. با یک مدل System One، نوع است رابط: یک سوال بله/خیر به عنوان احتمال، یک سوال انتخابی به عنوان یکی از گزینه های شما و یک تاریخ به عنوان یک تاریخ برگردانده می شود.

دو ویژگی دیگر در عمل مهم هستند:

  • هر پاسخ حاوی اطمینان یا احتمال است. کد شما می تواند بر روی پاسخ های ایمن عمل کند و پاسخ های ناامن را برای یک شخص ارسال کند.
  • آنها سریع و ارزان هستند. در سری زیر، هر مدل در چند صد میلی ثانیه به کسری از سنت پاسخ داد.

دو مدل، دو کار

Jev و Clairic مدل های System One هستند، اما کارهای متفاوتی انجام می دهند و این باعث می شود جفت خوبی باشند.

Jev (TypeSafe) Clairic (Cloudflare Worker AI)
کار کردن در مورد ورودی تصمیم گیری می کند مقادیر را از ورودی می خواند و محاسبه می کند
انواع سوالات انتخاب (یک گزینه را انتخاب کنید) نتیجه (نرخ رتبه بندی شده)، نول (احتمالا) متن، شماره، تاریخ، زمان، تاریخ و زمان، مدت، فهرست، ارزیابی، پیش بینی
آنچه را پس می گیرید گزینه، نتیجه یا احتمال، به علاوه قطعیت مقدار (مقادیر متن مانند فواصل دقیق نویسه ورودی)، اطمینان، و احتمال اینکه اصلا وجود ندارد
قیمت 0.042 دلار به ازای هر میلیون توکن ورودی، بدون برداشت 0.10 دلار به ازای هر میلیون توکن وارد شده
وضعیت در دسترس عموم (jev-1.14.0) بررسی کنید

Jev نمی تواند به شما شماره سفارش بدهد و Clairic راهی برای انتخاب از بین لیست گزینه ها یا پاسخ بله یا خیر ندارد. به هر یک از آنها شغلی را بدهید که برای آن ایجاد شده اند.

اگر آموزش Jev و LangChain SitePoint را خوانده باشید، دیده اید که چگونه Jev تصمیم می گیرد که کدام مدل درخواست یک نماینده را رسیدگی کند. در اینجا ما از آن در خود متن ورودی استفاده خواهیم کرد.

ما چه می سازیم؟

پنج ایمیل ساختگی برای یک فروشگاه لوازم در فضای باز ساختگی وارد می شود. برای هر کدام:

  1. Jev تصمیم می گیرد که مشتری چه می خواهد، چقدر فوری است، و اینکه آیا شخص نیاز به مداخله دارد یا خیر.
  2. روحانی شماره سفارش، مبلغ بازپرداخت، تاریخ سفارش و هر مهلتی را بیرون می آورد.
  3. کد ساده قوانین فروشگاه را اجرا می‌کند: بازپرداخت‌های کوچک به صف بازپرداخت می‌رود، مشتریان عصبانی به سمت شخصی می‌روند، شماره‌های سفارش گمشده به صورت خودکار یک «شماره سفارش شما چیست؟» دریافت می‌کنند. پاسخ و غیره

هر دو مدل یک ایمیل را می خوانند، بنابراین همزمان کار می کنند.

پیش نیازها

  • Node.js 23 یا جدیدتر که فایل های TypeScript را مستقیماً اجرا می کند (در Node 22 add --experimental-strip-types)
  • کلید API TypeSafe از کنسول TypeSafe
  • شناسه حساب Cloudflare و توکن API مجوز AI Workers

سه مقدار را در محیط خود قرار دهید:

export TYPESAFE_API_KEY=...
export CLOUDFLARE_ACCOUNT_ID=...
export CLOUDFLARE_API_TOKEN=...

بدون نیاز به SDK هر دو مدل تک هستند fetch یک تماس

مرحله 1: صندوق ورودی

اینم صندوق ورودی تست هر ایمیل برای آزمایش مسیر متفاوتی از طریق قوانین وجود دارد:


export const emails = [
  {
    id: 'refund-small',
    text: `Hi there, I ordered the trail socks (3 pack) on October 20, order #NW-48213, and one pair arrived with a hole in the heel. Could I get the $18.95 back for that pack? Happy to send a photo. Thanks, Priya`,
  },
  {
    id: 'refund-angry',
    text: `This is the THIRD time I've emailed. Order NW-47790 — the tent poles snapped on the first night and my kids were out in the rain. I paid $389 and I want every cent back today or I'm disputing the charge with my bank and leaving a review everyone will see.`,
  },
  {
    id: 'where-is-it',
    text: `Hey, just checking on order NW-48577 from last Monday. My hiking trip starts on the 14th so I really need the boots before then. Any chance you can tell me where it's at?`,
  },
  {
    id: 'no-order-number',
    text: `Hello, I bought a rain jacket from you a couple of weeks ago and it's way too big. Can I swap it for a medium?`,
  },
  {
    id: 'pre-sale',
    text: `Does the Ridgeline 40L pack fit carry-on rules for most airlines? And does it come in green? Thinking of buying two.`,
  },
];

مرحله 2: Jev تصمیم می گیرد

Jev a را می گیرد state (ایمیل) و مجموعه ای از سوالات نامگذاری شده. از هر نوع از سه نفر می پرسیم:

const JEV_QUESTIONS = {
  intent: {
    type: 'choice',
    instructions: 'What is the customer mainly asking the store to do in this email?',
    criteria: {
      refund: 'Give money back for an order or a charge',
      order_status: 'Say where an order is or when it will arrive',
      exchange: 'Swap an item for a different size, colour or product',
      product_question: 'Answer a question about a product before or after buying',
      other: 'Anything else',
    },
  },
  urgency: {
    type: 'score',
    instructions: 'How soon does this email need a reply from the store?',
    criteria: ['Can wait a few days', 'Should be answered today', 'Needs a reply within the hour'],
  },
  needs_person: {
    type: 'noul',
    instructions:
      'Does this email need a person rather than an automatic reply? Yes if the customer is very upset, threatens a chargeback, a bad review or legal action, or raises a safety problem with a product.',
  },
} as const;

چند نکته قابل توجه:

  • انتخاب معیار یک نقشه از گزینه تا توضیحات است. شرح همان چیزی است که Jev در مورد آن قضاوت می کند، بنابراین آن را همانطور که به یکی از اعضای جدید کارمند توضیح می دهید بنویسید.
  • نتیجه معیارها سطوح مرتب شده هستند، ابتدا کمترین. پاسخ عددی بین 0 و بالاترین سطح است، بنابراین 1.7 به معنای “بین امروز و ظرف یک ساعت، حروف کج فوری” است.
  • نول نام TypeSafe برای یک سوال بله / خیر است. پاسخ به احتمال زیاد بله است.

هر سه سوال در یک درخواست قرار می گیرند. Jev ایمیل را یک بار می خواند و به هر سوال به صورت موازی پاسخ می دهد، بنابراین اضافه کردن یک سوال هزینه بسیار کمی دارد:

async function askJev(state: string) {
  const started = performance.now();
  const res = await fetch('https://api.typesafe.ai/v1/systemone', {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.TYPESAFE_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ model: 'jev-1.14.0', state, questions: JEV_QUESTIONS }),
  });
  if (!res.ok) throw new Error(`Jev ${res.status}: ${await res.text()}`);
  const body = await res.json();
  return { ...body, ms: Math.round(performance.now() - started) };
}

چفت می کنیم jev-1.14.0 و نه در jev-latest نام مستعار آستانه های شما در برابر احتمالات یک نسخه تنظیم شده است، بنابراین می خواهید انتخاب کنید که آن نسخه چه زمانی تغییر کند.

برای ایمیل چادر خشمگین، جیو برگشت با:

{
  "intent": { "type": "choice", "choice": "refund", "confidence": 1.0 },
  "urgency": { "type": "score", "score": 1.75, "confidence": 0.62 },
  "needs_person": { "type": "noul", "noul": 0.98 }
}

(بریده شده: پاسخ واقعی شامل احتمال هر گزینه و سطح نیز می شود.)

مرحله 3: Clairic مقادیر را می خواند

روحانی هم همین را می پذیرد state، به علاوه مجموعه ای از تایپ شده زمینه ها به جای سوال:

const CLAIRIC_FIELDS = {
  order_number: { type: 'text', instructions: 'The order number the customer gives' },
  amount: { type: 'number', decimals: 2, unit: 'USD', instructions: 'The amount of money the customer wants back, in dollars' },
  ordered_on: { type: 'date', instructions: 'The date the customer placed the order' },
  needed_by: { type: 'date', instructions: 'The date the customer says they need the order by' },
};

async function askClairic(state: string) {
  const started = performance.now();
  const url = `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCOUNT_ID}/ai/run/@cf/cloudflare/clairic`;
  const res = await fetch(url, {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ model: 'clairic', state, fields: CLAIRIC_FIELDS, reference_date: '2026-11-02' }),
  });
  if (!res.ok) throw new Error(`Clairic ${res.status}: ${await res.text()}`);
  const { result } = await res.json(); 
  return { ...result, ms: Math.round(performance.now() - started) };
}

reference_date تاریخ های نسبی مانند “چهاردهم” یا “دوشنبه گذشته” را نشان می دهد. در محیط تولید، تاریخ ورود ایمیل را ارسال کنید.

هر پاسخ سه چیز ارزش استفاده را برمی‌گرداند:

  • value: پاسخ یا null اگر ایمیل نگوید
  • confidence: چقدر مطمئن است که Clairic این مقدار را دارد.
  • p_null: احتمال اینکه مقدار اصلاً در ورودی نباشد.

برای “کجاست؟” ایمیل، Clairik ضرب الاجل را به این ترتیب خواند:

"needed_by": { "type": "date", "value": "2026-11-14", "confidence": 0.99999, "p_null": 0.002 }

“14” به یک تاریخ کامل تبدیل شد که از تاریخ مرجع توسعه یافته است. فیلدهای متنی مانند order_number همچنین به عنوان مجموعه نویسه های ایمیل اصلی بازگردانده می شوند. مقدار از ورودی کپی می‌شود، تولید نمی‌شود، بنابراین نمی‌تواند با شماره سفارشی بیاید که وجود ندارد.

مرحله 4: هر دو را همزمان اجرا کنید

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

for (const email of emails) {
  const [jev, clairic] = await Promise.all([askJev(email.text), askClairic(email.text)]);
  rows.push({ email, jev, clairic, action: decide(jev.answers, clairic.answers) });
}

زمان هر ایمیل بستگی به این دارد که کدام مدل کندتر است، نه اینکه این دو با هم جمع شوند.

مرحله 5: قوانین را در کد قرار دهید

این بخشی است که مدل چت معمولاً آن را ضعیف انجام می دهد: قوانین تجاری. در اینجا آنها کدهای ساده ای هستند که می توانید آنها را بخوانید، آزمایش کنید و بدون لمس کردن دستور تغییر دهید:

const AUTO_REFUND_LIMIT = 100; 
const SURE = 0.9;

function decide(jev, clairic) {
  const { intent, urgency } = jev;
  const needsPerson = jev.needs_person.noul;
  const order = clairic.order_number;
  const amount = clairic.amount;

  if (needsPerson > 0.5) return 'person: upset or risky';
  if (intent.confidence  0.6) return 'person: unclear what they want';
  if (intent.choice === 'product_question' || intent.choice === 'other') return `${intent.choice} queue`;

  
  if (order.value === null) return 'auto-reply: ask for the order number';
  if (order.confidence  SURE) return 'person: order number unclear';
  const orderNo = String(order.value).replace(/^#/, '');

  if (intent.choice === 'refund') {
    if (typeof amount.value !== 'number') return 'person: refund with no amount';
    return amount.value  AUTO_REFUND_LIMIT && amount.confidence >= SURE
      ? `refund queue: $${amount.value.toFixed(2)} on ${orderNo}`
      : 'person: refund over the limit';
  }
  if (intent.choice === 'order_status') {
    
    const neededBy = clairic.needed_by.confidence >= SURE ? clairic.needed_by.value : null;
    const rush = urgency.score >= 1.5 || neededBy !== null;
    return `${rush ? 'priority ' : ''}tracking reply for ${orderNo}${neededBy ? ` (needed by ${neededBy})` : ''}`;
  }
  return `${intent.choice} queue for ${orderNo}`;
}

توجه داشته باشید که اطمینان مدل درست در کنار قانون تجارت قرار دارد. بازپرداخت 18.95 دلار فقط در صورتی خودکار است که Clairic هم از تعداد سفارش و هم از مبلغ مطمئن باشد. افزایش حد بازیابی یا نوار اطمینان یک تغییر خط است و نیازی نیست دوباره با هیچ مدلی تماس بگیرید تا ببینید چه کاری انجام خواهد داد. پاسخ ها را ذخیره کرده و تکرار کنید.

نتایج

در اینجا نتایج هر پنج ایمیل آمده است:

ایمیل Jev روحانی اقدام
بازیابی – کوچک 407 میلی‌ثانیه 420 میلی‌ثانیه صف بازپرداخت: 18.95 دلار به ازای هر NW-48213
بهبودی-عصبانی 252 میلی‌ثانیه 515 میلی‌ثانیه چهره: ناراحت یا مخاطره آمیز
کجاست 254 میلی‌ثانیه 333 میلی‌ثانیه پاسخ ردیابی اولویت برای NW-48577 (سررسید تا 14-11-2026)
شماره بدون سفارش 245 میلی‌ثانیه 561 میلی‌ثانیه پاسخ خودکار: شماره سفارش را بخواهید
پیش فروش 261 میلی‌ثانیه 503 میلی‌ثانیه صف محصول_سوال

هر ایمیل به جایی که باید رفت رفت. کل سری از 2703 توکن ورودی Jev و 2292 Clairic استفاده می‌کرد که مجموعاً حدود 0.0003 دلار آمریکا بود. با این نرخ، هزینه 10000 ایمیل پشتیبانی تقریبا 0.70 دلار خواهد بود.

آنچه که نمرات اعتماد به نفس به دست آوردند

بخش جالب اجرا پاسخ های صحیح نبود. هر دو اشتباه می کردند.

“از دوشنبه گذشته.” اجرا از 2 نوامبر 2026 به عنوان تاریخ مرجع استفاده می کند که دوشنبه است. “دوشنبه گذشته” به معنای 26 اکتبر است، اما Clairic پاسخ داد 2026-11-02، خود تاریخ مرجع. اعتماد او به این پاسخ بود 0.54، در مقایسه با 0.99 یا بالاتر برای تقریباً هر مقدار دیگر در چرخه.

“چند هفته پیش.” روحانی این را تبدیل کرد 2026-10-19، که خواندنی منصفانه است، اما همچنان یک حدس است. اعتماد به نفس او بود 0.43.

هیچ تاریخی هیچ اقدامی را تغییر نداده است زیرا قوانین فقط به مقادیر 0.9 یا بالاتر اعتماد دارند. این عادت ساخت است: مقدار زیر نوار شما ناشناخته در نظر گرفته می شود. یک مدل چت که JSON را برمی گرداند به شما می داد "2026-11-02" با همان اطمینان همه چیز دیگر.

نکته دیگر: روحانی شماره سفارش را به عنوان کپی می کند #NW-48213، هش گنجانده شده است زیرا مشتری آن را اینگونه نوشته است. مقادیر متن محدوده های ورودی هستند، بنابراین عادی سازی آنها وظیفه کد شماست. این یک خط کد است.

جایی که هر مدلی سقوط می کند

Jev

  • تصمیم می گیرد؛ مقادیر را نمی خواند درخواست شماره سفارش ابزار اشتباهی است.
  • اطمینان از نتیجه می تواند با مقیاس های فازی متوسط باشد. اطمینان فوری از 0.28 تا 0.86 در پنج ایمیل متغیر بود و سؤال مبهم پیش فروش کمترین اطمینان را داشت. از نتیجه به عنوان یک سیگنال، همراه با شواهد دیگر (مانند مهلت واقعی Clairic) استفاده کنید، نه به عنوان یک قانون کلی.
  • آستانه ها فقط برای داده های خود شما مهم هستند. 0.5 برای needs_person روی پنج ایمیل کار می کند. قبل از اینکه به آن اعتماد کنید، آن را با چند صد مورد واقعی بررسی کنید.

روحانی

  • در پیش نمایش است، بنابراین منتظر تغییرات باشید و قبل از تکیه بر آن، آزمایشات خود را به خروجی آن متصل کنید.
  • مقادیر را می خواند و محاسبه می کند، اما نمی تواند بین گزینه های شما یکی را انتخاب کند. طبقه بندی متعلق به Jev یا کد است.
  • همانطور که مورد «دوشنبه گذشته» نشان می دهد، تاریخ های نسبی جایی هستند که کمترین قطعیت را دارند. همیشه پاس reference_dateو اعتبار تاریخ ها را بررسی کنید.

هر دو

  • چیزی هم نمی گوید. آنها کد شما را در ایمیل می گویند. آنها نمی توانند به آن پاسخ دهند.

وقتی هنوز به یک مدل چت کامل نیاز دارید

مدل های System One کار خواندن و مسیریابی را انجام می دهند. آنها گفتگو نمی کنند. پس از ارسال ایمیل، چیزی برای نوشتن پاسخ، پرسیدن سوال بعدی یا توضیح خط مشی بازگشت به زبان خود مشتری نیاز دارد. این جایی است که مدل چت حفظ خود را به دست می آورد.

جدایی که کار می کند این است: مدل های System One تصمیم می گیرند، کد قوانین را اجرا می کند، و مدل چت فقط مواردی را دریافت می کند که کلمات مهم هستند.

تکمیل

ما یک کانال مرتب‌سازی صندوق ورودی پشتیبانی از دو مدل کوچک و چند کد ساده ایجاد کرده‌ایم:

  • Jev به سه سوال برای هر ایمیل پاسخ داد: چه چیزی می خواستند، چقدر فوری بود، و اینکه آیا یک شخص باید آن را مدیریت کند.
  • روحانی شماره سفارش، مبلغ و تاریخ‌ها را استخراج کرد، که هر کدام دارای رتبه اطمینان بودند.
  • TypeScript قوانین را فقط با اعتماد به مقادیر بالای باند اطمینان اعمال کنید.

هر ایمیل حدود نیم ثانیه طول می کشد و کمتر از یک صدم سنت هزینه دارد. مهمتر از همه، دو پاسخی که اشتباه می‌کردند، نامشخص بودند.

کد کامل حدود 160 خط بدون وابستگی است. سعی کنید سوال چهارم Jev را اضافه کنید (آیا مشتری عکسی را ذکر می کند؟) یا estimate در Clairic (چند روز مانده به سفر؟) و ببینید بقیه خط لوله چقدر نیاز به تغییر دارد.


Source link

نوشته های مشابه

دیدگاهتان را بنویسید

همچنین ببینید
بستن
دکمه بازگشت به بالا