{"record":{"id":"88e2c8e484ec4301","repo":"datawhalechina/hello-agents","slug":"str-e-88e2c8","errorCode":null,"errorMessage":"向量生成失败: {str(e)}","messagePattern":"向量生成失败: (.+?)","errorType":"exception","errorClass":"AgentException","httpStatus":null,"severity":"error","filePath":"Co-creation-projects/Apricity-InnocoreAI/utils/embedding.py","lineNumber":65,"sourceCode":"            cleaned_text = self._clean_text(text)\n            \n            # 调用OpenAI API\n            response = await self.client.embeddings.create(\n                model=self.embedding_model,\n                input=cleaned_text\n            )\n            \n            embedding = response.data[0].embedding\n            \n            # 缓存结果\n            if use_cache:\n                cache_key = self._get_cache_key(text)\n                self.cache[cache_key] = embedding\n            \n            return embedding\n            \n        except Exception as e:\n            raise AgentException(f\"向量生成失败: {str(e)}\")\n    \n    async def generate_batch_embeddings(self, texts: List[str], \n                                       batch_size: int = 10) -> List[List[float]]:\n        \"\"\"批量生成向量\"\"\"\n        embeddings = []\n        \n        for i in range(0, len(texts), batch_size):\n            batch = texts[i:i + batch_size]\n            \n            try:\n                # 批量调用API\n                cleaned_texts = [self._clean_text(text) for text in batch]\n                \n                response = await self.client.embeddings.create(\n                    model=self.embedding_model,\n                    input=cleaned_texts\n                )\n                ","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/Apricity-InnocoreAI/utils/embedding.py#L47-L83","documentation":"An AgentException raised by EmbeddingGenerator.generate_embedding() in utils/embedding.py when the OpenAI embeddings call fails. The try wraps the API request and response extraction (response.data[0].embedding); typical causes are wrong model name, auth errors, network failures, rate limits, or empty text issues slipping past the early return. The original cause survives only as its string form, losing the exception type and status code.","triggerScenarios":"Calling generate_embedding(text) with config.vector_db.embedding_model set to a model the endpoint does not serve (e.g. 'text-embedding-3-small' against a gateway exposing only 'bge-large'); invalid/expired api_key (401); rate limit (429); connectivity problems to base_url; or an API response with empty data raising IndexError. Empty string text returns a zero vector before the call, so whitespace-only or None inputs reaching the API can also error.","commonSituations":"Switching embedding providers without updating the model name in config; hitting OpenAI rate limits during bulk indexing (the batch path calls this repeatedly); expired keys; local embedding server down; mixing the chat-LLM credential with an embedding-only credential.","solutions":["Check the wrapped message: 401 → fix api_key, 404/model_not_found → fix embedding_model in config.vector_db, 429 → add backoff/retry","Verify the endpoint actually serves the configured model with a one-off curl to {base_url}/models","Add retry with exponential backoff around the call for 429/5xx (the openai SDK honors max_retries on the client)","Preserve the original exception: raise AgentException(...) from e so tracebacks show the root cause","Trim/validate text before the call so whitespace-only input takes the zero-vector path"],"exampleFix":"# before\nexcept Exception as e:\n    raise AgentException(f\"向量生成失败: {str(e)}\")\n\n# after\nexcept Exception as e:\n    raise AgentException(f\"向量生成失败: {str(e)}\") from e\n# plus, on the client:\nself.client = AsyncOpenAI(api_key=..., base_url=..., max_retries=3)","handlingStrategy":"retry","validationCode":"assert embedder.client is not None, 'call initialize() before generate_embedding()'\nassert isinstance(text, str) and text.strip(), 'empty/whitespace text yields zero vectors'\n# optionally verify model availability:\nmodels = [m.id for m in await embedder.client.models.list()]\nassert embedder.embedding_model in models","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        return await embedder.generate_embedding(text)\n    except AgentException as e:\n        msg = str(e)\n        if '429' in msg or 'timeout' in msg or 'connection' in msg.lower():\n            await asyncio.sleep(2 ** attempt); continue\n        raise  # auth/model errors are not retried","preventionTips":["Configure the openai client with max_retries and sane timeouts for embedding calls","Verify embedding_model against the provider's /models endpoint at startup","Cache embeddings (the class already does) to reduce quota pressure during bulk indexing","Raise with 'from e' in wrappers to keep the root cause inspectable"],"tags":["openai","embeddings","rate-limit","configuration","error-handling"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}