Skip to content

Commit d37fa96

Browse files
authored
Update PromptGenerator.SystemPrompt and GeneratePrompt (#13)
* Update PromptGenerator.SystemPrompt and GeneratePrompt * Fix field name
1 parent 7aac998 commit d37fa96

1 file changed

Lines changed: 131 additions & 74 deletions

File tree

Lines changed: 131 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,179 @@
1-
using System.Runtime.CompilerServices;
1+
using System.Buffers;
2+
using System.Runtime.CompilerServices;
3+
using System.Text.RegularExpressions;
24

35
namespace PRDigest.NET;
46

5-
internal static class PromptGenerator
7+
internal static partial class PromptGenerator
68
{
79
private const int MaxFileCount = 30;
810

911
public const string SystemPrompt = """
1012
あなたは.NET開発者向けのPull Request要約アシスタントです。
11-
以下の形式で要約を出力してください:
13+
提供された情報のみに基づいて要約してください。
14+
提供されていない情報の推測・補完は行わないでください。
1215
13-
=================================
14-
出力形式:
15-
16+
## 出力形式
17+
.NET開発者にとって有益な情報を含める形で、最大1000文字までで要約してください。
18+
以下の出力フォーマット(概要、変更内容、パフォーマンスへの影響、関連Issue、その他)に遵守して、markdown形式で出力してください。
19+
タイトルは不要です。
20+
21+
## 要約ガイドライン
22+
要約を作成する際は、以下の点に特に注意を払ってください:
23+
- 変更の主な意図と技術的ポイントを記述してください(ファイル一覧の再掲は不要)
24+
- 変更がランタイム/コンパイラ/ライブラリのどの部分に影響するか、公開APIか内部実装かを区別してください
25+
- 互換性への影響(破壊的変更、非推奨化など)があれば明記してください
26+
- セキュリティ脆弱性修正の場合はその重要度とCVE番号(あれば)を明記する
27+
- バグ修正の場合は修正前の問題と修正後の動作を対比する
28+
- パフォーマンス改善の場合は改善率や具体的な数値を記載する
29+
- 全体を簡潔にまとめ、必要最低限の情報に絞ること
30+
31+
## 出力フォーマット
1632
#### 概要
17-
1行から5行ぐらいで簡潔に記述してください
18-
またサンプルコードなどもあれば記載してください
19-
33+
変更の目的と内容を1〜5行で簡潔に記述してください
34+
またサンプルコードが存在する場合のみ記載してください
35+
2036
#### 変更内容
2137
変更されたファイルと主な変更内容をリストアップしてください。
22-
38+
2339
#### パフォーマンスへの影響
24-
パフォーマンスに関連する変更があれば具体的に記載してください。(なければ"影響なし")
40+
パフォーマンス(メモリ・実行速度・スループット)に関連する変更があれば具体的に記載してください。(なければ"影響なし")
41+
ベンチマーク結果があれば含めてください。
2542
改善点や懸念点を明記してください。
26-
43+
2744
#### 関連Issue
28-
関連するIssueあれば記載してください。(なければ"なし")
29-
45+
関連するIssueがなければ「なし」と記載してください。
46+
関連するIssueがある場合は記載以下のルールに従って記載してください。
47+
dotnet/runtimeのIssueの場合、[#12345](https://github.com/dotnet/runtime/issues/12345)の形で記載してください。
48+
それ以外のリポジトリのIssueの場合は、リポジトリ名とIssue番号を記載してください。
49+
3050
#### その他
31-
それ以外に記載した方が良い特記事項があれば記載してください。(なければ"なし")
51+
上記以外の特記事項があれば記載してください。
52+
C#のコードサンプルを示す場合は ```csharp ブロックを必ず使用してください。
53+
なければ「なし」。
54+
""";
3255

33-
#### サンプルコードを記載時の注意点
34-
C#のコードブロックを使用してください:
35-
```csharp
36-
// ソースコードを記載
37-
```
38-
=================================
56+
private static ReadOnlySpan<string> EmptyReviewComment => new string[]
57+
{
58+
"generated no new comments",
59+
"generated no comments",
60+
"no new comments",
61+
"Copilot encountered an error and was unable to review this pull request"
62+
};
3963

40-
.NET開発者にとって有益な情報を含める形で、最大1000文字までで要約してください。
41-
タイトルは不要です。markdown形式で出力してください。
64+
private static readonly SearchValues<string> EmptyReviewCommentSearchValues = SearchValues.Create(EmptyReviewComment, StringComparison.Ordinal);
4265

43-
【追加の詳細ガイドライン】
44-
要約を作成する際は、以下の点に特に注意を払ってください:
66+
[GeneratedRegex(@"^\s*(##\s*Pull request overview\s*)?Copilot reviewed \d+ out of \d+ changed files in this pull request and generated \d+ comments\.\s*$")]
67+
private static partial Regex ReviewedOutOfRegex();
68+
69+
public static string GeneratePrompt(PullRequestInfo info)
70+
{
71+
var prompt = $"""
72+
以下のdotnet/runtimeのPull Requestを要約してください。
73+
またできる限り、以下の情報以外の内容を推測して含めないようにしてください。
4574
46-
1. **コード変更の技術的影響**
47-
- 変更がランタイム、コンパイラ、ライブラリのどの部分に影響するか明記
48-
- API の変更がある場合は、公開APIか内部実装かを区別
49-
- 互換性への影響(破壊的変更、非推奨化など)を明確に記載
75+
Pull Request:
76+
- {info.PullRequest.Title} #{info.PullRequest.Number}
77+
- 作成者: {info.PullRequest.User.Login}
78+
- レビュワー: {GenerateReviewersText(info)}
5079
51-
2. **パフォーマンスに関する分析**
52-
- メモリ使用量、実行速度、スループットへの影響を具体的に記載
53-
- ベンチマーク結果や計測値がある場合は必ず含める
54-
- パフォーマンス改善の場合は、改善率や具体的な数値を記載
80+
作成者による概要:
81+
{GenerateBody(info)}
5582
56-
3. **セキュリティとバグ修正**
57-
- セキュリティ上の脆弱性修正の場合は、その重要度を明記
58-
- バグ修正の場合、修正前の問題の再現条件と修正後の動作を対比
59-
- CVE番号などのセキュリティ識別子がある場合は記載
60-
""";
83+
Copilotによる概要:
84+
{GenerateCopilotReviewText(info)}
6185
62-
public static string GeneratePrompt(PullRequestInfo info)
86+
変更ファイル:
87+
{GenerateFilesChangedText(info)}
88+
""";
89+
return prompt;
90+
}
91+
92+
private static string GenerateBody(PullRequestInfo info)
6393
{
64-
// pull reqeust info
6594
var body = info.PullRequest.Body;
6695
if (string.IsNullOrWhiteSpace(body))
6796
{
6897
body = "なし";
6998
}
99+
return body;
100+
}
70101

71-
// file changes info
72-
var files = info.Files;
73-
var filesChanged = string.Join(Environment.NewLine, files
74-
.Take(MaxFileCount)
75-
.Select(f => $"- {f.FileName} (+{f.Additions}/-{f.Deletions}, total: {f.Changes})")
76-
.Append(files.Count > MaxFileCount ? $"- その他 {files.Count - MaxFileCount} files" : ""));
77-
78-
// reviewer info
102+
private static string GenerateReviewersText(PullRequestInfo info)
103+
{
79104
var reviews = info.Reviews;
80-
var reviewersBuilder = new DefaultInterpolatedStringHandler(0, 0);
105+
var builder = new DefaultInterpolatedStringHandler(0, 0);
81106
for (int i = 0; i < reviews.Count; i++)
82107
{
83108
var pullRequestReview = reviews[i];
84-
reviewersBuilder.AppendLiteral(pullRequestReview.User.Login);
109+
builder.AppendLiteral(pullRequestReview.User.Login);
85110
if (i < reviews.Count - 1)
86111
{
87-
reviewersBuilder.AppendLiteral(", ");
112+
builder.AppendLiteral(", ");
88113
}
89114
}
90115

91-
// latest copilot overview
92-
var copilotOverview = info.Reviews.Where(r => r.User.Login == "copilot-pull-request-reviewer[bot]")
93-
.OrderByDescending(r => r.SubmittedAt)
94-
.FirstOrDefault();
95-
var overviewText = copilotOverview != null ? copilotOverview.Body.Trim() : "";
96-
if (string.IsNullOrWhiteSpace(overviewText))
116+
return builder.ToStringAndClear();
117+
}
118+
119+
private static string GenerateCopilotReviewText(PullRequestInfo pullRequestInfo)
120+
{
121+
var copilotReviews = pullRequestInfo
122+
.Reviews
123+
.Where(r =>
124+
r.User.Login == "copilot-pull-request-reviewer[bot]" &&
125+
r.Body.Length > 0 &&
126+
!r.Body.AsSpan().ContainsAny(EmptyReviewCommentSearchValues) &&
127+
!ReviewedOutOfRegex().IsMatch(r.Body)
128+
)
129+
.OrderBy(r => r.SubmittedAt)
130+
.ToArray();
131+
132+
if (copilotReviews.Length == 0) return "なし";
133+
if (copilotReviews.Length == 1) return copilotReviews[0].Body.Trim();
134+
if (copilotReviews.Length == 2) return $"{copilotReviews[0].Body.Trim()}{Environment.NewLine}{Environment.NewLine}{copilotReviews[1].Body.Trim()}";
135+
136+
var copilotReviewsSpan = copilotReviews.AsSpan();
137+
138+
// Set first review body.
139+
var builder = new DefaultInterpolatedStringHandler(0, 0);
140+
builder.AppendLiteral(copilotReviewsSpan[0].Body.Trim());
141+
142+
// Append remaining reviews with two new lines as separator, but limit total length to 10000 characters to avoid exceeding token limit.
143+
foreach (var review in copilotReviewsSpan[1..^1])
97144
{
98-
overviewText = "なし";
145+
if (builder.Text.Length > 10000)
146+
{
147+
break;
148+
}
149+
builder.AppendLiteral(Environment.NewLine);
150+
builder.AppendLiteral(Environment.NewLine);
151+
builder.AppendLiteral(review.Body.Trim());
99152
}
100153

101-
var prompt = $"""
102-
以下のdotnet/runtimeのPull Requestを要約してください。
103-
またできる限り、以下の情報以外の内容を推測して含めないようにしてください。
154+
// Append latest review.
155+
builder.AppendLiteral(Environment.NewLine);
156+
builder.AppendLiteral(Environment.NewLine);
157+
builder.AppendLiteral(copilotReviewsSpan[^1].Body.Trim());
104158

105-
Pull Request:
106-
- {info.PullRequest.Title} #{info.PullRequest.Number}
107-
- 作成者: {info.PullRequest.User.Login}
108-
- レビュワー: {reviewersBuilder.ToStringAndClear()}
109-
110-
作成者による概要:
111-
{body}
159+
return builder.ToStringAndClear();
160+
}
112161

113-
Copilotによる概要:
114-
{overviewText}
162+
private static string GenerateFilesChangedText(PullRequestInfo info)
163+
{
164+
var builder = new DefaultInterpolatedStringHandler(0, 0);
165+
foreach (var f in info.Files.Take(MaxFileCount))
166+
{
167+
builder.AppendLiteral($"- {f.FileName} (+{f.Additions}/-{f.Deletions}, total: {f.Changes})");
168+
builder.AppendLiteral(Environment.NewLine);
169+
}
115170

116-
変更ファイル:
117-
{filesChanged}
171+
var count = info.Files.Count - MaxFileCount;
172+
if (count > 0)
173+
{
174+
builder.AppendLiteral($"- その他 {count} files");
175+
}
118176

119-
""";
120-
return prompt;
177+
return builder.ToStringAndClear();
121178
}
122179
}

0 commit comments

Comments
 (0)