Skip to content

feat: add one-shot ai-review reusable (Gemini/Claude, CODE/ACADEMIC)#44

Merged
toshi0806 merged 2 commits into
mainfrom
add-ai-review-reusable
Jun 8, 2026
Merged

feat: add one-shot ai-review reusable (Gemini/Claude, CODE/ACADEMIC)#44
toshi0806 merged 2 commits into
mainfrom
add-ai-review-reusable

Conversation

@toshi0806

Copy link
Copy Markdown
Member

概要

claude-code-action(エージェントループ)ベースのレビューが遅い・高い・不安定(実測: 卒論小diffで 5.4分/$0.54/投稿ゼロ)問題への根本対処。ワンショット LLM 呼び出しsmkwlab/ai-academic-paper-reviewer@v1.5(provider 抽象追加済み)を呼ぶ reusable を追加する。

実機比較: 同じ卒論 PR で one-shot 版は ~63秒・単一コメントで高品質レビューを確実に投稿(指導教員級の指摘)。

変更内容

  • .github/workflows/ai-review.yml: reusable。MODEL_CODE×REVIEW_MODE×single_comment でパラメータ化
    • model_code: claude-* → Anthropic、gemini-* → Google(自動選択)
    • review_mode: CODE(inline・バグ/ロジック)/ ACADEMIC(論文)
    • single_comment: 単一要約コメント(ACADEMIC 推奨 — 論文全体に言及する FB は inline の diff 行制約に掛かるため)
    • プロバイダのキー不在時はグレースフルスキップ、review_mode を検証
  • .github/workflows/ai-review-self.yml: 検証用 self-caller(Claude / CODE)

設計(棲み分け)

用途 仕組み
自動レビュー(code/paper) ワンショット(本 reusable) ← 速い・安い・確実
@claude 対話・修正 claude-code-action(エージェントが正解、維持)

検証

  • YAML / actionlint クリーン、check ステップのロジック(review_mode 検証・プロバイダ別キー判定)確認
  • 本 PR 自体で ai-review-self(Claude/CODE)が発火し、reusable をエンドツーエンド検証

このあと

  • 良ければ caller テンプレート(ai-code-review / ai-paper-review のプリセット)を scripts/callers/ に追加し、claude-code-review / claude-paper-review を退役してテンプレートを差し替え
  • inline モードの diff 行フィルタ堅牢化(別途)

注: GitHub の diff 行制約(API は diff 外行にコメント不可)を実機確認済み。ACADEMIC が single_comment 既定なのはこのため。

Add a reusable that runs PR review via smkwlab/ai-academic-paper-reviewer@v1.5
(a single LLM call, not an agent loop), provider- and mode-pluggable:
- model_code picks the provider (claude-* -> Anthropic, else Google)
- review_mode CODE (inline) or ACADEMIC (paper review)
- single_comment for a summary comment (recommended for ACADEMIC, which spans
  the whole document and would hit GitHub's diff-line constraint inline)
- graceful skip when the provider key is absent; review_mode is validated

This is the fast/cheap replacement for the claude-code-action based
claude-code-review / claude-paper-review (agent loop: ~5 min / $0.5+, often
posting nothing). claude-mention stays on claude-code-action.

Also add ai-review-self.yml to exercise it (Claude, CODE) on this repo's PRs.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このPRはワンショットLLM呼び出しによるAIレビューのreusable workflowを追加するものです。全体的な設計は明確で合理的ですが、いくつか重要な問題点を指摘します。

review:
runs-on: ubuntu-latest
timeout-minutes: ${{ inputs.timeout_minutes }}
if: github.event.pull_request.draft == false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [HIGH] [HIGH] if: github.event.pull_request.draft == falseworkflow_call トリガーでは機能しません。workflow_call イベントには github.event.pull_request コンテキストが存在しないため、この条件は常に false と評価され、ジョブが常にスキップされます。

ドラフトスキップのロジックは caller 側(ai-review-self.yml 等)で行うか、あるいは workflow_call の場合は条件を省略する必要があります。例えば以下のように修正できます:

if: ${{ github.event_name != 'workflow_call' || github.event.pull_request.draft == false }}

ただし workflow_call では pull_request イベント情報が引き継がれないため、caller 側で types: [opened, reopened, ready_for_review]synchronize を除く)のようにフィルタリングするのが最も確実です。

Comment thread .github/workflows/ai-review-self.yml Outdated

on:
pull_request:
types: [opened, reopened, ready_for_review]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [MEDIUM] [MEDIUM] synchronize(追加コミット時)が types に含まれていません。旧 ai-review.yml では synchronize が含まれており、PR に新しいコミットが push された際にもレビューが走っていました。意図的に除外したのであればコメントで理由を明記することを推奨します。除外しない場合は synchronize を追加してください。


- name: AI Review
if: steps.check.outputs.skip != 'true'
uses: smkwlab/ai-academic-paper-reviewer@v1.5

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [MEDIUM] [MEDIUM] smkwlab/ai-academic-paper-reviewer@v1.5 のようにバージョンをタグで固定しています。タグは mutable(上書き可能)であるため、セキュリティおよび再現性の観点から、コミット SHA で固定することが推奨されます(例: smkwlab/ai-academic-paper-reviewer@<full-sha>)。特に外部アクションを利用する場合、タグが悪意ある変更で上書きされるサプライチェーン攻撃のリスクがあります。

