Code Review Agent
CRA
Code Review Agent
The Code Review Agent turns a SystemVerilog codebase into a fully-indexed, conversational code review assistant --- in one command. Point it at your RTL source files, give it a model config, and it produces a self-contained agent that can answer questions about your design, surface bugs, and explain module behaviour.
Overview
Reviewing RTL at scale is time-consuming. Engineers must cross-reference module interfaces, lint output, and design documentation while keeping track of cross-file issues --- all before writing a single review comment.
The Code Review Agent automates the analysis phase. It runs a seven-step pipeline over your source files, builds semantic search indices over the generated reviews and descriptions, and packages everything into a portable agent you can query in natural language.
[mllm-user]: What bugs exist in the FIFO implementation?
Agent: The empty flag in fifo_sync.sv uses != instead of ==
on line 47, which inverts the empty condition and will
cause read-underflow on the first cycle after reset.[mllm-user]: Summarize the main issues found across the codebase.
Agent: Three critical issues were identified:
1. AXI read data registered one cycle too late (axi_lite_slave.sv)
2. Inverted FIFO empty signal (fifo_sync.sv)
3. Write/read channel coupling violates AXI independence requirementGetting Started
Step 1 --- Create a config file:
Create a my_review.config.json with your model credentials:
{
"Config": {
"name": "my_review_agent",
"LangChain": {
"provider": "openai",
"model": "gpt-4.1",
"credentials": "/path/to/openai/key.json",
"temperature": 0.0
},
"MultiLLM": {
"llms": [
{
"file": "models/models.py",
"class_name": "GPT",
"provider": "openai",
"model": "gpt-4.1",
"credentials": "/path/to/openai/key.json"
}
]
}
}
}See Configuration for all available options.
Step 2 --- Build the agent:
multillm --create-review-agent \
--input path/to/rtl/ \
--config my_review.config.json \
--name my_design_reviewThe --input argument accepts a directory (recursively scanned) or one
or more individual files.
Step 3 --- Run it:
# Interactive chat
multillm --run-agent my_design_review/
# Single query
multillm --run-agent my_design_review/ --query "What are the top issues?"Pipeline
The build command runs seven steps automatically:
| Step | Name | Description |
|---|---|---|
| 1 | File collection | Recursively gathers .sv, .v, and .svh files from the input path and writes a manifest. |
| 2 | Linting | Runs verible-verilog-lint over all collected files. Skipped gracefully if Verible is not on PATH. |
| 3 | Combine | Concatenates all source files into a single combined file for downstream context. |
| 4 | Repo analysis | Calls SVParse (VerifAI's structural analyser) to extract module interfaces, port directions, parameters, and instance hierarchies. Uses the Config.LangChain model. |
| 5 | LLM review + description | Generates per-file code reviews and module descriptions in parallel, then merges them into final_summary.md and final_descriptions.md. Uses the Config.LangChain model. |
| 6 | Semantic search | Builds two ChromaDB vector databases --- one over reviews, one over descriptions --- for retrieval during agent queries. |
| 7 | Repo analysis | Writes a self-contained agent.py and copies all required configs and tool files into the output directory. |
Output Structure
The build command produces a self-contained output directory:
my_design_review/
├── agent.py ← Entry point for multillm --run-agent
└── .verifaiws/
├── mllm.config.json ← Agent config (AgentTools injected)
├── system_prompt.txt ← Agent system prompt
├── tools.py ← Semantic search tool implementations
├── review_semantic_search.config.json ← RAG config for reviews DB
├── description_semantic_search.config.json
├── file_list.txt ← Collected source files
├── lint_results.txt ← Verible lint output
├── combined_code.txt ← All source concatenated
├── repo_analysis.json ← SVParse structural analysis
├── file_summaries/ ← Per-file code reviews
├── file_descriptions/ ← Per-file module descriptions
├── final_summary.md ← Merged review report
├── final_descriptions.md ← Merged description report
└── semantic_search/
├── reviews_db/ ← ChromaDB reviews index
└── descriptions_db/ ← ChromaDB descriptions indexThe output directory is fully portable --- copy or move it anywhere and
multillm --run-agent will still work.
Configuration
All pipeline and agent settings live in a single JSON config file.
Minimal config
{
"Config": {
"name": "my_review_agent",
"LangChain": {
"provider": "openai",
"model": "gpt-4.1",
"temperature": 0.0
},
"MultiLLM": {
"llms": [
{
"file": "models/models.py",
"class_name": "GPT",
"provider": "openai",
"model": "gpt-4.1",
"credentials": "/path/to/openai/key.json"
}
]
}
}
}Full config reference
| Key | Default | Description |
|---|---|---|
Config.LangChain.provider | "openai" | LLM provider for pipeline steps (SVParse + reviews). Supported: openai, anthropic, azure-openai, ollama. |
Config.LangChain.model | "gpt-4.1-mini" | Model name passed to the LangChain client for pipeline steps. |
Config.LangChain.temperature | 0.0 | Sampling temperature for pipeline LLM calls. |
Config.LangChain.credentials | (env var) | Path to a JSON file containing {"api_key": "..."} for the LangChain provider. If omitted, the provider's standard environment variable must be set (e.g. OPENAI_API_KEY). |
Config.Pipeline.max_workers | 8 | Maximum parallel threads for per-file review and description generation in step 5. |
Config.Pipeline.batch_size | 3 | Number of per-file summaries merged per LLM call in the incremental merge pass. |
Config.MultiLLM | --- | MultiLLM configuration for the generated agent (chat interface). See AgentDemos for full MultiLLM config reference. |
Config.VectorStore.databases | --- | Array of {"role": ..., "db_path": ...} entries defining where the two ChromaDB indices are stored. Roles must be reviews_db and descriptions_db. Paths are relative to the agent output directory. |
Config.VectorStore.k_matches | 5 | Number of nearest-neighbour results returned per semantic search query. |
Config.VectorStore.embedding_llm | "None" | Embedding model for ChromaDB. "None" uses the default sentence-transformer embedding. Set to "openai" to use OpenAI embeddings. |
Example full config
{
"Config": {
"name": "rtl_review_agent",
"agent_class": "LlmAgent",
"model_name": "GEMINI",
"LangChain": {
"provider": "openai",
"model": "gpt-4.1",
"credentials": "/home/ubuntu/.config/openai/key.json",
"temperature": 0.0
},
"Pipeline": {
"max_workers": 16,
"batch_size": 3
},
"MultiLLM": {
"ranking_llm": "GEMINI",
"merging_llm": "GEMINI",
"prompts_llm": "GEMINI",
"llms": [
{
"file": "models/models.py",
"class_name": "GEMINI",
"provider": "vertex",
"model": "google/gemini-3-flash-preview",
"credentials": "/home/ubuntu/.config/google/google.key"
},
{
"file": "models/models.py",
"class_name": "GPT",
"provider": "openai",
"model": "gpt-4.1",
"credentials": "/home/ubuntu/.config/openai/key.json"
}
]
},
"VectorStore": {
"k_matches": 5,
"embedding_llm": "None",
"databases": [
{ "role": "reviews_db", "db_path": "./semantic_search/reviews_db" },
{ "role": "descriptions_db", "db_path": "./semantic_search/descriptions_db" }
]
}
}
}Prerequisites
Python environment
The pipeline requires the verifai package (for SVParse) to be
installed in the active Python environment:
pip install verifaiAPI credentials
The Config.LangChain provider requires either:
-
A credentials JSON file at the path specified in
Config.LangChain.credentials:{ "api_key": "sk-..." } -
Or the provider's standard environment variable set in the shell:
export OPENAI_API_KEY="sk-..."
Verible (optional)
Linting in step 2 requires verible-verilog-lint on PATH. If not
found, linting is skipped and the pipeline continues without lint data.
PATH:
export PATH=$PATH:/usr/local/verible/bin
# To make permanent, add to ~/.bashrc:
echo 'export PATH=$PATH:/usr/local/verible/bin' >> ~/.bashrcCLI Reference
multillm --create-review-agent \
--input <path> One or more files or directories to review
--config <path> Path to the review agent config JSON
--name <name> Output directory name
[--output <path>] Base output directory (default: current directory)Example Queries
Once the agent is running, try queries like:
Bug finding
What bugs exist in the FIFO implementation?
Is there a timing issue with the AXI read data channel?
Are there any combinational loops or latching hazards?Lint findings
What did the linter flag in these files?
Which signals are missing explicit storage types?Code understanding
How does the AXI write path work?
What is the relationship between the read and write pointers in the FIFO?
Summarize the main issues found in this codebase.
What are the most critical problems I should fix first?