paint-brush
আরও ভাল - একটি AI চালিত কোড রিভিউয়ারদ্বারা@murtuzaalisurti
নতুন ইতিহাস

আরও ভাল - একটি AI চালিত কোড রিভিউয়ার

দ্বারা Murtuza8m2024/11/20
Read on Terminal Reader
Read this story w/o Javascript

অতিদীর্ঘ; পড়তে

কোড পর্যালোচনাগুলি সর্বদা একটি মান বজায় রাখতে এবং একটি প্রকল্পে কোডের সর্বোত্তম অনুশীলনের উপর জোর দেওয়ার জন্য গুরুত্বপূর্ণ। এটি বিকাশকারীদের কীভাবে কোডটি পর্যালোচনা করা উচিত সে সম্পর্কে কোনও পোস্ট নয়, এটি এর একটি অংশ এআইকে অর্পণ করার বিষয়ে আরও বেশি। এই কারণেই আমি একটি গিথুব অ্যাকশন তৈরি করার সিদ্ধান্ত নিয়েছি (github.com/murtuzaalisurti/better) যে কোডটি একটি পুল অনুরোধের পার্থক্য পর্যালোচনা করে এবং AI ব্যবহার করে পরামর্শ তৈরি করে।

People Mentioned

Mention Thumbnail
Mention Thumbnail

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - আরও ভাল - একটি AI চালিত কোড রিভিউয়ার
Murtuza HackerNoon profile picture
0-item
1-item

কোড পর্যালোচনাগুলি সর্বদা উচ্চ মান বজায় রাখতে এবং একটি কোডিং প্রকল্পে সর্বোত্তম অনুশীলনগুলিকে শক্তিশালী করার জন্য গুরুত্বপূর্ণ। এটি বিকাশকারীদের কীভাবে কোডটি পর্যালোচনা করা উচিত সে সম্পর্কে কোনও পোস্ট নয়, এটি এর একটি অংশ এআইকে অর্পণ করার বিষয়ে আরও বেশি।


মাইকেল লিঞ্চ যেমন তার পোস্টে উল্লেখ করেছেন - "কিভাবে কোড রিভিউ লাইক আ হিউম্যান" - আমাদের উচিত কম্পিউটারগুলিকে কোড পর্যালোচনার বিরক্তিকর অংশগুলির যত্ন নিতে দেওয়া । মাইকেল একটি ফর্ম্যাটিং টুলের উপর জোর দেওয়ার সময়, আমি এটিকে আরও এক ধাপ এগিয়ে নিতে চাই এবং কৃত্রিম বুদ্ধিমত্তাকে এটি বের করতে চাই। আমি বলতে চাচ্ছি, কেন শিল্পে এআই বুমের সুবিধা নেবেন না?


এখন আমি বলছি না যে AI ফর্ম্যাটিং টুল এবং লিন্টারের জায়গায় ব্যবহার করা উচিত। পরিবর্তে, এটি তার উপরে ব্যবহার করা হবে, তুচ্ছ জিনিসগুলি ধরার জন্য যা একজন মানুষ মিস করতে পারে। এই কারণেই আমি একটি গিথুব অ্যাকশন তৈরি করার সিদ্ধান্ত নিয়েছি যা কোড একটি পুল অনুরোধের পার্থক্য পর্যালোচনা করে এবং এআই ব্যবহার করে পরামর্শ তৈরি করে। আমাকে এটা মাধ্যমে আপনি হাঁটা যাক.


🚨 দ্রষ্টব্য:


পার্থক্য পেয়ে

Github API এর সাথে ইন্টারঅ্যাক্ট করার জন্য, আমি octokit ব্যবহার করেছি, যা একটি SDK বা একটি ক্লায়েন্ট লাইব্রেরি যা গিথুব এপিআই এর সাথে ইডিওম্যাটিক উপায়ে ইন্টারঅ্যাক্ট করার জন্য


আপনি উত্থাপিত পুল অনুরোধের পার্থক্য পেতে, আপনাকে প্রয়োজনীয় প্যারামিটার সহ মান application/vnd.github.diff সহ Accept হেডার পাস করতে হবে।


 async function getPullRequestDetails(octokit, { mode }) { let AcceptFormat = "application/vnd.github.raw+json"; if (mode === "diff") AcceptFormat = "application/vnd.github.diff"; if (mode === "json") AcceptFormat = "application/vnd.github.raw+json"; return await octokit.rest.pulls.get({ owner: github.context.repo.owner, repo: github.context.repo.repo, pull_number: github.context.payload.pull_request.number, headers: { accept: AcceptFormat, }, }); }