if: steps.check.outputs.skip != 'true'
uses: smkwlab/ai-academic-paper-reviewer@v1.5
with:
GEMINI_API_KEY: ${{ secrets.gemini_api_key }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ [LOW] [LOW] GEMINI_API_KEYANTHROPIC_API_KEY の両方を常にアクションに渡しています。使用しないプロバイダのキーも渡されるため、不要なシークレットの露出が生じます。steps.check で判定済みのプロバイダに対応するキーのみを渡す設計にすることで、最小権限の原則に沿った実装になります。

Comment thread .github/workflows/ai-review-self.yml Outdated

on:
pull_request:
types: [opened, reopened, ready_for_review]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[warning] synchronize トリガーが欠落しています。

ai-review.yml には synchronize(PR へのコミット追加)が含まれていましたが、このセルフ呼び出しには含まれていません。結果として、PR オープン後に新しいコミットを push しても再レビューがトリガーされません。

意図的にコスト削減のために省いたのであれば、コメントでその旨を明記することを推奨します。再レビューを有効にする場合は以下のように修正してください。

Suggested change
types: [opened, reopened, ready_for_review]
types: [opened, synchronize, reopened, ready_for_review]

review:
runs-on: ubuntu-latest
timeout-minutes: ${{ inputs.timeout_minutes }}
if: github.event.pull_request.draft == false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[warning] workflow_call reusable でのドラフトチェックに副作用があります。

github.event.pull_request は呼び出し元のイベントコンテキストを継承しますが、呼び出し元が pull_request 以外のイベント(例: workflow_dispatch)でトリガーされた場合、github.event.pull_requestnull になります。GitHub Actions の式評価では null.draft''(空文字列)となり、'' == falsefalse と評価されるため、ジョブがサイレントにスキップされます。

このチェックは本来呼び出し元の責務であり、reusable 側に置くと汎用性を損ないます。このチェックを呼び出し元(ai-review-self.yml)に移動し、reusable からは削除することを検討してください。


- name: AI Review
if: steps.check.outputs.skip != 'true'
uses: smkwlab/ai-academic-paper-reviewer@v1.5

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[warning] ミュータブルタグ @v1.5 へのピン留めはサプライチェーンリスクがあります。

タグは任意のコミットに移動可能なため、タグが書き換えられた場合、悪意のあるコードが ANTHROPIC_API_KEY / GEMINI_API_KEY の両方にアクセスできる状態になります。コミット SHA へのピン留めを推奨します。

Suggested change
uses: smkwlab/ai-academic-paper-reviewer@v1.5
uses: smkwlab/ai-academic-paper-reviewer@<commit-sha> # v1.5

同組織のリポジトリであり直接的な攻撃面は限られますが、CI の再現性と防御的なベストプラクティスの観点から SHA ピン留めを推奨します。

Address the AI review's valid points on #44:
- note why ai-review-self omits synchronize (cost; @claude for on-demand)
- note that the reusable's draft guard works because github.event is
  inherited from the caller's pull_request event (the review's [HIGH]
  claim that it always skips is a false positive — this PR's own run ran
  and posted, proving the guard evaluated true)
@toshi0806

Copy link
Copy Markdown
Member Author

AI レビュー指摘への対応(commit 406e26a

ワンショット AI レビューの4指摘を1件ずつ評価しました。

🚨 [HIGH] ai-review.yml:64 「draft 判定は workflow_call で機能せず常にスキップ」→ 誤検知(false positive)

workflow_callgithub コンテキストは呼び出し元の pull_request イベントから継承されるため、github.event.pull_request.draft は利用可能です。

実証:

  • 本 PR の AI Review (self) run が実際に実行され 4件投稿=job の if: draft == false は TRUE と評価された(スキップされていない)
  • 既存 claude-code-review.yml も同じ書き方で正常動作中

→ コード修正は不要。誤解防止のため、if に「github.event は caller から継承される」注記を追記。

⚠️ [MEDIUM] ai-review-self.yml:11 「synchronize 不在」→ 対応

意図的(毎push再レビューを避けるコスト判断)。提案どおり理由コメントを追記(再レビューは @claude で)。

⚠️ [MEDIUM] ai-review.yml:96 「@v1.5 は mutable タグ」→ 意図的(タグ維持)

サプライチェーンの一般論は正しいが、自前管理の内部 actionかつ org が一貫して @v1 タグ運用のため、それに合わせる。外部 action なら SHA 固定すべき点は同意。

ℹ️ [LOW] ai-review.yml:98 「両キー常時受け渡し」→ 軽微・現状維持

未使用側は空文字で action が無視するため無害。


所感: ワンショット版は速く確実に投稿し、指摘も具体的で有用でした。一方 [HIGH] が誤検知だった点は「AI レビューも人間の確認が必要」という良い実例です(自信ありげな重大指摘ほど検証する価値がある)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant