استفاده از Localized LLM برای پر کردن شکاف های مورد نیاز مشتری

چالش ها در جمع آوری نیازمندی ها
در بیش از 200 وبسایت و برنامه تلفن همراه، من هنوز ندیدهام مشتری با مجموعه کاملی از الزامات پروژه خود ظاهر شود. در واقع، بسیاری از مشتریان ما دانشگاهیان هستند که دانش محدودی در زمینه توسعه نرم افزار دارند. مهمتر از آن، آنها اغلب دانش خاص دامنه دارند که بسیار فراتر از دانش ماست. این میتواند تعیین نسخه جامد نسخه 1.0 را دشوار کند.
ما به فرآیند مصاحبه با استفاده از طراحی مبتنی بر سناریو (SBD) برای گرفتن جزئیات خاص دامنه و روشن کردن یک محصول حداقل قابل دوام متکی هستیم. ما یک کاربرگ ایجاد کردهایم که مشتریان را در طول فرآیند، شامل اهداف پروژه، مفاهیم کلیدی، ذینفعان و سناریوهای کاملاً تعریفشده، گام بر میدارد. با این حال، فرآیند مصاحبه می تواند دست و پا گیر باشد و اغلب ساعت ها طول می کشد تا تکمیل شود. همچنین به میزان مشارکت مشتری حساس است. برای سادهسازی این فرآیند، ما LLM را در گردش کار ادغام کردهایم تا یک خط پایه ایجاد کنیم و به مشتری اجازه میدهیم به جای کار از روی بوم خالی، بازخورد ارائه کند.
اخیراً، ما یک ابزار SBD تعاملی را منتشر کردهایم تا به مشتریان این امکان را میدهد تا به تنهایی این فرآیند را انجام دهند. در سیستم پروژه ما، مشتریان می توانند مراحل را طی کرده و نیازمندی ها را توسعه دهند. از آنجایی که این شامل تعدادی تماس با یک API LLM است، ما میخواستیم بار و هزینههای سیستمهای خود را کاهش دهیم. در عوض، ما از مشتری میخواهیم که یک LLM را به صورت محلی نصب کند و از این نمونه برای تولید سناریوهای خود استفاده میکنیم. این یک مورد استفاده جالب را ایجاد می کند که فکر کردم آن را به اشتراک بگذارم.
نصب LLM
برای عملی کردن این فرآیند برای مشتریان، ما برای دانلود و اجرای یک LLM محلی به Olama متکی هستیم. مدل اصلی یک دانلود ~ 5 گیگابایتی است و برای آنچه ما در تلاش هستیم به اندازه کافی قدرتمند است. در ابزار SBD، دستورالعملهایی برای راهاندازی و اجرای LLM ارائه میکنیم.
هنگامی که LLM نصب شد، مدل را شناسایی کرده و یک نشانگر وضعیت ارائه میکنیم که به آنها اجازه میدهد بدانند که برای ایجاد یک طرح مبتنی بر سناریو آماده هستند.
const models = ref<llmModel[]>([])
const ollamaRunning = ref(false)
function getModels() {
return axios.request<tagResponse>({
url: "http://localhost:11434/api/tags",
}).then((rsp) => {
const tags = rsp.data
models.value = tags.models
}).catch((err) => {
ollamaRunning.value = false
console.error(err)
})
}
q-btn(label="LLM Online" color="positive" v-if="models.length > 0" icon="sym_o_assistant_on_hub")
q-btn(label="LLM Offline" color="secondary" v-else @click="dlgInstallInstructions=true")
تعامل با API
برقراری تماس با نمونه محلی نسبتاً ساده است. ما از بسته olama NPM برای مدیریت تماس ها به LLM استفاده می کنیم. این به ما این توانایی را می دهد که با درخواست LLM، تکمیل چت را انجام دهیم. در اینجا استفاده اساسی از پلاگین olama است.
import ollama from 'ollama/browser'
const response = await ollama.chat({
model: 'llama3.1',
messages: [{ role: 'user', content: 'Why is the sky blue?' }],
})
console.log(response.message.content)
ما حتی میتوانیم از جریان پشتیبانی کنیم تا به مشتریان اجازه دهیم نتایج LLM را در زمان واقعی مشاهده کنند.
const message = { role: 'user', content: 'Why is the sky blue?' }
const response = await ollama.chat({ model: 'llama3.1', messages: [message], stream: true })
for await (const part of response) {
response.value += part.message.content
}
به عنوان یک مثال در دنیای واقعی، در اینجا نحوه ایجاد یک پروژه انتزاعی از یک توصیف اولیه است.
async function generateAbstract() {
loading.value = true
project.value.abstract = ''
const messages = [
{ role: 'user', content: 'Given the following project description, write a project abstract in 5-8 sentences which describes the problem the project addresses, nature and aims of the software solution, and the expected outcomes. Provide only the abstract without additional details or commentary.' },
{ role: 'user', content: aims.value }
]
const stream = await ollama.chat({ model: props.model, messages: messages, stream: true })
for await (const part of stream) {
project.value.abstract += part.message.content
}
loading.value = false
}
استفاده از LLM برای طراحی مبتنی بر سناریو
از آنجایی که فرآیند طراحی مبتنی بر سناریو ما شامل مراحل بسیاری است، باید اطلاعات پروژه را همزمان با توسعه مشخصات مشتری به جلو منتشر کنیم. در حالی که اولاما دارای یک سیستم حافظه نهفته است که زمینه را فراهم می کند، ما اطلاعات بیشتری را تزریق می کنیم که برای به دست آوردن کنترل بیشتر بر فرآیند مرتبط است.
messages.push({ role: 'user', content: 'Given the following project DESCRIPTION and OUTLINE, List any important tasks that will help to shape the priority and order of deliverables.' })
messages.push({
role: 'user', content: `
DESCRIPTION:
${project.value.abstract}
`})
messages.push({
role: 'user', content: `
OUTLINE:
${timeline.value}
`})
ما اغلب می خواهیم داده های ساختار یافته را از LLM دریافت کنیم، که می تواند با مدل پایه اوللاما (llama3.1) چالش برانگیز باشد. به جای اینکه کلاینت یک مدل از نحوی مانند codellama را نصب کند، ما از یک تکنیک تحریک برای استخراج پاسخ های با قالب بندی صحیح استفاده می کنیم.
جلب همکاری LLM برای تولید دادههای با قالب JSON میتواند چالشبرانگیز باشد، بنابراین ما یک الگو از آنچه میخواهیم برگردانیم ارائه میکنیم.
{
role: 'system', content: `
Provide only a JSON response starting at <BEGIN_JSON> to <END_JSON> with correct syntax strictly adhering to the following structure.
{
"name":"Jane Doe",
"gender":"Female",
"age":"25",
"race":"",
"occupation":"student",
"education":"bachelor's degree",
"marital_status":"",
"income_level":"low",
"background":"[5-8 sentences about the character's background that led them to use the app with a specific purpose or need]",
"success_story:"Jane was able to use the app successfully to solve her problem.",
"media":{
"image_url":"[a sample image url appropriate to the character]"
}
}
`
},
در تجربه ما، پاسخ می تواند غیرقابل پیش بینی باشد و همیشه JSON را به درستی قالب بندی نمی کند. در حالی که codellama نتایج منسجم تری را با نحو کد ارائه می دهد، ما نمی خواستیم کاربران ما مجبور به نصب مدل دیگری باشند. درعوض، با ارائه ابتدای دستور دستیار به LLM کمک کوچکی می کنیم.
messages.push({
role: 'assistant', content: `Sure! here is the character in the JSON format you requested.
<BEGIN_JSON>
{
"name":"`})
با استفاده از نقش دستیار برای هدایت فرمت پاسخ، ادامه مکالمه چت را برمی گردیم. سپس ساختار مورد انتظار خود را آماده می کنیم و پاسخ JSON را بین توکن های اصلی استخراج می کنیم <BEGIN_JSON>
و <END_JSON>
. این با اطمینان بیشتر قالبی را به ما می دهد که بتوانیم بخش های مربوطه از داده های ساختاریافته را هدف قرار داده و استخراج کنیم.
let content = '<BEGIN_JSON>{"name":"' + rsp.message.content
json = content.substring(content.indexOf("<BEGIN_JSON>") + 12, content.lastIndexOf("<END_JSON>"))
const char = JSON.parse(json)
در اینجا تابع generalCharacter کامل است.
async function generateCharacter() {
loading.value = true
const messages = [
{
role: 'system', content: `
Provide only a JSON response starting at <BEGIN_JSON> to <END_JSON> with correct syntax strictly adhering to the following structure.
{
"name":"Jane Doe",
"gender":"Female",
"age":"25",
"race":"",
"occupation":"student",
"education":"bachelor's degree",
"marital_status":"",
"income_level":"low",
"background":"[5-8 sentences about the character's background that led them to use the app with a specific purpose or need]",
"success_story:"Jane was able to use the app successfully to solve her problem.",
"media":{
"image_url":"[a sample image url appropriate to the character]"
}
}
`
},
{ role: 'user', content: 'Given the following PROJECT, create a CHARACTER as described below.' },
{ role: 'user', content: 'PROJECT: \n' + project.value.abstract + '\n\n' },
{ role: 'user', content: 'CHARACTER: \n' + character.value },
{
role: 'assistant', content: `Sure! here is the character in the JSON format you requested.
<BEGIN_JSON>
{
"name":"`}
]
const rsp = await ollama.chat({ model: props.model, messages: messages, stream: false, options: { temperature: 1.5 } })
let json = ""
let content = '<BEGIN_JSON>{"name":"' + rsp.message.content
try {
json = content.substring(content.indexOf("<BEGIN_JSON>") + 12, content.lastIndexOf("<END_JSON>"))
const char = JSON.parse(json)
char.stakeholder = characterStakeholder.value
project.value.characters.push(char)
charactersError.value = false
dlgAICharacters.value = false
} catch (error) {
charactersError.value = true
project.value.timeline = []
}
loading.value = false
}
همانطور که می بینید، این ابزار مجموعه ای غنی از نیازمندی ها را ایجاد می کند که مشتری می تواند آن را مطابق با نیازهای خود تغییر دهد. ما دریافتهایم که این روشی مؤثر (و سرگرمکننده) برای جمعآوری نیازمندیها حتی از بیمیلترین یا بیتصمیمترین مشتری است. با کمی کمک در طول فرآیند مصاحبه، ما جمع آوری نیازمندی ها را به طور قابل توجهی ساده کرده ایم و نتایج بسیار قابل اعتمادتری تولید کرده ایم. امیدواریم این مثالها به شما کمک کند تا راهحلهای مشابهی را ایجاد کنید که از فناوریهای هوش مصنوعی به سرعت در حال تکامل و فوقالعاده قدرتمند استفاده میکنند که به ابزاری ضروری برای توسعه نرمافزار مدرن تبدیل میشوند.