আপনি যদি গিথুব অ্যাকশনগুলির সাথে একেবারেই পরিচিত না হন তবে এখানে ভিক্টোরিয়া লো-এর একটি গিথুব অ্যাকশন 101 সিরিজ রয়েছে এবং এটি একটি ভাল শুরু।



একবার আমি পার্থক্যটি পেয়ে গেলে, আমি এটি পার্স করি এবং অবাঞ্ছিত পরিবর্তনগুলি সরিয়ে ফেলি এবং তারপরে নীচে দেখানো একটি স্কিমাতে এটি ফিরিয়ে দিই:


 /** using zod */ schema = z.object({ path: z.string(), position: z.number(), line: z.number(), change: z.object({ type: z.string(), add: z.boolean(), ln: z.number(), content: z.string(), relativePosition: z.number(), }), previously: z.string().optional(), suggestions: z.string().optional(), })

ফাইল উপেক্ষা করা

ফাইল উপেক্ষা করা বেশ সহজবোধ্য। ব্যবহারকারীর ইনপুট তালিকার জন্য গ্লোব প্যাটার্নগুলির একটি সেমিকোলন পৃথক স্ট্রিং প্রয়োজন৷ তারপর এটি পার্স করা হয়, উপেক্ষা করা ফাইলগুলির ডিফল্ট তালিকার সাথে সংযুক্ত করা হয় এবং ডি-ডুপ করা হয়।


 **/*.md; **/*.env; **/*.lock; const filesToIgnoreList = [ ...new Set( filesToIgnore .split(";") .map(file => file.trim()) .filter(file => file !== "") .concat(FILES_IGNORED_BY_DEFAULT) ), ];


উপেক্ষা করা ফাইলের তালিকাটি তখন ভিন্ন পরিবর্তনগুলি সরাতে ব্যবহৃত হয় যা সেই উপেক্ষা করা ফাইলগুলিকে উল্লেখ করে। এটি আপনাকে একটি কাঁচা পেলোড দেয় যার মধ্যে শুধুমাত্র আপনি যে পরিবর্তনগুলি চান।

প্রস্তাবনা তৈরি করা হচ্ছে

একবার আমি পার্থক্য পার্স করার পরে কাঁচা পেলোড পেয়ে গেলে, আমি এটি প্ল্যাটফর্ম API এ পাস করি। এখানে OpenAI API-এর একটি বাস্তবায়ন।


 async function useOpenAI({ rawComments, openAI, rules, modelName, pullRequestContext }) { const result = await openAI.beta.chat.completions.parse({ model: getModelName(modelName, "openai"), messages: [ { role: "system", content: COMMON_SYSTEM_PROMPT, }, { role: "user", content: getUserPrompt(rules, rawComments, pullRequestContext), }, ], response_format: zodResponseFormat(diffPayloadSchema, "json_diff_response"), }); const { message } = result.choices[0]; if (message.refusal) { throw new Error(`the model refused to generate suggestions - ${message.refusal}`); } return message.parsed; }


আপনি API বাস্তবায়নে প্রতিক্রিয়া বিন্যাসের ব্যবহার লক্ষ্য করতে পারেন। এটি অনেক LLM প্ল্যাটফর্মের দ্বারা প্রদত্ত একটি বৈশিষ্ট্য, যা আপনাকে একটি নির্দিষ্ট স্কিমা/ফরম্যাটে প্রতিক্রিয়া তৈরি করতে মডেলকে বলতে দেয়। এই ক্ষেত্রে এটি বিশেষভাবে সহায়ক কারণ আমি চাই না মডেলটি হ্যালুসিনেট করুক এবং পুল অনুরোধে ভুল ফাইল বা অবস্থানের জন্য পরামর্শ তৈরি করুক বা প্রতিক্রিয়া পেলোডে নতুন বৈশিষ্ট্য যুক্ত করুক।


সিস্টেম প্রম্পটটি মডেলটিকে আরও প্রসঙ্গ দেওয়ার জন্য রয়েছে যে এটি কীভাবে কোড পর্যালোচনা করা উচিত এবং কিছু জিনিস কী মনে রাখতে হবে। আপনি github.com/murtuzaalisurti/better এখানে সিস্টেম প্রম্পট দেখতে পারেন। ব্যবহারকারীর প্রম্পটে প্রকৃত পার্থক্য, নিয়ম এবং পুল অনুরোধের প্রসঙ্গ রয়েছে। এটা কি কোড পর্যালোচনা বন্ধ কিক.


এই গিথুব অ্যাকশন ওপেনএআই এবং অ্যানথ্রপিক উভয় মডেলকে সমর্থন করে। এটি কীভাবে অ্যানথ্রপিক API প্রয়োগ করে তা এখানে:


 async function useAnthropic({ rawComments, anthropic, rules, modelName, pullRequestContext }) { const { definitions } = zodToJsonSchema(diffPayloadSchema, "diffPayloadSchema"); const result = await anthropic.messages.create({ max_tokens: 8192, model: getModelName(modelName, "anthropic"), system: COMMON_SYSTEM_PROMPT, tools: [ { name: "structuredOutput", description: "Structured Output", input_schema: definitions["diffPayloadSchema"], }, ], tool_choice: { type: "tool", name: "structuredOutput", }, messages: [ { role: "user", content: getUserPrompt(rules, rawComments, pullRequestContext), }, ], }); let parsed = null; for (const block of result.content) { if (block.type === "tool_use") { parsed = block.input; break; } } return parsed; }

মন্তব্য যোগ করা হচ্ছে

অবশেষে, পরামর্শগুলি পুনরুদ্ধার করার পরে, আমি সেগুলিকে স্যানিটাইজ করি এবং পর্যালোচনার অংশ হিসাবে মন্তব্যগুলি যোগ করার জন্য সেগুলিকে গিটহাব এপিআইতে প্রেরণ করি।

আমি মন্তব্য যোগ করার জন্য নীচের উপায়টি বেছে নিয়েছি কারণ একটি নতুন পর্যালোচনা তৈরি করে, আপনি একবারে একটি একক মন্তব্য যোগ করার পরিবর্তে একযোগে সমস্ত মন্তব্য যোগ করতে পারেন৷ একের পর এক মন্তব্য যোগ করলেও রেট সীমিত হতে পারে কারণ মন্তব্য যোগ করা বিজ্ঞপ্তিগুলিকে ট্রিগার করে এবং আপনি বিজ্ঞপ্তি দিয়ে ব্যবহারকারীদের স্প্যাম করতে চান না।


 function filterPositionsNotPresentInRawPayload(rawComments, comments) { return comments.filter(comment => rawComments.some(rawComment => rawComment.path === comment.path && rawComment.line === comment.line) ); } async function addReviewComments(suggestions, octokit, rawComments, modelName) { const { info } = log({ withTimestamp: true }); // eslint-disable-line no-use-before-define const comments = filterPositionsNotPresentInRawPayload(rawComments, extractComments().comments(suggestions)); try { await octokit.rest.pulls.createReview({ owner: github.context.repo.owner, repo: github.context.repo.repo, pull_number: github.context.payload.pull_request.number, body: `Code Review by ${modelName}`, event: "COMMENT", comments, }); } catch (error) { info(`Failed to add review comments: ${JSON.stringify(comments, null, 2)}`); throw error; } }

উপসংহার

আমি গিটহাব অ্যাকশনটিকে ওপেন-এন্ডেড এবং ইন্টিগ্রেশনের জন্য উন্মুক্ত রাখতে চেয়েছিলাম এবং সেজন্য আপনি আপনার পছন্দের যে কোনও মডেল ব্যবহার করতে পারেন ( সমর্থিত মডেলগুলির তালিকা দেখুন) , অথবা আপনি সমর্থিত মডেলগুলির উপরে আপনার নিজস্ব কাস্টম মডেল তৈরি করতে পারেন বেস মডেল এবং এই GitHub কর্মের সাথে এটি ব্যবহার করুন।


আপনি যদি কোনো টোকেন সমস্যা বা হার সীমাবদ্ধতার সম্মুখীন হন, আপনি সংশ্লিষ্ট প্ল্যাটফর্মের ডকুমেন্টেশন উল্লেখ করে আপনার মডেল সীমা আপগ্রেড করতে চাইতে পারেন।


তাই, আপনি কি জন্য অপেক্ষা করছেন? আপনার যদি গিথুবে সংগ্রহস্থল থাকে তবে এখনই অ্যাকশনটি চেষ্টা করুন - এটি গিথুব অ্যাকশন মার্কেটপ্লেসে রয়েছে।