feat(livia): Modell und Textlänge über Umgebungsvariablen einstellbar
Das Modell stand fest im Code, obwohl es die grösste Kostenstellschraube ist — ein Lauf über fünfzig Meldungen kostet mit Opus 5 rund 0.40 USD, mit Haiku 4.5 etwa 0.08. Wer die Anwendung betreibt, soll diese Abwägung treffen können, ohne den Quelltext anzufassen und neu zu deployen. `LIVIA_RESEARCH_MODEL` wählt das Modell, `LIVIA_RESEARCH_TEXT_LIMIT` die Menge Artikeltext je Meldung — der zweite grosse Hebel, weil der Immobilienbezug einer Firmenmeldung fast immer im ersten Absatz steht und jede Halbierung die Eingabekosten halbiert. Beide haben Vorgabewerte; ohne gesetzte Variablen verhält sich alles wie bisher. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
e986e9f274
commit
c19f071acc
1 file changed
+25
-2
@@ -90,6 +90,29 @@ function extractJson(text: string): unknown {
|
|||||||
*/
|
*/
|
||||||
const BATCH_SIZE = 5
|
const BATCH_SIZE = 5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Welches Modell die Einordnung vornimmt.
|
||||||
|
*
|
||||||
|
* Über `LIVIA_RESEARCH_MODEL` umstellbar, ohne den Code anzufassen — die
|
||||||
|
* Wahl ist eine Kosten- und Qualitätsabwägung und gehört damit dem Betreiber,
|
||||||
|
* nicht dem Quelltext.
|
||||||
|
*
|
||||||
|
* Grössenordnung je Lauf über rund fünfzig Meldungen:
|
||||||
|
* claude-opus-5 ≈ 0.40 USD stärkstes Urteil
|
||||||
|
* claude-sonnet-5 ≈ 0.20 USD
|
||||||
|
* claude-haiku-4-5 ≈ 0.08 USD für eine Ja/Nein-Einordnung meist ausreichend
|
||||||
|
*/
|
||||||
|
const MODEL = process.env.LIVIA_RESEARCH_MODEL ?? 'claude-opus-5'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wie viel Artikeltext das Modell zu lesen bekommt.
|
||||||
|
*
|
||||||
|
* Ebenfalls umstellbar, weil es der zweite grosse Kostenhebel ist: Der
|
||||||
|
* Immobilienbezug einer Firmenmeldung steht fast immer im ersten Absatz, und
|
||||||
|
* jede Halbierung halbiert die Eingabekosten.
|
||||||
|
*/
|
||||||
|
const TEXT_LIMIT = Number(process.env.LIVIA_RESEARCH_TEXT_LIMIT ?? 2000)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wie viele Teilstapel gleichzeitig beurteilt werden.
|
* Wie viele Teilstapel gleichzeitig beurteilt werden.
|
||||||
*
|
*
|
||||||
@@ -116,12 +139,12 @@ async function analyzeBatch(
|
|||||||
`Quelle: ${it.source}`,
|
`Quelle: ${it.source}`,
|
||||||
`Titel: ${it.title}`,
|
`Titel: ${it.title}`,
|
||||||
it.publishedAt ? `Publiziert: ${it.publishedAt}` : '',
|
it.publishedAt ? `Publiziert: ${it.publishedAt}` : '',
|
||||||
`Text: ${it.text.slice(0, 2000)}`,
|
`Text: ${it.text.slice(0, TEXT_LIMIT)}`,
|
||||||
].filter(Boolean).join('\n'))
|
].filter(Boolean).join('\n'))
|
||||||
.join('\n\n')
|
.join('\n\n')
|
||||||
|
|
||||||
const response = await client.messages.create({
|
const response = await client.messages.create({
|
||||||
model: 'claude-opus-5',
|
model: MODEL,
|
||||||
max_tokens: 8000,
|
max_tokens: 8000,
|
||||||
system: SYSTEM_PROMPT,
|
system: SYSTEM_PROMPT,
|
||||||
// Einordnen ist bei fünf Einträgen eine Routineaufgabe — die niedrige Stufe
|
// Einordnen ist bei fünf Einträgen eine Routineaufgabe — die niedrige Stufe
|
||||||
|
|||||||
Reference in new issue
Block a user