Kod incelemeleri, bir kodlama projesinde yüksek standartları korumak ve en iyi uygulamaları güçlendirmek için her zaman önemli olmuştur. Bu, geliştiricilerin kodu nasıl incelemesi gerektiğiyle ilgili bir gönderi değil, daha çok bir kısmını yapay zekaya devretmekle ilgilidir. Michael Lynch'in başlıklı yazısında belirttiği gibi, kod incelemesinin . Michael bir biçimlendirme aracını vurgularken, ben bunu bir adım öteye taşıyıp yapay zekanın çözmesine izin vermek istiyorum. Yani, sektördeki yapay zeka patlamasından neden faydalanmayalım ki? "İnsan Gibi Kod İncelemeleri Nasıl Yapılır" sıkıcı kısımlarıyla bilgisayarların ilgilenmesine izin vermeliyiz Şimdi AI'nın biçimlendirme araçları ve lint araçları yerine kullanılması gerektiğini söylemiyorum. Bunun yerine, bir insanın kaçırabileceği önemsiz şeyleri yakalamak için bunun üstüne kullanılmalıdır. Bu yüzden, bir çekme isteği farkını inceleyen ve AI kullanarak öneriler üreten bir oluşturmaya karar verdim. Size yol göstereyim. github eylemi 🚨 NOT: Bu GitHub eylemi artık yerinde mevcuttur. GitHub pazar Bu bir javascript eylemidir - hakkında daha fazla bilgi edinin. javascript github eylemleri oluşturma Farkı almak Github API'siyle etkileşime girebilmek için, olan kullandım. Github API'siyle deyimsel bir şekilde etkileşime girmek için bir tür SDK veya istemci kütüphanesi octokit Çekme isteğinin farkını alabilmeniz için başlığına değerini ve gerekli parametreleri geçirmeniz gerekiyor. Accept application/vnd.github.diff 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, }, }); } Eğer github action'larına hiç aşina değilseniz, iyi bir başlangıç olabilir. Victoria Lo'nun github actions 101 serisi Diff'i aldıktan sonra onu ayrıştırıp istenmeyen değişiklikleri kaldırıyorum ve ardından aşağıda gösterilen şemaya döndürüyorum: /** 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(), }) Dosyaları Yoksayma Dosyaları yok saymak oldukça basittir. Kullanıcı girdi listesi, noktalı virgülle ayrılmış bir glob desenleri dizisi gerektirir. Daha sonra ayrıştırılır, yok sayılan dosyaların varsayılan listesiyle birleştirilir ve çoğaltılmaz. **/*.md; **/*.env; **/*.lock; const filesToIgnoreList = [ ...new Set( filesToIgnore .split(";") .map(file => file.trim()) .filter(file => file !== "") .concat(FILES_IGNORED_BY_DEFAULT) ), ]; Yoksayılan dosyalar listesi daha sonra, bu yoksayılan dosyalara atıfta bulunan diff değişikliklerini kaldırmak için kullanılır. Bu size yalnızca istediğiniz değişiklikleri içeren ham bir yük verir. Öneriler oluşturuluyor Diff'i ayrıştırdıktan sonra ham veriyi aldığımda, bunu platform API'sine iletirim. İşte OpenAI API'sinin bir uygulaması. 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 uygulamasında yanıt biçiminin kullanıldığını fark edebilirsiniz. Bu, birçok LLM platformu tarafından sağlanan ve modele yanıtı belirli bir şema/biçimde oluşturmasını söylemenize olanak tanıyan bir özelliktir. Bu durumda özellikle yararlıdır çünkü modelin halüsinasyon görmesini ve çekme isteğindeki yanlış dosyalar veya konumlar için öneriler oluşturmasını veya yanıt yüküne yeni özellikler eklemesini istemiyorum. Sistem istemi, modele kod incelemesini nasıl yapması gerektiği ve akılda tutulması gereken bazı şeyler hakkında daha fazla bağlam sağlamak için vardır. Sistem istemini buradan görüntüleyebilirsiniz . Kullanıcı istemi gerçek diff'i, kuralları ve çekme isteğinin bağlamını içerir. Kod incelemesini başlatan şeydir. github.com/murtuzaalisurti/better Bu github eylemi hem OpenAI hem de Anthropic modellerini destekler. Anthropic API'yi şu şekilde uygular: 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; } Yorum Ekleme Son olarak önerileri aldıktan sonra onları temizleyip yorumların incelemenin bir parçası olarak eklenmesi için GitHub API'sine iletiyorum. Aşağıdaki yorum ekleme yolunu seçtim çünkü yeni bir inceleme oluşturarak tek seferde tek yorum eklemek yerine tüm yorumları tek seferde ekleyebilirsiniz. Yorumları tek tek eklemek ayrıca oran sınırlamasını da tetikleyebilir çünkü yorum eklemek bildirimleri tetikler ve kullanıcıları bildirimlerle spamlamak istemezsiniz. 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; } } Çözüm GitHub eylemini açık uçlu ve entegrasyonlara açık tutmak istedim ve bu yüzden dilediğiniz modeli kullanabilirsiniz veya desteklenen temel modeller üzerine kendi özel modelinizi ince ayar yapıp oluşturabilir ve bu GitHub eylemiyle birlikte kullanabilirsiniz. ( listesine bakın) desteklenen modeller Herhangi bir karşılaşırsanız, ilgili platformun belgelerine başvurarak model sınırlarınızı yükseltmek isteyebilirsiniz. token sorunu veya oran sınırlamasıyla Peki, daha ne bekliyorsunuz? Github'da deponuz varsa, eylemi şimdi deneyin - . Github Action Marketplace'te