Skip to content

Implement AI moderator workflow with spam detection and comment minimization - #5907

Merged
pelikhan merged 14 commits into
mainfrom
copilot/implement-ai-moderator-features
Dec 9, 2025
Merged

Implement AI moderator workflow with spam detection and comment minimization#5907
pelikhan merged 14 commits into
mainfrom
copilot/implement-ai-moderator-features

Conversation

Copilot AI commented Dec 8, 2025

Copy link
Copy Markdown
Contributor

Implementation Plan: AI Moderator Workflow ✅

Creating an agentic workflow that replicates the github/ai-moderator features:

  • Create workflow markdown file (ai-moderator.md)
    • Configure triggers (issues, comments, PR review comments, workflow_dispatch)
    • Set appropriate permissions (using defaults)
    • Configure safe-outputs for labeling and minimizing
    • Use built-in minimize-comment safe output
    • Add documentation as XML comment in workflow file
    • Skip workflow for team members (admin/maintainer/write access)
    • Support custom moderation prompts (markdown format)
    • Support manual workflow_dispatch with issue URL input
  • Implement spam detection logic
    • Generic spam detection (promotional, scams, irrelevant)
    • Link spam detection (suspicious URLs, short links)
    • AI-generated content detection
    • Optional custom prompt from .github/prompts/custom-moderation.md
  • Create prompts for each detection type
    • Embed prompts in workflow body with clear analysis criteria
    • Define spam indicators and guidelines
    • Use needs.activation.outputs.text for content (marked as unsafe_user_input)
  • Configure output actions
    • Add labels for detected spam types (spam, ai-generated, link-spam)
    • Use built-in minimize-comment safe output (max: 5)
  • Compile and validate workflow
    • Run gh aw compile ai-moderator with strict mode
    • Verify generated lock file (343.8 KB)
  • Documentation
    • Moved as XML comment in workflow file
    • Document features, configuration, and customization
    • Add comparison with original github/ai-moderator
    • Add label creation instructions (UI, CLI, API)
    • Add custom prompt file documentation with markdown examples

Key Features

Built-in Safe Outputs

Uses gh-aw's built-in minimize-comment safe output for comment moderation, eliminating the need for custom GraphQL code.

Team Member Optimization

The workflow automatically skips spam detection for repository team members (users with admin, maintainer, or write access) to optimize resource usage:

  • Includes a custom check_external_user job that checks user permissions via GitHub API
  • Skips the agent job (and spam detection) for team members
  • Only runs for external users (read access or non-collaborators)
  • Workflow_dispatch always runs (manual triggers bypass team member check)
  • Team members' content is trusted and not scanned

Custom Moderation Prompts

Supports optional custom moderation rules via .github/prompts/custom-moderation.md:

  • Simple markdown format for easy editing
  • AI agent reads the file as additional system prompt instructions
  • Allows repository-specific spam detection criteria
  • Combines custom rules with built-in detection tasks

Example custom moderation file:

# Custom Moderation Rules

Additional spam indicators for this repository:
- Posts mentioning competitor products (CompetitorX, CompetitorY)
- Off-topic gaming discussions (this is a development tools project)
- Cryptocurrency or blockchain mentions (not relevant to this project)
- Generic "me too" comments without substance
- Links to specific domains we don't allow: example-spam-site.com

Manual Moderation via workflow_dispatch

Allows manual triggering to moderate specific content:

  • Supports workflow_dispatch with issue_url input parameter
  • Can provide any issue or discussion URL to analyze
  • Useful for retroactively checking content or moderating specific posts
  • Always runs for manual triggers (bypasses team member check)

Security

  • User-provided content marked with <unsafe_user_input> XML tags for clarity
  • Content automatically sanitized by activation job before reaching agent
  • Uses default permissions (minimal access)
  • Safe-outputs for all write operations

Changes Summary

  • Consolidated documentation into the workflow file as an XML comment
  • Used built-in minimize-comment safe output instead of custom implementation
  • Added intelligent team member detection to skip unnecessary scans
  • Added support for custom moderation prompts (simple markdown format)
  • Added workflow_dispatch support for manual moderation
  • Workflow only processes content from external users for efficiency
  • Uses needs.activation.outputs.text for content (auto-fetched by framework)
  • Marked user content with unsafe_user_input XML tags for security clarity
  • Removed unnecessary permissions block (uses defaults)
  • Removed unnecessary tools

Custom agent used: create-agentic-workflow
Design agentic workflows using GitHub Agentic Workflows (gh-aw) extension with interactive guidance on triggers, tools, and security best practices.

Custom agent used: create-agentic-workflow
Design agentic workflows using GitHub Agentic Workflows (gh-aw) extension with interactive guidance on triggers, tools, and security best practices.

Custom agent used: create-agentic-workflow
Design agentic workflows using GitHub Agentic Workflows (gh-aw) extension with interactive guidance on triggers, tools, and security best practices.

