sqlite_graphrag/commands/deep_research/
args.rs1#[derive(clap::Args)]
5#[command(
6 about = "Deep parallel multi-hop GraphRAG research via query decomposition",
7 after_long_help = "CONTRACT:\n \
8 stdout = pretty JSON envelope only (machine-readable).\n \
9 stderr = tracing / progress / diagnostics only.\n \
10 Never redirect with `&>` or `2>&1` into the same file as stdout — that\n \
11 contaminates the JSON and breaks jaq/jq. Prefer:\n \
12 sqlite-graphrag deep-research \"q\" > out.json 2>/dev/null\n \
13 or --output out.json (atomic write via atomwrite algorithm).\n\n\
14EXAMPLES:\n \
15 # Basic deep research (single-token queries auto-expand into aspects)\n \
16 sqlite-graphrag deep-research \"alice\"\n\n \
17 # With custom parameters\n \
18 sqlite-graphrag deep-research \"auth\" --k 20 --max-hops 3 --max-sub-queries 7\n\n \
19 # Include full memory bodies in output\n \
20 sqlite-graphrag deep-research \"auth\" --with-bodies\n\n \
21 # Manual sub-queries (one query per line)\n \
22 sqlite-graphrag deep-research \"alice\" --sub-query-strategy manual \\\n \
23 --sub-queries-file aspects.txt\n\n \
24 # Atomic JSON file (crash-safe; preferred for large --with-bodies runs)\n \
25 sqlite-graphrag deep-research \"auth\" --output /tmp/dr.json\n\n \
26 # Tune RRF and graph scoring\n \
27 sqlite-graphrag deep-research \"auth and deployment\" --rrf-k 60 --graph-decay 0.7"
28)]
29pub struct DeepResearchArgs {
30 #[arg(
32 value_name = "QUERY",
33 allow_hyphen_values = true,
34 help = "Research query to decompose and search"
35 )]
36 pub query: String,
37 #[arg(
39 long,
40 short,
41 aliases = ["limit", "top-k"],
42 default_value_t = 20,
43 value_parser = crate::parsers::parse_k_range,
44 help = "Results per sub-query (Recall@20 captures 95%+ relevant hits)"
45 )]
46 pub k: usize,
47 #[arg(
49 long,
50 default_value_t = 7,
51 value_parser = crate::parsers::parse_sub_queries_range,
52 help = "Maximum sub-queries (covers complex multi-hop queries)"
53 )]
54 pub max_sub_queries: usize,
55 #[arg(
57 long,
58 default_value_t = 3,
59 value_parser = crate::parsers::parse_hops_range_usize,
60 help = "Multi-hop graph traversal depth (sweet spot: 2-3 hops)"
61 )]
62 pub max_hops: usize,
63 #[arg(
65 long,
66 default_value_t = 0.3,
67 help = "Minimum edge weight for graph traversal"
68 )]
69 pub min_weight: f64,
70 #[arg(long, help = "Maximum concurrent sub-queries (default: min(cpus, 8))")]
72 pub max_concurrency: Option<usize>,
73 #[arg(long, default_value_t = 30, help = "Timeout per sub-query in seconds")]
75 pub timeout: u64,
76 #[arg(
78 long,
79 default_value_t = false,
80 help = "Include full memory bodies in results"
81 )]
82 pub with_bodies: bool,
83 #[arg(
85 long,
86 default_value_t = 50,
87 value_parser = crate::parsers::parse_k_range,
88 help = "Maximum results after deduplication"
89 )]
90 pub max_results: usize,
91 #[arg(
93 long,
94 default_value_t = 60.0,
95 help = "RRF k parameter (higher = less weight on top ranks)"
96 )]
97 pub rrf_k: f64,
98 #[arg(
100 long,
101 default_value_t = 0.7,
102 help = "Graph score decay factor per hop (0.0-1.0)"
103 )]
104 pub graph_decay: f64,
105 #[arg(
107 long,
108 default_value_t = 0.05,
109 help = "Minimum score threshold for graph-expanded results"
110 )]
111 pub graph_min_score: f64,
112 #[arg(
114 long,
115 help = "Limit neighbours per entity per hop for graph traversal (default: unlimited)"
116 )]
117 pub max_neighbors_per_hop: Option<usize>,
118 #[arg(long, help = "Namespace (flag / XDG namespace.default / global)")]
120 pub namespace: Option<String>,
121 #[arg(long, default_value = "none", value_parser = ["none"], hide = true)]
128 pub mode: String,
129 #[arg(
134 long,
135 value_name = "USD",
136 help = "Max LLM cost in USD (inert: no LLM research mode is available)"
137 )]
138 pub max_cost_usd: Option<f64>,
139 #[arg(long, hide = true)]
141 pub json: bool,
142 #[arg(long)]
144 pub db: Option<String>,
145 #[arg(
148 long,
149 default_value = "heuristic",
150 value_parser = ["heuristic", "manual"],
151 help = "Sub-query strategy: heuristic (default) or manual"
152 )]
153 pub sub_query_strategy: String,
154 #[arg(
157 long,
158 value_name = "PATH",
159 help = "File with one sub-query per line (manual strategy)"
160 )]
161 pub sub_queries_file: Option<std::path::PathBuf>,
162 #[arg(
167 short = 'o',
168 long,
169 value_name = "PATH",
170 help = "Atomic JSON output path (atomwrite algorithm; short -o)"
171 )]
172 pub output: Option<std::path::PathBuf>,
173}