datawhalechina/hello-agents · critical · ValueError

请在 .env 中配置 LLM_MODEL_ID, LLM_API_KEY, LLM_BASE_URL

Error message

请在 .env 中配置 LLM_MODEL_ID, LLM_API_KEY, LLM_BASE_URL

What it means

HelloAgentsLLM.__init__ raises ValueError when any of model id, API key, or base URL is missing after checking constructor args and the LLM_MODEL_ID / LLM_API_KEY / LLM_BASE_URL environment variables (loaded via python-dotenv from .env). It is a startup-time configuration guard: the OpenAI client cannot be constructed meaningfully without all three.

Source

Thrown at Co-creation-projects/CC1227871-StockInsightAgent/llm_client.py:19

"""Step 1: LLM 客户端 — 兼容 OpenAI 接口,支持流式响应"""
import os
from openai import OpenAI
from dotenv import load_dotenv
from typing import List, Dict

load_dotenv()


class HelloAgentsLLM:
    def __init__(self, model: str = None, apiKey: str = None,
                 baseUrl: str = None, timeout: int = None):
        self.model = model or os.getenv("LLM_MODEL_ID")
        apiKey = apiKey or os.getenv("LLM_API_KEY")
        baseUrl = baseUrl or os.getenv("LLM_BASE_URL")
        timeout = timeout or int(os.getenv("LLM_TIMEOUT", 60))

        if not all([self.model, apiKey, baseUrl]):
            raise ValueError("请在 .env 中配置 LLM_MODEL_ID, LLM_API_KEY, LLM_BASE_URL")

        self.client = OpenAI(api_key=apiKey, base_url=baseUrl, timeout=timeout)

    def think(self, messages: List[Dict[str, str]], temperature: float = 0) -> str:
        print(f"\n[{self.model}] 思考中...")
        try:
            response = self.client.chat.completions.create(
                model=self.model, messages=messages,
                temperature=temperature, stream=True,
            )
            collected = []
            for chunk in response:
                if not chunk.choices:
                    continue
                content = chunk.choices[0].delta.content or ""
                # 过滤无效代理字符 (surrogates)
                clean = content.encode("utf-8", errors="surrogateescape").decode("utf-8", errors="replace")
                print(clean, end="", flush=True)

View on GitHub (pinned to 606a07d341)

Solutions

  1. Create a .env next to the project root / the directory you run from, defining LLM_MODEL_ID, LLM_API_KEY and LLM_BASE_URL.
  2. Or export the three variables in the shell/container environment before starting the app.
  3. Alternatively pass them explicitly: HelloAgentsLLM(model='...', apiKey='...', baseUrl='...').
  4. Verify with: python -c "import os; from dotenv import load_dotenv; load_dotenv(); print([k for k in ('LLM_MODEL_ID','LLM_API_KEY','LLM_BASE_URL') if not os.getenv(k)])" — an empty list means fixed.

Example fix

# before: no .env
client = HelloAgentsLLM()  # ValueError

# after: .env contains
# LLM_MODEL_ID=gpt-4o-mini
# LLM_API_KEY=sk-...
# LLM_BASE_URL=https://api.openai.com/v1
client = HelloAgentsLLM()
Defensive patterns

Strategy: validation

Validate before calling

import os
from dotenv import load_dotenv
load_dotenv()
missing = [k for k in ('LLM_MODEL_ID', 'LLM_API_KEY', 'LLM_BASE_URL') if not os.getenv(k)]
assert not missing, f'missing env vars: {missing}'
client = HelloAgentsLLM()

Try / catch

try:
    client = HelloAgentsLLM()
except ValueError as e:
    if 'LLM_MODEL_ID' in str(e):
        sys.exit('Configuration incomplete: create .env with LLM_MODEL_ID, LLM_API_KEY, LLM_BASE_URL')

Prevention

When it happens

Trigger: Instantiating HelloAgentsLLM() with no .env file in the working directory, a .env missing one of the three variables, or a variable set to an empty string (falsy). Note load_dotenv() only fills vars not already in the environment and depends on cwd for .env discovery.

Common situations: Fresh clone without copying .env.example; running from a different directory so the .env is not found; CI/containers where the env file was not copied into the image; typo'd variable names (e.g. LLM_MODEL instead of LLM_MODEL_ID).

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/11596c84203c0e4b. Report an issue: GitHub.