feat(api): LLMClient.chat_json 加 want_usage 可选参返 (obj,usage)——漏斗 token 计量数据源, 默认调用零变化 [vps] [no-doc]
This commit is contained in:
@@ -34,8 +34,16 @@ class LLMClient:
|
||||
self._sleep = sleep or asyncio.sleep
|
||||
|
||||
async def chat_json(self, messages: list[dict], *, temperature: float = 0.2,
|
||||
max_tokens: int = 2000) -> dict:
|
||||
"""一轮对话→dict.传输层重试+参数自愈在 payload 级,解析失败 strict 重试一次."""
|
||||
max_tokens: int = 2000,
|
||||
want_usage: bool = False) -> dict | tuple[dict, dict]:
|
||||
"""一轮对话→dict;want_usage=True 返 (dict, usage)(P4-3 漏斗 token 计量,
|
||||
usage 含 prompt_tokens/completion_tokens)。默认调用形态零变化。"""
|
||||
obj, usage = await self._chat_json(messages, temperature=temperature,
|
||||
max_tokens=max_tokens)
|
||||
return (obj, usage) if want_usage else obj
|
||||
|
||||
async def _chat_json(self, messages: list[dict], *, temperature: float,
|
||||
max_tokens: int) -> tuple[dict, dict]:
|
||||
payload: dict = {
|
||||
"model": self._cfg.model,
|
||||
"messages": messages,
|
||||
@@ -62,7 +70,7 @@ class LLMClient:
|
||||
usage.get("prompt_tokens"),
|
||||
usage.get("completion_tokens"))
|
||||
try:
|
||||
return robust_json_parse(content)
|
||||
return robust_json_parse(content), usage
|
||||
except JSONParseError:
|
||||
return await self._strict_retry(messages, payload)
|
||||
if status in (401, 403, 404):
|
||||
@@ -96,7 +104,8 @@ class LLMClient:
|
||||
if status != 200:
|
||||
raise LLMError(f"LLM strict 重试失败(HTTP {status}): {text[:200]}")
|
||||
try:
|
||||
return robust_json_parse(self._content(text))
|
||||
usage = json.loads(text).get("usage") or {}
|
||||
return robust_json_parse(self._content(text)), usage
|
||||
except JSONParseError as e:
|
||||
raise LLMError(f"LLM 返回非 JSON(两轮): {e}") from e
|
||||
|
||||
|
||||
Reference in New Issue
Block a user