calling-the-llm-layer

Configure OpenRouter and DeepSeek LLM calls with structured output, retries, and cost control.

2|1|Updated Jun 29, 2026
One-click install
npx skills add https://github.com/frederico-kluser/newsletter-crawler --skill calling-the-llm-layer-frederico-kluser
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: calling-the-llm-layer
Source: https://github.com/frederico-kluser/newsletter-crawler/tree/main/.agents/skills/calling-the-llm-layer
Command: npx skills add https://github.com/frederico-kluser/newsletter-crawler --skill calling-the-llm-layer-frederico-kluser

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? It prevents costly mistakes when working with the newsletter crawler's LLM layer: invalid reasoning efforts that trigger HTTP 400 errors, stale API keys causing 401s, runaway classification costs, and pipeline starvation from prompts that return oversized outputs. ## Core Features & Use Cases - Provider and model configuration: Covers the OpenRouter vs direct DeepSeek transport split, model slug translation, reasoning effort levels (xhigh/high/medium, never max), and the two-tier Pro/Flash stage strategy. - Structured output discipline: Documents the json_schema strict plus zod validation pattern, defensive JSON parsing with retry and Pro escalation, and the small-output rule for high-volume stages. - Cost and reliability patterns: Explains per-facet classification cost traps, batch relevance judging with tolerant id merging, per-section roundup curation, local cost computation for the direct API, and the .env key override plus runtime live-binding gotchas. - Use Case: When a crawl suddenly returns 401 errors or a new LLM stage ignores its models.json entry, consult this Skill to find the live-binding key fix or the missing STAGE_KEYS registration. ## Quick Start Ask the AI to review your change to src/llm.js using the calling-the-llm-layer skill before modifying any prompt, schema, reasoning effort, or model.

Frequently Asked Questions about calling-the-llm-layer

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I choose the right reasoning effort for DeepSeek or OpenRouter calls?

Use xhigh for the Pro tier and high for Flash, with medium acceptable for mechanical stages. Never use max, which returns HTTP 400 on OpenRouter; a guard downgrades it to xhigh. On the direct DeepSeek API the reasoning parameter is omitted entirely.

How do I add structured JSON output with validation to an LLM call?

Set response_format to json_schema with strict:true and validate the result with zod. On the direct DeepSeek provider it degrades to json_object, so zod clamps and deterministic backstops remain the safety net. callJSON retries on the same model and escalates to Pro on the final attempt.

Why does my OpenRouter API key return 401 User not found?

The config loads the repo .env and then NC_HOME/.env, which override shell variables, so a stale exported key wins. Probe the key with curl against https://openrouter.ai/api/v1/key, and use setRuntimeKey or the key command to update it without restarting.

OpenRouter vs direct DeepSeek API: what changes in the request?

The direct provider switches the base URL to api.deepseek.com, omits OpenRouter-only parameters like reasoning and usage include, and degrades json_schema to json_object. Cost is computed locally from a price table since the direct API returns no usage.cost field.

Why is my LLM classification stage consuming most of the crawl budget?

Multi-facet classification makes one call per facet per article, and running many facets on Pro with the full article body re-sent each time is expensive. Restrict Pro to core facets, use Flash with medium effort for the rest, and cap input with CLASSIFY_MAX_CHARS.

Why did my new LLM stage ignore its models.json configuration?

A new stage must be registered in STAGE_KEYS in src/config.js, otherwise stageModel falls back to the default Pro with xhigh effort and the models.json entry is silently ignored. This was verified at runtime with the articleReclean stage.