better prompting, add channel id checking

This commit is contained in:
localhost 2026-03-02 22:02:19 +01:00
parent a728e4142c
commit 27e3181553
2 changed files with 32 additions and 11 deletions

View File

@ -135,7 +135,8 @@ app.ws('/save', {
} }
const slopScore = await parseSlop(videoId, data.videoDetails.title, const slopScore = await parseSlop(videoId, data.videoDetails.title,
(data.microformat.playerMicroformatRenderer.description?.simpleText || '').replaceAll('\n', '<br>')) (data.microformat.playerMicroformatRenderer.description?.simpleText || '').replaceAll('\n', '<br>'),
data.videoDetails.channelId)
if (slopScore >= 4) { if (slopScore >= 4) {
sendError(ws, 'Filters can always be wrong. Is the rating wrong? Email me at admin@preservetube.com', false); sendError(ws, 'Filters can always be wrong. Is the rating wrong? Email me at admin@preservetube.com', false);
@ -215,7 +216,8 @@ app.ws('/savechannel', {
break; break;
} }
const slopScore = await parseSlop(video.video_id, video.title.text, video.description_snippet?.text || '') const slopScore = await parseSlop(video.video_id, video.title.text,
video.description_snippet?.text || '', channelId)
if (slopScore >= 4) { if (slopScore >= 4) {
sendError(ws, 'Filters can always be wrong. Is the rating wrong? Email me at admin@preservetube.com', false); sendError(ws, 'Filters can always be wrong. Is the rating wrong? Email me at admin@preservetube.com', false);

View File

@ -1,5 +1,22 @@
import redis from '@/utils/redis'; import redis from '@/utils/redis';
const channelBlacklist = [
'UCR7d_LMsADXorkUF5fkcEHQ',
'UCgcX8KN9tjesfSg1KYW8JMA',
'UCRbV62Z7jv5j9WHdjCQT4BQ',
'UCErCs-HgXDfj_79jbWO8SqA',
'UClt1wsBuiIJS8_RoAFlkSlQ',
'UCviJ2KzLw4W7zRNzPv6FLbA',
'UCUQmW2YLzhEmMTqO0RAPlOw',
'UCtmnjVU-u1B7vX-XDhuvExA',
'UCgcX8KN9tjesfSg1KYW8JMA',
'UCh8VpxMSRm-JoogNpCFHbMw',
'UCUQmW2YLzhEmMTqO0RAPlOw',
'UC4Anp9y2TU-d5blFUf7wCqw',
'UC-TaLb_bURExFdLFXkJ3Adg',
'UC1XgosSxwK9xtrMLsRzCbHw'
]
async function analyseSlop(id: string, title: string, description: string) { async function analyseSlop(id: string, title: string, description: string) {
const llmResponse = await (await fetch('https://nano-gpt.com/api/v1/chat/completions', { const llmResponse = await (await fetch('https://nano-gpt.com/api/v1/chat/completions', {
method: 'POST', method: 'POST',
@ -29,20 +46,20 @@ Use these as intuition guides, not a checklist. Weight them by how many stack to
- **Pipe separators** (|) splitting title into the classic pattern of caption | source | song only a signal when used to stack multiple slop elements (e.g. character | show | slowed song). A single pipe for emphasis or listing does not count. - **Pipe separators** (|) splitting title into the classic pattern of caption | source | song only a signal when used to stack multiple slop elements (e.g. character | show | slowed song). A single pipe for emphasis or listing does not count.
- **4K / [4K] tag** almost always slop when paired with anything else. - **4K / [4K] tag** almost always slop when paired with anything else.
- **"Edit" / "OneShot" / "Morphosis"** suffix or delimiter usage ( Edit , Edit). - **"Edit" / "OneShot" / "Morphosis"** suffix or delimiter usage ( Edit , Edit).
- **Slowed / Reverb / Slowed+Reverb / MONTAGEM** not a signal on its own. Only counts when stacked with other slop signals. - **Slowed / Reverb / Slowed+Reverb / MONTAGEM** only counts when stacked with others
- **Known slop franchises:** Johnny English, Mr. Bean, Breaking Bad, Peaky Blinders, American Psycho, Patrick Bateman, The Boys, Homelander, Dexter, Joe Goldberg, Squid Game, Rick Grimes, Thomas Shelby, John Wick, Kingsman, and similar. - **Known slop franchises:** This list is definitive, not illustrative. Only the following qualify: Johnny English, Mr. Bean, Breaking Bad, Peaky Blinders, American Psycho, Patrick Bateman, The Boys, Homelander, Dexter, Joe Goldberg, Squid Game, Rick Grimes, Thomas Shelby, John Wick, Kingsman.
- **Song name explicitly in title** especially if slowed/remixed. - **Song name explicitly in title** especially if slowed/remixed.
- **Description** if it contains hashtag spam, "subscribe," "no copyright," or music credits it reinforces slop signals from the title. - **Description** if it contains hashtag spam, or music credits it reinforces slop signals from the title.
- **Tutorials and how-to videos** score 0, always.
- **Scenes or cut fragments from shows or movies** only applies when the title explicitly states it is a scene or clip from a specific, named and widely-known show or movie. Score 4. Fan animations or original artwork inspired by a franchise do not trigger this.
- **Clickbait** is its own category and does not affect the slop score. - **Clickbait** is its own category and does not affect the slop score.
### EXCEPTIONS ### EXCEPTIONS
- If the content is "lost" or an archived version, the score is always 0, regardless of other signals. - Tutorials, news, commentary, politics score 0 automatically
- Slop only applies to video edits fan edits, character edits, movie/show clips with trending audio, and similar derivative media. News, commentary, opinion, or political content is never slop regardless of how sensationalized the title is. Score these 0. - Lost/archived content score 0 automatically
- Fan animations/original franchise-inspired art do not trigger slop
- Direct movie/TV clips or scenes uploaded without transformative editing score 4 automatically
### OUTPUT ### OUTPUT
Valid JSON only. No other text. Reasoning max one sentence, and brief. Valid JSON only. No other text. One sentence reasoning max, be brief. Use your judgment if multiple signals stack logically toward slop, score accordingly. Do not assume content type beyond what title explicitly states.
{"score": 0, "reasoning": "..."} {"score": 0, "reasoning": "..."}
@ -65,7 +82,9 @@ User Description: ${description.slice(0,100)}` }
return parsedResponse return parsedResponse
} }
async function parseSlop(id: string, title: string, description: string): Promise<number> { async function parseSlop(id: string, title: string, description: string, channelId: string): Promise<number> {
if (channelBlacklist.includes(channelId)) return 5;
const cachedSlop = await redis.get(`slop:${id}`) const cachedSlop = await redis.get(`slop:${id}`)
if (cachedSlop) return parseInt(cachedSlop) if (cachedSlop) return parseInt(cachedSlop)