Custom agent used: create-agentic-workflow
Design agentic workflows using GitHub Agentic Workflows (gh-aw) extension with interactive guidance on triggers, tools, and security best practices.

Original prompt

Create an agentic workflow that implements the same features as https://github.com/github/ai-moderator

Custom agent used: create-agentic-workflow
Design agentic workflows using GitHub Agentic Workflows (gh-aw) extension with interactive guidance on triggers, tools, and security best practices.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits December 8, 2025 21:43
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement features from ai-moderator project Implement AI moderator workflow with spam detection and comment minimization Dec 8, 2025
Copilot AI requested a review from pelikhan December 8, 2025 22:04
@pelikhan

pelikhan commented Dec 8, 2025

Copy link
Copy Markdown
Collaborator

@copilot use minimize-comment safe output type instead of custom job

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Dec 8, 2025

Copy link
Copy Markdown
Contributor Author

@copilot use minimize-comment safe output type instead of custom job

Updated to use the built-in minimize-comment safe output type instead of a custom job. The workflow now uses the simpler configuration:

safe-outputs:
  minimize-comment:
    max: 5

This eliminates ~80 lines of custom GraphQL code and provides a cleaner API for the AI agent.

Commit: dd4b0e1

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot move readme as xml comment in ai-moderator.md

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved README content as an XML comment at the end of ai-moderator.md and deleted the separate README-ai-moderator.md file.

Commit: 04e8339

Comment thread .github/workflows/ai-moderator.md Outdated
Comment on lines +109 to +133
## How to fetch the Node ID

If you need to minimize a comment, you'll need its GraphQL node ID. You can fetch this using the GitHub MCP server tools:

**For issue comments**, use the GitHub REST API to get the comment:
```
GET /repos/<owner>/<repo>/issues/comments/<comment_id>
```
Replace `<owner>`, `<repo>`, and `<comment_id>` with actual values from your workflow context.
The response will include a `node_id` field.

**For PR review comments**, use:
```
GET /repos/<owner>/<repo>/pulls/comments/<comment_id>
```
Replace `<owner>`, `<repo>`, and `<comment_id>` with actual values.
The response will include a `node_id` field.

The node ID is a base64-like encoded string used by GitHub's GraphQL API (e.g., `IC_kwDOABcD1M5ZJfGH`).

Once you have the node ID, call the minimize_comment tool:
```
minimize_comment(comment_id="IC_kwDOABcD1M5ZJfGH")
```

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot this section is automatically handled by the minimize-comment tool, remove

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed the "How to fetch the Node ID" section. The minimize-comment tool handles GraphQL node ID fetching automatically.

Commit: 16bc26d

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan

pelikhan commented Dec 8, 2025

Copy link
Copy Markdown
Collaborator

@copilot Add a custom step in the pre-activation job that skips the workflow is the actor is owner/maintainer/write access since we don't need to scan team member messages.

@pelikhan

pelikhan commented Dec 8, 2025

Copy link
Copy Markdown
Collaborator

@copilot add an optional import in the prompt body to include custom moderation prompt. Use the same file location as in the original actions/ai-moderator action.

- Remove "How to fetch the Node ID" section (handled automatically by minimize-comment tool)
- Add roles: all to allow all users to trigger the workflow
- Add custom check_external_user job to skip workflow for team members (admin/maintain/write)
- Add if condition to agent job to only run for external users

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Dec 8, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Add a custom step in the pre-activation job that skips the workflow is the actor is owner/maintainer/write access since we don't need to scan team member messages.

Added custom check_external_user job that skips the workflow for users with owner/maintainer/write access. The workflow now:

  • Sets roles: all to allow all users to trigger it
  • Adds a custom job that checks user permissions via GitHub API
  • Skips the agent job (and spam detection) for team members
  • Only runs for external users (read access or non-collaborators)

This optimizes resources by not scanning content from trusted team members.

Commit: 16bc26d

- Add optional custom prompt file support at .github/prompts/custom-moderation.prompt.yml
- Follows same YAML format as original github/ai-moderator action
- AI agent checks if file exists and applies additional rules if present
- Updated documentation with example custom prompt configuration

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Dec 9, 2025

Copy link
Copy Markdown
Contributor Author

@copilot add an optional import in the prompt body to include custom moderation prompt. Use the same file location as in the original actions/ai-moderator action.

Added support for optional custom moderation prompts. The workflow now:

  • Checks for a custom prompt file at .github/prompts/custom-moderation.prompt.yml (same location as original ai-moderator)
  • Uses the same YAML format with messages, model, responseFormat, and jsonSchema
  • AI agent reads and applies custom rules if the file exists
  • Combines custom rules with built-in detection tasks

Updated documentation includes an example custom prompt showing the format.

Commit: 45dd92d

