claude/skills/llm-parse-retry/SKILL.md
Use when LLM agents expect structured JSON output but responses are non-deterministic with potential malformed JSON or unexpected formats that need application-level retry logic with graceful degradation.
npx skillsauth add dragonkid/dotfiles llm-parse-retryInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
LLM responses are non-deterministic and may return malformed JSON or unexpected formats. Network-level retries (tenacity) don't help when the API succeeds but the content is unparseable. Use tenacity's retry_if_result to retry when parse returns None.
import structlog
from pydantic import ValidationError
from tenacity import (
retry,
retry_if_result,
stop_after_attempt,
wait_exponential,
before_sleep_log,
)
logger = structlog.get_logger()
class LLMAgent:
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=1, max=30),
retry=retry_if_result(lambda x: x is None),
before_sleep=before_sleep_log(logger, "WARNING"),
reraise=False,
)
async def _fetch_and_parse(self, request: Request) -> Response | None:
raw = await self.llm_client.chat(
system_prompt=self.get_system_prompt(),
user_prompt=self.get_user_prompt(request),
)
return self._parse_response(raw)
async def run(self, request: Request) -> Response:
response = await self._fetch_and_parse(request)
if response is None:
logger.error("all parse attempts failed, using default")
response = Response(items=[], status="parse_failed")
return response
def _parse_response(self, raw: str) -> Response | None:
json_str = self._extract_json(raw)
if not json_str:
return None
try:
return Response.model_validate_json(json_str)
except ValidationError:
return None
@staticmethod
def _extract_json(content: str) -> str | None:
import re
code_blocks = re.findall(r"```(?:json)?\s*([\s\S]*?)```", content)
if code_blocks:
return code_blocks[-1].strip()
json_match = re.search(r"\{[\s\S]*\}", content)
return json_match.group(0) if json_match else None
tools
Use when user wants to manage TODO items - adding tasks, listing pending items, marking done, removing, or searching. Triggers on /todo command or TODO-related requests.
tools
Use when creating a new skill, updating an existing skill, or troubleshooting skill frontmatter, gating, or slash command registration issues in OpenClaw.
tools
手动触发自我改进与记忆维护。分析近期 memory 文件,维护工作区文件,提出改进提案。触发方式:/self_improve 或用户说"自我改进"、"self improve"。
testing
测试 OpenClaw 配置中 LLM provider 的可用性。触发方式:/provider_check 或用户问"测试 provider 可用性"、"检查 provider 状态"、"provider 健康检查"。