datawhalechina/hello-agents · error · HelloAgentsException

LLM调用失败: {str(e)}

Error message

LLM调用失败: {str(e)}

What it means

The streaming path (think) wraps any exception raised during a chat.completions streaming call into HelloAgentsException("LLM call failed: ..."), after printing an error line. Typical underlying causes are auth failures, rate limits, model-not-found, timeouts, and network errors from the OpenAI-compatible client; the original message is preserved in str(e).

Source

Thrown at Co-creation-projects/lcyting-StockSage-agent/HelloAgents Optimized/hello_agents/core/llm.py:385

                temperature=temperature
                if temperature is not None
                else self.temperature,
                max_tokens=self.max_tokens,
                stream=True,
            )

            # 处理流式响应
            print("✅ 大语言模型响应成功:")
            for chunk in response:
                content = chunk.choices[0].delta.content or ""
                if content:
                    print(content, end="", flush=True)
                    yield content
            print()  # 在流式输出结束后换行

        except Exception as e:
            print(f"❌ 调用LLM API时发生错误: {e}")
            raise HelloAgentsException(f"LLM调用失败: {str(e)}")

    def invoke(self, messages: list[dict[str, str]], **kwargs) -> str:
        """
        非流式调用LLM,返回完整响应。
        适用于不需要流式输出的场景。
        """
        try:
            response = self._client.chat.completions.create(
                model=self.model,
                messages=messages,
                temperature=kwargs.get("temperature", self.temperature),
                max_tokens=kwargs.get("max_tokens", self.max_tokens),
                **{
                    k: v
                    for k, v in kwargs.items()
                    if k not in ["temperature", "max_tokens"]
                },
            )

View on GitHub (pinned to 606a07d341)

Solutions

  1. Read the embedded original error in the message — it names the real cause (401 vs 429 vs timeout).
  2. For 401/403: fix the API key; for 429: back off and retry; for model errors: correct LLM_MODEL_ID.
  3. Verify base_url is reachable and OpenAI-compatible (curl a minimal completion).
  4. Increase the client timeout for long generations, and consume the generator inside try/except since streaming errors surface lazily.

Example fix

# before
for chunk in llm.think(messages):  # raises mid-iteration on provider error
    print(chunk)

# after
try:
    for chunk in llm.think(messages):
        print(chunk)
except HelloAgentsException as e:
    logger.error("stream failed: %s", e)  # str(e) contains provider detail
    raise
Defensive patterns

Strategy: retry

Validate before calling

from dotenv import load_dotenv
load_dotenv()
assert os.getenv("LLM_API_KEY"), "LLM_API_KEY missing before streaming"
assert llm._client is not None  # client constructed successfully

Try / catch

try:
    for chunk in llm.think(messages):
        handle(chunk)
except HelloAgentsException as e:
    msg = str(e)
    if "429" in msg or "timeout" in msg.lower():
        time.sleep(2); continue_outer_retry  # backoff and retry stream
    raise  # auth/model errors are not retryable

Prevention

When it happens

Trigger: Calling think()/stream_invoke() with an invalid model name, expired API key, rate-limited account, unreachable base_url, or a mid-stream disconnect; note the generator only raises when iterated.

Common situations: Long streaming sessions hitting provider timeouts; wrong base_url for the provider; quota exhaustion; proxies/firewalls cutting SSE streams.

Related errors


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