How to Debug SkillSpector Using LangGraph Studio: A Step-by-Step Guide
Run make langgraph-dev to launch LangGraph Studio, then step through the SkillSpector workflow node-by-node while inspecting the evolving SkillspectorState to isolate bugs in analyzers or LLM calls.
SkillSpector is a security analysis tool built as a LangGraph workflow by NVIDIA. The entire graph is defined in src/skillspector/graph.py and all shared state is managed through the typed dictionary in src/skillspector/state.py. Developers can debug SkillSpector using LangGraph Studio to visualize execution flow, inject custom inputs, and examine intermediate state without writing print statements or restarting the CLI.
Launch the LangGraph Development Server
Start the local development server using the Makefile target:
make langgraph-dev
This command launches a FastAPI server that loads the LangGraph definition from src/skillspector/graph.py and opens LangGraph Studio in your browser. The terminal displays the local URL (typically http://127.0.0.1:2024). Ensure you have configured your environment variables in a .env file or exported them directly—such as SKILLSPECTOR_PROVIDER and OPENAI_API_KEY—as documented in docs/DEVELOPMENT.md.
Inspect the Graph Layout
Once Studio loads, the interface renders a Mermaid diagram representing the workflow logic. The execution flow follows this sequence:
resolve_input– Validates and localizes the target skillbuild_context– Scans files and populates metadata- Parallel analyzer nodes (e.g.,
static_yara,behavioral_ast) – Run security checks meta_analyzer– Optional LLM-based filtering of findingsreport– Generates final output and risk scoring
Each node corresponds to a Python module in src/skillspector/nodes/, allowing you to cross-reference the visual graph with the underlying implementation.
Configure Custom Input Payloads
The graph expects a JSON payload containing either an input_path (URL, zip, file, or directory) or a pre-resolved skill_path. In LangGraph Studio’s Run panel, paste a configuration like:
{
"input_path": "/path/to/my/skill",
"output_format": "json",
"use_llm": false
}
Setting use_llm to false disables the meta_analyzer step, significantly speeding up iterative debugging. The output_format field accepts terminal, json, markdown, or sarif, controlling how the final node structures the report.
Step Through Node Execution
LangGraph Studio allows interactive traversal of the graph. After triggering a run, click through each node to inspect the SkillspectorState dictionary in the right-hand pane.
Resolve Input Node
The resolve_input node (implemented in src/skillspector/nodes/resolve_input.py) handles URL downloads, zip extractions, and directory validation. If this node fails, check the state for temp_dir_for_cleanup—a path to extracted files that may reveal malformed archives or permission errors.
Build Context Node
Next, build_context (in src/skillspector/nodes/build_context.py) populates components, file_cache, manifest, and component_metadata. Verify that your skill files appear correctly in the file_cache dictionary before proceeding to analysis.
Analyzer Nodes
Parallel analyzers registered in src/skillspector/nodes/analyzers/__init__.py append findings to the state. Inspect the list after each analyzer runs:
- Static analyzers (e.g.,
static_yara,static_patterns_prompt_injection) search for hardcoded secrets or injection patterns - Behavioral analyzers (e.g.,
behavioral_ast) parse abstract syntax trees for risky code paths
If a node returns an empty findings list unexpectedly, verify the corresponding analyzer implementation in the src/skillspector/nodes/analyzers/ directory.
Meta Analyzer and Report Nodes
When use_llm is enabled, the meta_analyzer node (in src/skillspector/nodes/meta_analyzer.py) calls the configured LLM to filter false positives. Finally, the report node (in src/skillspector/nodes/report.py) writes the report_body, risk_score, and risk_severity to the state based on the accumulated findings.
Diagnose Common Issues
Use Studio’s state inspector to pinpoint failures without sifting through log files:
- Missing inputs: If
skill_pathisNoneafterresolve_input, check thetemp_dir_for_cleanupentry for extraction errors or invalid URLs. - Silent analyzers: Empty
findingslists following an analyzer node indicate the check did not match your test file—verify the analyzer’s logic in its dedicated module. - LLM errors: Exceptions in
meta_analyzersurface as explicit error messages in the node output; confirm your API keys are set correctly in the environment.
Debug Programmatically (Alternative)
For developers preferring Python REPLs over the web UI, invoke the compiled graph directly:
from skillspector import graph
result = graph.invoke({
"input_path": "/path/to/skill",
"output_format": "json",
"use_llm": False,
})
print(result["risk_score"], result["risk_severity"])
print(result["report_body"])
This approach bypasses the Studio interface while still executing the full workflow defined in src/skillspector/graph.py.
Summary
- Launch: Run
make langgraph-devto start LangGraph Studio and load the workflow fromsrc/skillspector/graph.py. - Input: Provide JSON payloads with
input_pathand setuse_llm: falsefor faster iteration. - Inspect: Step through
resolve_input,build_context, analyzer nodes, andreportto view theSkillspectorStateevolution. - Fix: Correlate empty states or errors with specific node implementations in
src/skillspector/nodes/.
Frequently Asked Questions
How do I launch LangGraph Studio for SkillSpector debugging?
Execute make langgraph-dev from the repository root. This starts the FastAPI server and opens Studio in your browser, loading the graph definition from src/skillspector/graph.py and state schema from src/skillspector/state.py.
What JSON payload format does SkillSpector require in LangGraph Studio?
The graph accepts a dictionary containing input_path (string) and optional keys like output_format (json, markdown, sarif, or terminal) and use_llm (boolean). You can also pass skill_path directly if the input has already been resolved.
How can I speed up debugging by skipping LLM calls?
Set use_llm: false in your input payload. This bypasses the meta_analyzer node entirely, allowing you to iterate quickly on static and behavioral analyzers without incurring API latency or costs.
Where are temporary files managed during a debug session?
The resolve_input node writes extracted archives to a path stored in temp_dir_for_cleanup within the SkillspectorState. While the Studio server discards these on exit, you can manually inspect this path during a paused execution to verify extraction integrity.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →