import%20marimo%0A%0A__generated_with%20%3D%20%220.22.0%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20sqlite3%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20os%0A%20%20%20%20import%20re%0A%20%20%20%20import%20logging%0A%20%20%20%20import%20ast%0A%20%20%20%20from%20typing%20import%20Dict%2C%20Any%2C%20Tuple%2C%20List%0A%20%20%20%20from%20CyVer%20import%20SyntaxValidator%0A%20%20%20%20from%20neo4j%20import%20GraphDatabase%2C%20basic_auth%0A%20%20%20%20from%20model_evaluator%20import%20ModelEvaluator%0A%0A%20%20%20%20%23%20Silence%20verbose%20Neo4j%20notifications%0A%20%20%20%20logging.getLogger(%22neo4j%22).setLevel(logging.ERROR)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Any%2C%0A%20%20%20%20%20%20%20%20Dict%2C%0A%20%20%20%20%20%20%20%20GraphDatabase%2C%0A%20%20%20%20%20%20%20%20List%2C%0A%20%20%20%20%20%20%20%20ModelEvaluator%2C%0A%20%20%20%20%20%20%20%20SyntaxValidator%2C%0A%20%20%20%20%20%20%20%20Tuple%2C%0A%20%20%20%20%20%20%20%20ast%2C%0A%20%20%20%20%20%20%20%20basic_auth%2C%0A%20%20%20%20%20%20%20%20mo%2C%0A%20%20%20%20%20%20%20%20np%2C%0A%20%20%20%20%20%20%20%20pd%2C%0A%20%20%20%20%20%20%20%20plt%2C%0A%20%20%20%20%20%20%20%20re%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%20Model%20Analysis%3A%20Reasoning%20Performance%20Comparison%0A%0A%20%20%20%20This%20notebook%20analyzes%20and%20compares%20the%20performance%20of%20**Qwen%2FQwen3.5-4B**%20on%20the%20**LC-QuAD%202.0**%20dataset%2C%20specifically%20focusing%20on%20the%20difference%20between%20responses%20generated%20with%20and%20without%20reasoning%20enabled.%0A%0A%20%20%20%20%23%23%23%20Key%20Objectives%3A%0A%20%20%20%20-%20Compare%20Cypher%20query%20character%20lengths.%0A%20%20%20%20-%20Analyze%20the%20%22thinking%22%20process%20length%20for%20reasoning-enabled%20models.%0A%20%20%20%20-%20Visualize%20distributions%20and%20identify%20potential%20outliers%20or%20patterns.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Data%20Loading%20and%20Preparation%0A%0A%20%20%20%20We%20retrieve%20cached%20model%20responses%20from%20a%20SQLite%20database%20(%60ai_cache.db%60).%0A%20%20%20%20-%20For%20**Reasoning%20OFF**%2C%20we%20extract%20the%20JSON%20content%20directly.%0A%20%20%20%20-%20For%20**Reasoning%20ON**%2C%20we%20parse%20the%20content%20to%20separate%20the%20%60%3Cthink%3E%60%20reasoning%20block%20from%20the%20final%20Cypher%20query.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ModelEvaluator%2C%20pd)%3A%0A%20%20%20%20evaluator%20%3D%20ModelEvaluator(model_name%3D'dummy'%2C%20api_key%3D'')%0A%0A%20%20%20%20%23%20Load%20reasoning%3D0%20data%20with%20all%20fields%0A%20%20%20%20df_no_reason%20%3D%20evaluator.fetch_cached_responses('Qwen%2FQwen3.5-4B'%2C%20'lc-quad-2.0'%2C%20include_reasoning%3D0)%0A%20%20%20%20df_no_reason%5B'query_length'%5D%20%3D%20pd.to_numeric(df_no_reason%5B'content'%5D.str.len()%2C%20errors%3D'coerce')%0A%0A%20%20%20%20%23%20Load%20reasoning%3D1%20data%20with%20all%20fields%0A%20%20%20%20df_reason%20%3D%20evaluator.fetch_cached_responses('Qwen%2FQwen3.5-4B'%2C%20'lc-quad-2.0'%2C%20include_reasoning%3D1)%0A%20%20%20%20df_reason.rename(columns%3D%7B'content'%3A%20'full_content'%7D%2C%20inplace%3DTrue)%0A%0A%20%20%20%20def%20_extract_parts(text)%3A%0A%20%20%20%20%20%20%20%20if%20not%20text%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%22%22%2C%20%22%22%0A%20%20%20%20%20%20%20%20%23%20The%20model%20response%20for%20reasoning%20models%20usually%20wraps%20thinking%20in%20%3Cthink%3E...%3C%2Fthink%3E%0A%20%20%20%20%20%20%20%20%23%20We%20look%20for%20the%20closing%20tag%20to%20separate%20thinking%20from%20the%20final%20query.%0A%20%20%20%20%20%20%20%20_clean_text%20%3D%20text.replace(%22%3Cthink%3E%22%2C%20%22%22)%0A%20%20%20%20%20%20%20%20before%2C%20sep%2C%20after%20%3D%20_clean_text.partition(%22%3C%2Fthink%3E%22)%0A%20%20%20%20%20%20%20%20if%20sep%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20before.strip()%2C%20after.strip()%0A%20%20%20%20%20%20%20%20return%20None%0A%0A%20%20%20%20_parts%20%3D%20df_reason%5B'full_content'%5D.apply(_extract_parts)%0A%20%20%20%20invalid_response_count%20%3D%20int(_parts.isna().sum())%0A%20%20%20%20_valid_parts%20%3D%20_parts.dropna()%0A%0A%20%20%20%20%23%20Initialize%20columns%20with%20empty%2FNone%0A%20%20%20%20df_reason%5B'thinking_text'%5D%20%3D%20%22%22%0A%20%20%20%20df_reason%5B'query_text'%5D%20%3D%20%22%22%0A%0A%20%20%20%20%23%20Map%20valid%20parts%20back%20to%20the%20dataframe%0A%20%20%20%20if%20not%20_valid_parts.empty%3A%0A%20%20%20%20%20%20%20%20df_reason%20%3D%20df_reason.loc%5B_valid_parts.index%5D.copy()%0A%20%20%20%20%20%20%20%20df_reason%5B'thinking_text'%5D%20%3D%20_valid_parts.apply(lambda%20x%3A%20x%5B0%5D)%0A%20%20%20%20%20%20%20%20df_reason%5B'query_text'%5D%20%3D%20_valid_parts.apply(lambda%20x%3A%20x%5B1%5D)%0A%0A%20%20%20%20df_reason%5B'thinking_length'%5D%20%3D%20pd.to_numeric(df_reason%5B'thinking_text'%5D.str.len()%2C%20errors%3D'coerce')%0A%20%20%20%20df_reason%5B'query_length'%5D%20%3D%20pd.to_numeric(df_reason%5B'query_text'%5D.str.len()%2C%20errors%3D'coerce')%0A%20%20%20%20return%20df_no_reason%2C%20df_reason%2C%20invalid_response_count%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Data%20Preview%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_no_reason%2C%20df_reason%2C%20mo)%3A%0A%20%20%20%20_preview%20%3D%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20mo.md(%22%23%23%23%20Preview%3A%20Reasoning%20OFF%22)%2C%0A%20%20%20%20%20%20%20%20mo.ui.table(df_no_reason.head())%2C%0A%20%20%20%20%20%20%20%20mo.md(%22%23%23%23%20Preview%3A%20Reasoning%20ON%22)%2C%0A%20%20%20%20%20%20%20%20mo.ui.table(df_reason.head())%0A%20%20%20%20%5D)%0A%20%20%20%20_preview%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_no_reason%2C%20df_reason%2C%20invalid_response_count%2C%20mo)%3A%0A%20%20%20%20if%20df_no_reason.empty%20or%20df_reason.empty%3A%0A%20%20%20%20%20%20%20%20_stats_md%20%3D%20mo.md(%22%23%20Missing%20data%20for%20comparison.%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20_s_no%20%3D%20df_no_reason%5B'query_length'%5D.describe()%0A%20%20%20%20%20%20%20%20_s_re%20%3D%20df_reason%5B'query_length'%5D.describe()%0A%20%20%20%20%20%20%20%20_s_th%20%3D%20df_reason%5B'thinking_length'%5D.describe()%0A%0A%20%20%20%20%20%20%20%20%23%20Create%20a%20small%20warning%20string%20if%20there%20are%20invalid%20responses%0A%20%20%20%20%20%20%20%20_invalid_msg%20%3D%20%22%22%0A%20%20%20%20%20%20%20%20if%20invalid_response_count%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_invalid_msg%20%3D%20f%22**Note%3A**%20%7Binvalid_response_count%7D%20responses%20were%20skipped%20because%20they%20were%20missing%20%60%3C%2Fthink%3E%60%20tags.%22%0A%0A%20%20%20%20%20%20%20%20_stats_md%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%20Summary%20Statistics%3A%20Reasoning%20OFF%20vs%20ON%0A%0A%20%20%20%20%20%20%20%20This%20table%20compares%20the%20**Cypher%20Query**%20character%20lengths%3A%0A%20%20%20%20%20%20%20%20-%20**OFF%3A%20Response**%3A%20The%20full%20response%20(query%20only)%20when%20reasoning%20is%20disabled.%0A%20%20%20%20%20%20%20%20-%20**ON%3A%20Query**%3A%20The%20extracted%20query%20section%20when%20reasoning%20is%20enabled.%0A%20%20%20%20%20%20%20%20-%20**ON%3A%20Thinking**%3A%20The%20reasoning%20content%20extracted%20from%20%60%3Cthink%3E%60%20tags.%0A%0A%20%20%20%20%20%20%20%20%7C%20Metric%20%7C%20OFF%3A%20Response%20%7C%20ON%3A%20Query%20%7C%20ON%3A%20Thinking%20%7C%0A%20%20%20%20%20%20%20%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Count**%20%7C%20%7B_s_no%5B'count'%5D%3A.0f%7D%20%7C%20%7B_s_re%5B'count'%5D%3A.0f%7D%20%7C%20%7B_s_th%5B'count'%5D%3A.0f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Mean**%20%7C%20%7B_s_no%5B'mean'%5D%3A.2f%7D%20%7C%20%7B_s_re%5B'mean'%5D%3A.2f%7D%20%7C%20%7B_s_th%5B'mean'%5D%3A.2f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Median%20(50%25)**%20%7C%20%7B_s_no%5B'50%25'%5D%3A.2f%7D%20%7C%20%7B_s_re%5B'50%25'%5D%3A.2f%7D%20%7C%20%7B_s_th%5B'50%25'%5D%3A.2f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Std%20Dev**%20%7C%20%7B_s_no%5B'std'%5D%3A.2f%7D%20%7C%20%7B_s_re%5B'std'%5D%3A.2f%7D%20%7C%20%7B_s_th%5B'std'%5D%3A.2f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Min**%20%7C%20%7B_s_no%5B'min'%5D%3A.0f%7D%20%7C%20%7B_s_re%5B'min'%5D%3A.0f%7D%20%7C%20%7B_s_th%5B'min'%5D%3A.0f%7D%20%7C%0A%20%20%20%20%20%20%20%20%7C%20**Max**%20%7C%20%7B_s_no%5B'max'%5D%3A.0f%7D%20%7C%20%7B_s_re%5B'max'%5D%3A.0f%7D%20%7C%20%7B_s_th%5B'max'%5D%3A.0f%7D%20%7C%0A%0A%20%20%20%20%20%20%20%20%7B_invalid_msg%7D%0A%20%20%20%20%20%20%20%20%22%22%22)%0A%0A%20%20%20%20_stats_md%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_no_reason%2C%20df_reason%2C%20mo%2C%20pd)%3A%0A%20%20%20%20def%20_get_samples(df%2C%20text_col%2C%20n%3D5)%3A%0A%20%20%20%20%20%20%20%20if%20df.empty%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20pd.DataFrame()%0A%0A%20%20%20%20%20%20%20%20%23%20Ensure%20variety%20by%20dropping%20identical%20queries%20first%0A%20%20%20%20%20%20%20%20_unique_df%20%3D%20df.drop_duplicates(subset%3D%5Btext_col%5D)%0A%20%20%20%20%20%20%20%20_n%20%3D%20min(n%2C%20len(_unique_df))%0A%0A%20%20%20%20%20%20%20%20%23%20Random%20sample%20for%20a%20diverse%20view%0A%20%20%20%20%20%20%20%20return%20_unique_df.sample(n%3D_n%2C%20random_state%3D42)%0A%0A%20%20%20%20_samples_off%20%3D%20_get_samples(df_no_reason%2C%20'content')%0A%20%20%20%20_samples_on%20%3D%20_get_samples(df_reason%2C%20'query_text')%0A%0A%20%20%20%20def%20_format_list(samples%2C%20text_col)%3A%0A%20%20%20%20%20%20%20%20if%20samples.empty%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%22_No%20samples%20available._%22%0A%0A%20%20%20%20%20%20%20%20items%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20_%2C%20_row%20in%20samples.iterrows()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_question%20%3D%20_row%5B'question'%5D%20if%20'question'%20in%20_row%20else%20%22Unknown%20Question%22%0A%20%20%20%20%20%20%20%20%20%20%20%20_length%20%3D%20int(_row%5B'query_length'%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20_text%20%3D%20_row%5Btext_col%5D.strip()%20if%20_row%5Btext_col%5D%20else%20%22%5BEmpty%5D%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Format%20each%20sample%20with%20its%20question%20and%20the%20Cypher%20query%0A%20%20%20%20%20%20%20%20%20%20%20%20_item_md%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22**Question%3A**%20%7B_question%7D%5Cn%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22**Query%20(Length%3A%20%7B_length%7D%20chars)%3A**%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f%22%60%60%60cypher%5Cn%7B_text%7D%5Cn%60%60%60%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20items.append(_item_md)%0A%0A%20%20%20%20%20%20%20%20return%20%22%5Cn%5Cn---%5Cn%5Cn%22.join(items)%0A%0A%20%20%20%20_content%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%20Random%20Sample%20Queries%0A%0A%20%20%20%20These%20samples%20are%20selected%20at%20random%20from%20the%20dataset%20to%20provide%20a%20diverse%20look%20at%20the%20model's%20output%20quality.%0A%0A%20%20%20%20%23%23%23%20Reasoning%20OFF%20(Average%3A%20%7Bdf_no_reason%5B'query_length'%5D.mean()%20if%20not%20df_no_reason.empty%20else%200%3A.1f%7D%20chars)%0A%20%20%20%20%7B_format_list(_samples_off%2C%20'content')%7D%0A%0A%20%20%20%20%23%23%23%20Reasoning%20ON%20(Average%3A%20%7Bdf_reason%5B'query_length'%5D.mean()%20if%20not%20df_reason.empty%20else%200%3A.1f%7D%20chars)%0A%20%20%20%20%7B_format_list(_samples_on%2C%20'query_text')%7D%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20_content%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Distribution%20Analysis%0A%0A%20%20%20%20The%20following%20visualizations%20compare%20the%20character%20length%20distributions%20of%20the%20generated%20Cypher%20queries.%0A%20%20%20%20Note%20that%20for%20reasoning-enabled%20models%2C%20we%20only%20measure%20the%20*final%20query*%20length%2C%20excluding%20the%20thinking%20process.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_no_reason%2C%20df_reason%2C%20plt)%3A%0A%20%20%20%20_fig%20%3D%20None%0A%20%20%20%20if%20not%20df_no_reason.empty%20and%20not%20df_reason.empty%3A%0A%20%20%20%20%20%20%20%20_l0%2C%20_u0%20%3D%20df_no_reason%5B'query_length'%5D.quantile(0.05)%2C%20df_no_reason%5B'query_length'%5D.quantile(0.95)%0A%20%20%20%20%20%20%20%20_l1%2C%20_u1%20%3D%20df_reason%5B'query_length'%5D.quantile(0.05)%2C%20df_reason%5B'query_length'%5D.quantile(0.95)%0A%0A%20%20%20%20%20%20%20%20_shared_min%20%3D%20min(_l0%2C%20_l1)%0A%20%20%20%20%20%20%20%20_shared_max%20%3D%20max(_u0%2C%20_u1)%0A%0A%20%20%20%20%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(10%2C%206))%0A%0A%20%20%20%20%20%20%20%20_ax.hist(df_no_reason%5B'query_length'%5D%2C%20bins%3D50%2C%20range%3D(_shared_min%2C%20_shared_max)%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha%3D0.5%2C%20label%3D'Reasoning%20OFF%20(Full%20Response)'%2C%20color%3D'blue'%2C%20edgecolor%3D'darkblue')%0A%20%20%20%20%20%20%20%20_ax.hist(df_reason%5B'query_length'%5D%2C%20bins%3D50%2C%20range%3D(_shared_min%2C%20_shared_max)%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alpha%3D0.5%2C%20label%3D'Reasoning%20ON%20(Extracted%20Query)'%2C%20color%3D'orange'%2C%20edgecolor%3D'darkorange')%0A%0A%20%20%20%20%20%20%20%20_ax.set_title(%22Query%20Length%20Distribution%3A%20Reasoning%20OFF%20vs%20ON%22)%0A%20%20%20%20%20%20%20%20_ax.set_xlabel(%22Query%20Length%20(characters)%22)%0A%20%20%20%20%20%20%20%20_ax.set_ylabel(%22Frequency%22)%0A%20%20%20%20%20%20%20%20_ax.legend()%0A%20%20%20%20%20%20%20%20_ax.grid(True%2C%20alpha%3D0.3)%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_no_reason%2C%20df_reason%2C%20plt)%3A%0A%20%20%20%20_fig%20%3D%20None%0A%20%20%20%20if%20not%20df_no_reason.empty%20and%20not%20df_reason.empty%3A%0A%20%20%20%20%20%20%20%20%23%20We%20still%20calculate%20the%20upper%20bound%20for%20the%20shared%20axis%0A%20%20%20%20%20%20%20%20_u0%20%3D%20df_no_reason%5B'query_length'%5D.quantile(0.95)%0A%20%20%20%20%20%20%20%20_u1%20%3D%20df_reason%5B'query_length'%5D.quantile(0.95)%0A%20%20%20%20%20%20%20%20_shared_max%20%3D%20max(_u0%2C%20_u1)%0A%0A%20%20%20%20%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(10%2C%204))%0A%20%20%20%20%20%20%20%20_data%20%3D%20%5Bdf_no_reason%5B'query_length'%5D%2C%20df_reason%5B'query_length'%5D%5D%0A%20%20%20%20%20%20%20%20_ax.boxplot(_data%2C%20vert%3DFalse%2C%20labels%3D%5B'Reasoning%20OFF%20(Full)'%2C%20'Reasoning%20ON%20(Query)'%5D%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20patch_artist%3DTrue)%0A%0A%20%20%20%20%20%20%20%20%23%20Change%20the%20lower%20limit%20to%200%0A%20%20%20%20%20%20%20%20_ax.set_xlim(0%2C%20_shared_max)%20%0A%0A%20%20%20%20%20%20%20%20_ax.set_title(%22Response%20Length%20Box%20Comparison%22)%0A%20%20%20%20%20%20%20%20_ax.set_xlabel(%22Length%20(characters)%22)%0A%20%20%20%20%20%20%20%20_ax.grid(axis%3D'x'%2C%20alpha%3D0.3)%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Thinking%20Process%20Analysis%0A%0A%20%20%20%20When%20reasoning%20is%20enabled%2C%20the%20model%20generates%20a%20%22thinking%22%20chain%20before%20producing%20the%20final%20query.%0A%20%20%20%20Below%20is%20the%20distribution%20of%20the%20length%20(in%20characters)%20of%20these%20reasoning%20paths.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_reason%2C%20plt)%3A%0A%20%20%20%20_fig%20%3D%20None%0A%20%20%20%20if%20not%20df_reason.empty%3A%0A%20%20%20%20%20%20%20%20_l%2C%20_u%20%3D%20df_reason%5B'thinking_length'%5D.quantile(0.05)%2C%20df_reason%5B'thinking_length'%5D.quantile(0.95)%0A%20%20%20%20%20%20%20%20_df_mid%20%3D%20df_reason%5B(df_reason%5B'thinking_length'%5D%20%3E%3D%20_l)%20%26%20(df_reason%5B'thinking_length'%5D%20%3C%3D%20_u)%5D%0A%0A%20%20%20%20%20%20%20%20_fig%2C%20(_ax_hist%2C%20_ax_box)%20%3D%20plt.subplots(nrows%3D2%2C%20ncols%3D1%2C%20figsize%3D(10%2C%2010)%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20gridspec_kw%3D%7B'height_ratios'%3A%20%5B3%2C%201%5D%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20sharex%3DTrue)%0A%0A%20%20%20%20%20%20%20%20_ax_hist.hist(_df_mid%5B'thinking_length'%5D%2C%20bins%3D50%2C%20color%3D'purple'%2C%20edgecolor%3D'black'%2C%20alpha%3D0.7)%0A%20%20%20%20%20%20%20%20_ax_hist.set_title(%22Distribution%20of%20Thinking%20Length%20(Reasoning%20ON)%22)%0A%20%20%20%20%20%20%20%20_ax_hist.set_ylabel(%22Frequency%22)%0A%20%20%20%20%20%20%20%20_ax_hist.grid(axis%3D'y'%2C%20alpha%3D0.3)%0A%0A%20%20%20%20%20%20%20%20_ax_box.boxplot(df_reason%5B'thinking_length'%5D%2C%20vert%3DFalse%2C%20patch_artist%3DTrue%2C%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20boxprops%3Ddict(facecolor%3D'plum'))%0A%20%20%20%20%20%20%20%20_ax_box.set_xlabel(%22Thinking%20Length%20(characters)%22)%0A%20%20%20%20%20%20%20%20_ax_box.set_yticks(%5B%5D)%0A%20%20%20%20%20%20%20%20_ax_box.grid(axis%3D'x'%2C%20alpha%3D0.3)%0A%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Cypher%20Query%20Syntax%20Validation%20(CyVer%20AST)%0A%0A%20%20%20%20We%20validate%20all%20generated%20Cypher%20queries%20using%20**CyVer**'s%20%60SyntaxValidator%60%2C%20which%20uses%20the%20openCypher%20ANTLR%20grammar%20under%20the%20hood%20to%20perform%20real%20AST-based%20syntax%20validation.%0A%0A%20%20%20%20This%20analysis%20determines%20what%20percentage%20of%20the%20model's%20generated%20queries%20are%20syntactically%20invalid.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20Any%2C%0A%20%20%20%20Dict%2C%0A%20%20%20%20GraphDatabase%2C%0A%20%20%20%20SyntaxValidator%2C%0A%20%20%20%20Tuple%2C%0A%20%20%20%20basic_auth%2C%0A%20%20%20%20df_no_reason%2C%0A%20%20%20%20df_reason%2C%0A)%3A%0A%20%20%20%20%23%20Connect%20to%20Neo4j%20(required%20by%20CyVer)%0A%20%20%20%20_uri%3A%20str%20%3D%20%22bolt%3A%2F%2Flocalhost%3A7687%22%0A%20%20%20%20_auth%3A%20Tuple%5Bstr%2C%20str%5D%20%3D%20basic_auth(%22neo4j%22%2C%20%22password-to-kg%22)%0A%20%20%20%20_driver%20%3D%20GraphDatabase.driver(_uri%2C%20auth%3D_auth)%0A%0A%20%20%20%20_validator%3A%20SyntaxValidator%20%3D%20SyntaxValidator(_driver%2C%20check_multilabeled_nodes%3DFalse)%0A%0A%20%20%20%20def%20_validate_query(query_text%3A%20str)%20-%3E%20Dict%5Bstr%2C%20Any%5D%3A%0A%20%20%20%20%20%20%20%20%22%22%22Validate%20a%20single%20Cypher%20query%20using%20CyVer%20SyntaxValidator.%22%22%22%0A%20%20%20%20%20%20%20%20if%20not%20query_text%20or%20not%20isinstance(query_text%2C%20str)%20or%20not%20query_text.strip()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%22is_valid%22%3A%20False%2C%20%22error%22%3A%20%22Empty%20or%20None%20query%22%7D%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20CyVer%20returns%20(is_valid%3A%20bool%2C%20metadata%3A%20dict)%0A%20%20%20%20%20%20%20%20%20%20%20%20_is_valid%3A%20bool%0A%20%20%20%20%20%20%20%20%20%20%20%20_metadata%3A%20Dict%5Bstr%2C%20Any%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_is_valid%2C%20_metadata%20%3D%20_validator.validate(query_text.strip())%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%22is_valid%22%3A%20_is_valid%2C%20%22error%22%3A%20%22%22%20if%20_is_valid%20else%20str(_metadata)%7D%0A%20%20%20%20%20%20%20%20except%20Exception%20as%20e%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%7B%22is_valid%22%3A%20False%2C%20%22error%22%3A%20f%22Exception%3A%20%7Bstr(e)%7D%22%7D%0A%0A%20%20%20%20%23%20---%20Process%20Reasoning%20OFF%20Subset%20(up%20to%20200)%20---%0A%20%20%20%20_count_no%3A%20int%20%3D%20min(200%2C%20len(df_no_reason))%0A%20%20%20%20df_no_sample%20%3D%20df_no_reason.sample(n%3D_count_no%2C%20random_state%3D42).copy()%20if%20_count_no%20%3E%200%20else%20df_no_reason.copy()%0A%0A%20%20%20%20_results_no%20%3D%20df_no_sample%5B'content'%5D.apply(_validate_query)%0A%20%20%20%20df_no_sample%5B'is_valid'%5D%20%3D%20_results_no.apply(lambda%20x%3A%20x%5B'is_valid'%5D)%0A%20%20%20%20df_no_sample%5B'validation_error'%5D%20%3D%20_results_no.apply(lambda%20x%3A%20x%5B'error'%5D)%0A%0A%20%20%20%20%23%20---%20Process%20Reasoning%20ON%20Subset%20(up%20to%20200)%20---%0A%20%20%20%20_count_re%3A%20int%20%3D%20min(200%2C%20len(df_reason))%0A%20%20%20%20df_re_sample%20%3D%20df_reason.sample(n%3D_count_re%2C%20random_state%3D42).copy()%20if%20_count_re%20%3E%200%20else%20df_reason.copy()%0A%0A%20%20%20%20_results_re%20%3D%20df_re_sample%5B'query_text'%5D.apply(_validate_query)%0A%20%20%20%20df_re_sample%5B'is_valid'%5D%20%3D%20_results_re.apply(lambda%20x%3A%20x%5B'is_valid'%5D)%0A%20%20%20%20df_re_sample%5B'validation_error'%5D%20%3D%20_results_re.apply(lambda%20x%3A%20x%5B'error'%5D)%0A%0A%20%20%20%20_driver.close()%0A%0A%20%20%20%20%23%20Compute%20Statistics%20for%20Samples%0A%20%20%20%20total_no%3A%20int%20%3D%20len(df_no_sample)%0A%20%20%20%20valid_no%3A%20int%20%3D%20int(df_no_sample%5B'is_valid'%5D.sum())%0A%20%20%20%20invalid_no%3A%20int%20%3D%20total_no%20-%20valid_no%0A%20%20%20%20pct_invalid_no%3A%20float%20%3D%20(invalid_no%20%2F%20total_no%20*%20100)%20if%20total_no%20%3E%200%20else%200.0%0A%0A%20%20%20%20total_re%3A%20int%20%3D%20len(df_re_sample)%0A%20%20%20%20valid_re%3A%20int%20%3D%20int(df_re_sample%5B'is_valid'%5D.sum())%0A%20%20%20%20invalid_re%3A%20int%20%3D%20total_re%20-%20valid_re%0A%20%20%20%20pct_invalid_re%3A%20float%20%3D%20(invalid_re%20%2F%20total_re%20*%20100)%20if%20total_re%20%3E%200%20else%200.0%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20df_no_sample%2C%0A%20%20%20%20%20%20%20%20df_re_sample%2C%0A%20%20%20%20%20%20%20%20invalid_no%2C%0A%20%20%20%20%20%20%20%20invalid_re%2C%0A%20%20%20%20%20%20%20%20pct_invalid_no%2C%0A%20%20%20%20%20%20%20%20pct_invalid_re%2C%0A%20%20%20%20%20%20%20%20total_no%2C%0A%20%20%20%20%20%20%20%20total_re%2C%0A%20%20%20%20%20%20%20%20valid_no%2C%0A%20%20%20%20%20%20%20%20valid_re%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20invalid_no%3A%20int%2C%0A%20%20%20%20invalid_re%3A%20int%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20pct_invalid_no%3A%20float%2C%0A%20%20%20%20pct_invalid_re%3A%20float%2C%0A%20%20%20%20total_no%3A%20int%2C%0A%20%20%20%20total_re%3A%20int%2C%0A%20%20%20%20valid_no%3A%20int%2C%0A%20%20%20%20valid_re%3A%20int%2C%0A)%3A%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%23%20Validation%20Results%20Summary%20(Subset%20Sample%3A%20n%3D200%20per%20group)%0A%0A%20%20%20%20%7C%20Reasoning%20Mode%20%7C%20Total%20Sample%20%7C%20Valid%20Queries%20%7C%20Invalid%20Queries%20%7C%20%25%20Invalid%20%7C%0A%20%20%20%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%0A%20%20%20%20%7C%20**Reasoning%20OFF**%20%7C%20%7Btotal_no%7D%20%7C%20%7Bvalid_no%7D%20%7C%20%7Binvalid_no%7D%20%7C%20**%7Bpct_invalid_no%3A.2f%7D%25**%20%7C%0A%20%20%20%20%7C%20**Reasoning%20ON**%20%7C%20%7Btotal_re%7D%20%7C%20%7Bvalid_re%7D%20%7C%20%7Binvalid_re%7D%20%7C%20**%7Bpct_invalid_re%3A.2f%7D%25**%20%7C%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(df_no_sample%2C%20df_re_sample%2C%20mo)%3A%0A%20%20%20%20%23%20Sample%20invalid%20queries%20for%20both%0A%20%20%20%20%23%20Filter%20only%20rows%20with%20is_valid%3DFalse%0A%20%20%20%20_invalid_off_df%20%3D%20df_no_sample%5Bdf_no_sample%5B'is_valid'%5D%20%3D%3D%20False%5D%0A%20%20%20%20_invalid_on_df%20%3D%20df_re_sample%5Bdf_re_sample%5B'is_valid'%5D%20%3D%3D%20False%5D%0A%0A%20%20%20%20_invalid_off%20%3D%20_invalid_off_df%5B%5B'question'%2C%20'content'%2C%20'validation_error'%5D%5D.head(10)%0A%20%20%20%20_invalid_on%20%3D%20_invalid_on_df%5B%5B'question'%2C%20'query_text'%2C%20'validation_error'%5D%5D.head(10)%0A%0A%20%20%20%20_display%20%3D%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20mo.md(%22%23%23%23%20Sample%20Invalid%20Queries%3A%20Reasoning%20OFF%22)%2C%0A%20%20%20%20%20%20%20%20mo.ui.table(_invalid_off)%20if%20not%20_invalid_off.empty%20else%20mo.md(%22_No%20invalid%20queries%20found._%22)%2C%0A%20%20%20%20%20%20%20%20mo.md(%22%23%23%23%20Sample%20Invalid%20Queries%3A%20Reasoning%20ON%22)%2C%0A%20%20%20%20%20%20%20%20mo.ui.table(_invalid_on)%20if%20not%20_invalid_on.empty%20else%20mo.md(%22_No%20invalid%20queries%20found._%22)%0A%20%20%20%20%5D)%0A%20%20%20%20_display%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Any%2C%20Dict%2C%20List%2C%20ast%2C%20df_no_sample%2C%20df_re_sample%2C%20pd%2C%20re)%3A%0A%20%20%20%20def%20_clean_error(error_str%3A%20str)%20-%3E%20str%3A%0A%20%20%20%20%20%20%20%20%22%22%22Parse%20stringified%20list%20of%20errors%20and%20aggressively%20group%20by%20core%20category.%22%22%22%0A%20%20%20%20%20%20%20%20if%20not%20error_str%20or%20error_str%20%3D%3D%20%22Empty%20or%20None%20query%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20error_str%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Handle%20CyVer's%20string%20representation%20of%20list%20of%20dicts%0A%20%20%20%20%20%20%20%20%20%20%20%20_data%3A%20List%5BDict%5Bstr%2C%20Any%5D%5D%20%3D%20ast.literal_eval(error_str)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20not%20_data%20or%20not%20isinstance(_data%2C%20list)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20error_str%0A%20%20%20%20%20%20%20%20%20%20%20%20_desc%3A%20str%20%3D%20_data%5B0%5D.get('description'%2C%20'')%0A%20%20%20%20%20%20%20%20%20%20%20%20_desc_lower%3A%20str%20%3D%20_desc.lower()%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Broad%20category%20matching%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22invalid%20input%22%20in%20_desc_lower%20or%20%22extraneous%20input%22%20in%20_desc_lower%20or%20%22mismatched%20input%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Syntax%20Error%3A%20Invalid%20or%20unexpected%20input%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22unknown%20function%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Semantic%20Error%3A%20Unknown%20function%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22variable%22%20in%20_desc_lower%20and%20%22not%20defined%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Semantic%20Error%3A%20Variable%20not%20defined%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22type%20mismatch%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Semantic%20Error%3A%20Type%20mismatch%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22return%20can%20only%20be%20used%20at%20the%20end%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Syntax%20Error%3A%20RETURN%20must%20be%20at%20query%20end%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22query%20cannot%20conclude%20with%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Syntax%20Error%3A%20Query%20cannot%20conclude%20with%20clause%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22all%20sub%20queries%20in%20an%20union%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Semantic%20Error%3A%20UNION%20return%20columns%20mismatch%22%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20%22missing%22%20in%20_desc_lower%20and%20%22expected%22%20in%20_desc_lower%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Syntax%20Error%3A%20Missing%20expected%20token%22%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Fallback%3A%20remove%20anything%20in%20double%20quotes%20(usually%20query%20extracts)%2C%20then%20take%20text%20before%20colon%0A%20%20%20%20%20%20%20%20%20%20%20%20_clean%3A%20str%20%3D%20re.sub(r'%5C(line%20%5Cd%2B%2C%20column%20%5Cd%2B%20%5C(offset%3A%20%5Cd%2B%5C)%5C)'%2C%20''%2C%20_desc)%0A%20%20%20%20%20%20%20%20%20%20%20%20_clean%20%3D%20re.sub(r'%22.*%3F%22'%2C%20''%2C%20_clean).strip()%0A%20%20%20%20%20%20%20%20%20%20%20%20_clean%20%3D%20_clean.split('%3A')%5B0%5D.strip().replace('%5Cn'%2C%20'%20')%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20_clean%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20_clean%5B0%5D.upper()%20%2B%20_clean%5B1%3A%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%22Unknown%20Error%20Category%22%0A%0A%20%20%20%20%20%20%20%20except%20(ValueError%2C%20SyntaxError%2C%20Exception)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20error_str%0A%0A%20%20%20%20%23%20Process%20Reasoning%20OFF%20errors%0A%20%20%20%20_err_no%20%3D%20df_no_sample%5Bdf_no_sample%5B'is_valid'%5D%20%3D%3D%20False%5D%5B'validation_error'%5D.apply(_clean_error)%0A%20%20%20%20%23%20Process%20Reasoning%20ON%20errors%0A%20%20%20%20_err_re%20%3D%20df_re_sample%5Bdf_re_sample%5B'is_valid'%5D%20%3D%3D%20False%5D%5B'validation_error'%5D.apply(_clean_error)%0A%0A%20%20%20%20%23%20Combine%20for%20global%20ranking%0A%20%20%20%20err_ranking%20%3D%20pd.concat(%5B_err_no%2C%20_err_re%5D).value_counts().head(15)%0A%20%20%20%20return%20(err_ranking%2C)%0A%0A%0A%40app.cell%0Adef%20_(err_ranking%2C%20mo%2C%20plt)%3A%0A%20%20%20%20%23%20Ranking%20Chart%20of%20Common%20Syntax%20Errors%0A%20%20%20%20if%20err_ranking.empty%3A%0A%20%20%20%20%20%20%20%20_fig%20%3D%20mo.md(%22_No%20syntax%20errors%20found%20in%20the%20sample%20subsets._%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(14%2C%208))%0A%0A%20%20%20%20%20%20%20%20%23%20Truncate%20long%20error%20descriptions%20so%20they%20fit%20in%20the%20figure%20margins%0A%20%20%20%20%20%20%20%20_safe_index%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(str(lbl)%5B%3A75%5D%20%2B%20'...')%20if%20len(str(lbl))%20%3E%2075%20else%20str(lbl)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20lbl%20in%20err_ranking.index%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20_plot_series%20%3D%20err_ranking.copy()%0A%20%20%20%20%20%20%20%20_plot_series.index%20%3D%20_safe_index%0A%0A%20%20%20%20%20%20%20%20%23%20Sort%20so%20most%20frequent%20is%20at%20the%20top%0A%20%20%20%20%20%20%20%20_plot_series.iloc%5B%3A%3A-1%5D.plot(kind%3D'barh'%2C%20ax%3D_ax%2C%20color%3D'salmon'%2C%20alpha%3D0.9%2C%20edgecolor%3D'darkred')%0A%0A%20%20%20%20%20%20%20%20_ax.set_title(%22Most%20Common%20Cypher%20Syntax%20Errors%20(Top%2015%20Pattern%20Ranking)%22)%0A%20%20%20%20%20%20%20%20_ax.set_xlabel(%22Frequency%20(Combined%20Sample%20n%3D400)%22)%0A%20%20%20%20%20%20%20%20_ax.set_ylabel(%22Error%20Description%20(Cleaned)%22)%0A%0A%20%20%20%20%20%20%20%20%23%20Add%20labels%20to%20the%20end%20of%20bars%20for%20clarity%0A%20%20%20%20%20%20%20%20for%20i%2C%20v%20in%20enumerate(_plot_series.iloc%5B%3A%3A-1%5D)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_ax.text(v%20%2B%200.1%2C%20i%2C%20str(int(v))%2C%20color%3D'darkred'%2C%20va%3D'center'%2C%20fontweight%3D'bold')%0A%0A%20%20%20%20%20%20%20%20_ax.grid(axis%3D'x'%2C%20linestyle%3D'--'%2C%20alpha%3D0.3)%0A%20%20%20%20%20%20%20%20plt.tight_layout()%0A%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(invalid_no%3A%20int%2C%20invalid_re%3A%20int%2C%20np%2C%20plt%2C%20valid_no%3A%20int%2C%20valid_re%3A%20int)%3A%0A%20%20%20%20%23%20Grouped%20Bar%20Chart%3A%20Valid%20vs%20Invalid%20Comparison%20(Sampled%20Subset)%0A%20%20%20%20_categories%3A%20list%5Bstr%5D%20%3D%20%5B'Reasoning%20OFF'%2C%20'Reasoning%20ON'%5D%0A%20%20%20%20_valid_counts%3A%20list%5Bint%5D%20%3D%20%5Bvalid_no%2C%20valid_re%5D%0A%20%20%20%20_invalid_counts%3A%20list%5Bint%5D%20%3D%20%5Binvalid_no%2C%20invalid_re%5D%0A%0A%20%20%20%20_x%3A%20np.ndarray%20%3D%20np.arange(len(_categories))%0A%20%20%20%20_width%3A%20float%20%3D%200.35%0A%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(10%2C%206))%0A%20%20%20%20_ax.bar(_x%20-%20_width%2F2%2C%20_valid_counts%2C%20_width%2C%20label%3D'Valid'%2C%20color%3D'teal'%2C%20alpha%3D0.8)%0A%20%20%20%20_ax.bar(_x%20%2B%20_width%2F2%2C%20_invalid_counts%2C%20_width%2C%20label%3D'Invalid'%2C%20color%3D'crimson'%2C%20alpha%3D0.8)%0A%0A%20%20%20%20_ax.set_ylabel('Count')%0A%20%20%20%20_ax.set_title('Cypher%20Query%20Syntax%20Validation%20Comparison')%0A%20%20%20%20_ax.set_xticks(_x)%0A%20%20%20%20_ax.set_xticklabels(_categories)%0A%20%20%20%20_ax.legend()%0A%20%20%20%20_ax.grid(axis%3D'y'%2C%20alpha%3D0.3)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20_fig%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20df_no_reason%2C%0A%20%20%20%20df_reason%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20pct_invalid_no%3A%20float%2C%0A%20%20%20%20pct_invalid_re%3A%20float%2C%0A%20%20%20%20total_no%3A%20int%2C%0A%20%20%20%20total_re%3A%20int%2C%0A%20%20%20%20valid_no%3A%20int%2C%0A%20%20%20%20valid_re%3A%20int%2C%0A)%3A%0A%20%20%20%20_avg_len_no%20%3D%20df_no_reason%5B'query_length'%5D.mean()%20if%20not%20df_no_reason.empty%20else%200%0A%20%20%20%20_avg_len_re%20%3D%20df_reason%5B'query_length'%5D.mean()%20if%20not%20df_reason.empty%20else%200%0A%20%20%20%20_avg_think_len%20%3D%20df_reason%5B'thinking_length'%5D.mean()%20if%20not%20df_reason.empty%20else%200%0A%0A%20%20%20%20%23%20Calculate%20the%20improvement%20or%20degradation%20in%20validity%0A%20%20%20%20_diff_validity%20%3D%20pct_invalid_no%20-%20pct_invalid_re%0A%20%20%20%20_validity_msg%20%3D%20%22%22%0A%20%20%20%20if%20_diff_validity%20%3E%200%3A%0A%20%20%20%20%20%20%20%20_validity_msg%20%3D%20f%22Reasoning%20ON%20improved%20syntax%20validity%20by%20**%7B_diff_validity%3A.2f%7D%25**.%22%0A%20%20%20%20elif%20_diff_validity%20%3C%200%3A%0A%20%20%20%20%20%20%20%20_validity_msg%20%3D%20f%22Reasoning%20ON%20actually%20increased%20syntax%20errors%20by%20**%7Babs(_diff_validity)%3A.2f%7D%25**.%22%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20_validity_msg%20%3D%20%22Reasoning%20mode%20had%20no%20impact%20on%20syntax%20validity%20percentage.%22%0A%0A%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%20Conclusion%3A%20Key%20Discoveries%0A%0A%20%20%20%20Based%20on%20the%20analysis%20of%20**Qwen%2FQwen3.5-4B**%20on%20the%20**LC-QuAD%202.0**%20dataset%2C%20we%20have%20observed%20the%20following%3A%0A%0A%20%20%20%20%23%23%23%201.%20Structural%20Complexity%0A%20%20%20%20-%20**Query%20Length%3A**%20Enabling%20reasoning%20leads%20to%20an%20average%20query%20length%20of%20**%7B_avg_len_re%3A.1f%7D**%20characters%2C%20compared%20to%20**%7B_avg_len_no%3A.1f%7D**%20characters%20when%20reasoning%20is%20disabled.%20%0A%20%20%20%20-%20**Thinking%20Overhead%3A**%20The%20model%20generates%20an%20average%20of%20**%7B_avg_think_len%3A.1f%7D**%20characters%20of%20internal%20reasoning%20before%20outputting%20the%20final%20Cypher%20query.%0A%0A%20%20%20%20%23%23%23%202.%20Syntactic%20Reliability%20(Subset%20n%3D200)%0A%20%20%20%20-%20**Reasoning%20OFF%3A**%20Successfully%20generated%20**%7Bvalid_no%7D**%20valid%20queries%20out%20of%20%7Btotal_no%7D%20(**%7B100-pct_invalid_no%3A.2f%7D%25**%20success%20rate).%0A%20%20%20%20-%20**Reasoning%20ON%3A**%20Successfully%20generated%20**%7Bvalid_re%7D**%20valid%20queries%20out%20of%20%7Btotal_re%7D%20(**%7B100-pct_invalid_re%3A.2f%7D%25**%20success%20rate).%0A%20%20%20%20-%20**Impact%3A**%20%7B_validity_msg%7D%0A%0A%20%20%20%20%23%23%23%20Final%20Takeaway%0A%20%20%20%20The%20data%20suggests%20that%20while%20the%20internal%20reasoning%20process%20(thinking)%20adds%20significant%20token%20overhead%2C%20it%20%7B%22significantly%22%20if%20abs(_diff_validity)%20%3E%205%20else%20%22slightly%22%7D%20affects%20the%20grammatical%20correctness%20of%20the%20resulting%20Cypher.%20This%20analysis%20serves%20as%20a%20baseline%20for%20further%20ontology-constrained%20fine-tuning.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%20Next%20Steps%20%26%20Future%20Work%0A%0A%20%20%20%20To%20improve%20the%20efficiency%20and%20reliability%20of%20the%20cypher%20query%20generation%2C%20the%20following%20objectives%20have%20been%20identified%3A%0A%0A%20%20%20%20%23%23%23%201.%20Optimize%20Reasoning%20Efficiency%0A%20%20%20%20Reduce%20the%20character%20length%20of%20the%20reasoning%20process%20(%60%3Cthink%3E%60%20block)%20without%20compromising%20query%20quality.%20This%20can%20be%20achieved%20through%3A%0A%20%20%20%20-%20**Prompt%20Engineering%3A**%20Refining%20instructions%20to%20encourage%20%22concise%20but%20logical%22%20derivations.%0A%0A%20%20%20%20%23%23%23%202.%20Minimize%20Error%20Frequency%0A%20%20%20%20Address%20common%20syntax%20and%20semantic%20errors%20discovered%20in%20the%20current%20benchmarks%3A%0A%20%20%20%20-%20**Prompt%20Engineering%3A**%20Add%20examples%20or%20guidelines%20to%20avoid%20common%20errors.%0A%20%20%20%20-%20**Self-Correction%3A**%20Allow%20the%20LLM%20to%20retry%20if%20the%20query%20is%20invalid.%0A%20%20%20%20-%20**Ontology%20Awareness%3A**%20Injecting%20more%20specific%20medical%20ontology%20constraints%20into%20the%20system%20prompt.%0A%20%20%20%20-%20**Error-Correcting%20Fine-Tuning%3A**%20Training%20on%20a%20%22synthetic%20correction%22%20dataset%20where%20the%20model%20learns%20to%20fix%20its%20own%20previous%20mistakes.%0A%0A%20%20%20%20%23%23%23%203.%20Enforce%20Structured%20Query%20Generation%0A%20%20%20%20Standardize%20the%20model's%20output%20format%20to%20ensure%20maximum%20parseability%3A%0A%20%20%20%20-%20**Strict%20Query%20Format%3A**%20Make%20components%20of%20Cypher%20query%20(like%20MATCH%2C%20RETURN%2C%20...)%20follow%20a%20strict%20order%20to%20allow%20better%20parsing.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
1afc38fce21ff4c875207a0b8b1f6f89