- Added optional `thinking_budget` parameter to `config.yaml` for Gemini model, allowing for reserved thinking tokens. - Updated `LlmSettings` class in `config.py` to include `thinking_budget` and adjusted parsing logic accordingly. - Modified LLM call logic in `llm.py` to utilize `thinking_budget` for calculating `max_output_tokens`, improving output management.
111 lines
5.7 KiB
YAML
111 lines
5.7 KiB
YAML
# ── LLM configuration ─────────────────────────────────────────────────────────
|
|
# Two independent profiles, one per pipeline stage. Each accepts the same keys:
|
|
# provider: openai | anthropic | gemini
|
|
# openai_model / anthropic_model / gemini_model / max_tokens / temperature
|
|
# thinking_budget (optional, Gemini only): reserved thinking tokens. When set,
|
|
# Gemini's max_output_tokens is max_tokens + thinking_budget, so max_tokens
|
|
# is the visible-output budget. Omit it to keep max_tokens as the shared cap.
|
|
llm:
|
|
# Part_One: vector-search query synthesis (small structured JSON in,
|
|
# 1-2 short queries out). A lighter/cheaper model is sufficient here.
|
|
query_synthesis:
|
|
provider: gemini
|
|
openai_model: gpt-4o-mini
|
|
anthropic_model: claude-haiku-4-5
|
|
gemini_model: gemini-2.5-flash
|
|
max_tokens: 8192
|
|
temperature: 0.0
|
|
|
|
# Part_Two: the farmer-facing advisory generator. Receives the full
|
|
# json_for_advice_generation payload (weather, phenology, model output,
|
|
# applied treatments, product labels) and returns the structured advice
|
|
# JSON stored in the advice table. Needs a more capable model.
|
|
advice_generation:
|
|
provider: gemini
|
|
openai_model: gpt-4o
|
|
anthropic_model: claude-opus-4-5
|
|
gemini_model: gemini-2.5-pro
|
|
max_tokens: 4096
|
|
thinking_budget: 9216
|
|
temperature: 0.0
|
|
|
|
# ── Crop-first worklist ────────────────────────────────────────────────────────
|
|
# `python -m pipeline batch` discovers jobs from this list: for every crop, it
|
|
# finds all fields growing it (AI_agrosupport_cmp_layers ⨝ an_colture) that also
|
|
# have a matching row in AI_agrosupport_agro_models for each listed disease's
|
|
# model_name, and runs the full single-field pipeline for every resulting
|
|
# (field, disease) pair. `disease` is the canonical English name used for the
|
|
# product prefilter, the vector search, and the advice/prompt lookup; it must
|
|
# exist in vocab/diseases.yaml. `model_name` is matched (case-insensitively)
|
|
# against AI_agrosupport_agro_models.anmod_model.
|
|
#
|
|
# Each crop-disease pair needs a matching prompt directory under
|
|
# prompts/advice/<crop>__<disease slug>/ (see prompts/README or the pipeline
|
|
# README for the exact slug rules); pairs without one fall back to
|
|
# prompts/advice/_default/ and are logged at startup.
|
|
crops:
|
|
- crop: grapevine
|
|
diseases:
|
|
- model_name: PERONOSPORA
|
|
disease: downy mildew
|
|
|
|
# ── Worklist filters ───────────────────────────────────────────────────────────
|
|
worklist:
|
|
# AI_agrosupport_agro_models.anmod_enabled is True for every model row in the
|
|
# current database; keep this on so a disabled model never generates advice.
|
|
require_enabled_model: true
|
|
# Restrict the batch to specific field IDs while testing; empty = no filter.
|
|
field_allowlist: []
|
|
|
|
# ── Concurrency & rate limiting ────────────────────────────────────────────────
|
|
# One "gemini" budget covers both direct LLM calls (query synthesis, advice
|
|
# generation) and Weaviate near_text search, because the ProductProfile
|
|
# collection is vectorised with text2vec-palm (gemini-embedding-001) using the
|
|
# same GEMINI_API_KEY — they share one quota.
|
|
concurrency:
|
|
workers: 8
|
|
limits:
|
|
sql: 6
|
|
gemini: 4
|
|
gemini_requests_per_minute: 60
|
|
|
|
# ── Retry policy for transient LLM / Weaviate / SQL failures ──────────────────
|
|
retry:
|
|
attempts: 3
|
|
initial_backoff_seconds: 2
|
|
max_backoff_seconds: 30
|
|
|
|
# ── Daily SLA ───────────────────────────────────────────────────────────────────
|
|
# The batch must not still be running after this local time; jobs not yet
|
|
# started by then are skipped (status skipped_deadline) rather than risking a
|
|
# late advisory. Schedule the run itself no earlier than ~07:00 so weather is
|
|
# fresh (see README).
|
|
schedule:
|
|
deadline: "09:00"
|
|
|
|
# ── Single-field debug mode (`python -m pipeline one`) ────────────────────────
|
|
# Not used by `batch`; kept for ad-hoc single-field runs and debugging.
|
|
field_id: 4012
|
|
disease_name: "PERONOSPORA"
|
|
|
|
# ── Vocabulary paths ──────────────────────────────────────────────────────────
|
|
vocab:
|
|
crops: vocab/crops.yaml
|
|
diseases: vocab/diseases.yaml
|
|
|
|
# ── Observability (optional; off by default) ──────────────────────────────────
|
|
# Sends OpenTelemetry/OpenInference spans to the self-hosted Phoenix container
|
|
# in docker-compose.yml (http://localhost:6006). Never required: if this is
|
|
# off, or Phoenix is down/unreachable, `batch` and `one` run exactly as if
|
|
# this block did not exist (see pipeline/observability.py).
|
|
observability:
|
|
enabled: false
|
|
project_name: ai-agro-support
|
|
endpoint: http://localhost:6006/v1/traces
|
|
# Keep prompt/payload text out of Phoenix spans. json_for_advice_generation
|
|
# carries the full product-label payload and is already persisted under
|
|
# output/<date>/*.json; spans only need model/token/status metadata.
|
|
hide_prompts: true
|
|
# Hard cap on every exported string attribute (OTel span attribute limit).
|
|
max_attribute_chars: 4096
|