Comment thread .github/workflows/ai-moderator.md Outdated
allowed: [spam, ai-generated, link-spam]
minimize-comment:
max: 5
roles: all

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot

  • remove roles: all line

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed roles: all line.

Commit: ba802a6

Comment thread .github/workflows/ai-moderator.md
Comment thread .github/workflows/ai-moderator.md Outdated
engine: copilot
if: needs.check_external_user.outputs.is_external == 'true'
tools:
github:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot disable GitHub

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed GitHub tools configuration.

Commit: ba802a6

Comment thread .github/workflows/ai-moderator.md Outdated
Comment thread .github/workflows/ai-moderator.md Outdated

For issues, the issue title is: ${{ github.event.issue.title }}

The content body to analyze is available through the GitHub context. Use the GitHub tools to fetch the full context of the issue, comment, or pull request review comment that triggered this workflow.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot use the needs.activation.outputs.text value

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated to use needs.activation.outputs.text for content. The activation job auto-fetches content from the appropriate event context.

Commit: ba802a6

Comment thread .github/workflows/ai-moderator.md Outdated

**Content to analyze**:

For issues, the issue title is: ${{ github.event.issue.title }}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot remove entry

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed the issue title line.

Commit: ba802a6


Analyze the following content that was just posted in repository ${{ github.repository }}:

**Issue Number** (if applicable): #${{ github.event.issue.number }}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot use template conditionals

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Simplified context display to show all fields directly (Issue Number, PR Number, Comment ID, Author, Manual URL). Content now comes from needs.activation.outputs.text.

Commit: ba802a6

@pelikhan

pelikhan commented Dec 9, 2025

Copy link
Copy Markdown
Collaborator

@copilot simplify custom prompt to just markdown

@pelikhan

pelikhan commented Dec 9, 2025

Copy link
Copy Markdown
Collaborator

@copilot do not use import to read the custom rules, tell the agent to read these instruction as system prompt.

- Remove roles: all line (comment 2600564134)
- Add workflow_dispatch support with issue_url input (comment 2600564504)
- Remove GitHub tools (comment 2600565242)
- Remove models: read permission (comment 2600565644)
- Use needs.activation.outputs.text for content (comment 2600568773)
- Remove issue title line (comment 2600569278)
- Simplify context info display (comment 2600569830)
- Workflow_dispatch always runs (no team member check for manual triggers)

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

**Content to analyze**:

${{ needs.activation.outputs.text }}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot enclose line in xml tags "unsafe_user_input"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Enclosed the line with <unsafe_user_input> XML tags to mark user-provided content.

Commit: 96aa199

Comment thread .github/workflows/ai-moderator.md Outdated
**Pull Request Number** (if applicable): #${{ github.event.pull_request.number }}
**Comment ID** (if applicable): ${{ github.event.comment.id }}
**Author**: ${{ github.actor }}
**Manual URL** (if workflow_dispatch): ${{ github.event.inputs.issue_url }}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot use conditional templates

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated to "if provided via workflow_dispatch" for better clarity about when this field is populated.

Commit: 96aa199

- Change custom prompt file from .yml to .md (comment 3629579123)
- Instruct agent to read file as system prompt instead of importing (comment 3629581953)
- Use simple markdown format instead of complex YAML structure
- Updated documentation with markdown example

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Dec 9, 2025

Copy link
Copy Markdown
Contributor Author

@copilot do not use import to read the custom rules, tell the agent to read these instruction as system prompt.

Updated to instruct the agent to read the custom moderation file as additional system prompt instructions, rather than using import logic. The agent now simply reads .github/prompts/custom-moderation.md and applies the rules directly.

Commit: 5777d9b

@copilot simplify custom prompt to just markdown

Simplified custom prompt to markdown format. Changed from .github/prompts/custom-moderation.prompt.yml (YAML) to .github/prompts/custom-moderation.md (markdown).

Commit: 5777d9b

- Enclose needs.activation.outputs.text in unsafe_user_input XML tags (comment 2600594358)
- Update Manual URL description to be more descriptive (comment 2600595146)

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Comment thread .github/workflows/ai-moderator.md Outdated
description: 'Issue or discussion URL to moderate (e.g., https://github.com/owner/repo/issues/123)'
required: true
type: string
permissions:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@copilot no need for any permissions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed the permissions block. The workflow now uses default permissions.

Commit: e43d236

- Remove all permissions (comment 2600673054)
- Workflow will use default permissions

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI requested a review from pelikhan December 9, 2025 01:04
@pelikhan
pelikhan marked this pull request as ready for review December 9, 2025 02:07
@pelikhan
pelikhan merged commit 81b9380 into main Dec 9, 2025
5 checks passed
@pelikhan
pelikhan deleted the copilot/implement-ai-moderator-features branch December 9, 2025 02:07
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.

2 participants