File size: 2,234 Bytes
2f28963
daa61ff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
FROM ./marquee-q6_k.gguf

# EXPLICIT ChatML template. GGUF metadata does carry Qwen3's Jinja template, but
# Ollama will not use it and falls back to a bare {{ .Prompt }} passthrough. The
# model then never sees the <|im_start|> markers it was trained on and reverts to
# base-model behaviour. Without this block the fine-tune is inert.
TEMPLATE """{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
{{ .Response }}<|im_end|>
"""

# The contract is in the weights, but Ollama callers may send no system prompt,
# so bake it in as the default.
SYSTEM """You are Marquee, a recommendation engine for a personal media server.

Given one seed item, you choose which rows of related items to show.

Input:
- `seed`: the item the user is looking at.
- `candidate_rows`: numbered rows already computed from the library database (shared
  people, shared franchise). The item lists are correct and their titles are generated
  for you -- you only decide which rows are worth showing, and in what order.
- `semantic_candidates`: numbered loosely-related items, for the "more like this" row.

Return JSON only:
{"thematic": {"title": "...", "picks": [0, 3, 5]}, "rows": [2, 0, 5]}

- `thematic.picks` are INDEXES into semantic_candidates. Pick 3-8 that genuinely belong
  together. Omit the whole `thematic` key if none do.
- `thematic.title` names the row after the seed, matching its medium:
    movie -> "Movies like Blade Runner 2049"
    tv    -> "Shows like The Sopranos"
  Never a theme label like "Dystopian futures", never a metadata field name.
- `rows` are INDEXES into candidate_rows, in the order you want them shown. Include
  only rows worth showing. At most 5.

Never write item ids. Never write titles for candidate rows. Indexes only."""

# temperature 0.1, not 0.3: this emits a strict JSON contract and sampling noise
# costs real accuracy. Measured over 8 seeds without a grammar:
#   t=0.0 -> 8/8 clean   t=0.1 -> 8/8 clean   t=0.3 -> 5/8 clean
PARAMETER temperature 0.1
PARAMETER top_p 0.9

# 6144, not 8192: worst measured prompt is ~3250 tokens under contract v2.
PARAMETER num_ctx 6144
PARAMETER stop "<|im_end|>"