@furongjun1999/dsh-memory 0.4.7 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -47
- package/codebuddy/CODEBUDDY.md +21 -10
- package/codebuddy/README.md +13 -1
- package/codebuddy/mcp.json +9 -0
- package/docs/GBrain/345/217/257/345/200/237/351/211/264/347/202/271_/347/201/265/346/236/242/350/220/275/347/202/271/344/272/244/346/216/245_20260919.md +169 -0
- package/docs/Pi/345/217/257/345/255/246/344/271/240/344/274/230/347/202/271_/347/201/265/346/236/242/345/244/247/350/204/221/346/224/271/350/277/233/344/272/244/346/216/245_20260915.md +144 -0
- package/docs/README.md +111 -0
- package/docs/discipline/harnesses.yaml +226 -152
- package/docs/discipline/templates/full.md.tmpl +61 -58
- package/docs/eval//347/254/254/344/270/211/346/226/271/351/252/214/350/257/201/346/212/245/345/221/212_LoCoMo_/347/201/265/346/236/242_.md +127 -0
- package/docs/eval//347/254/254/344/270/211/346/226/271/351/252/214/350/257/201/346/212/245/345/221/212_LoCoMo_/347/201/265/346/236/242_.png +0 -0
- package/docs/eval//347/254/254/344/270/211/346/226/271/351/252/214/350/257/201/346/212/245/345/221/212_/347/201/265/346/236/242_vs_dejavu_/347/273/237/344/270/200/350/257/204/345/210/206_v7.md +202 -0
- package/docs/experiments/linkref_backfill/candidates_20260917.json +726 -0
- package/docs/experiments/linkref_backfill/candidates_internal_20260917.json +602 -0
- package/docs/experiments/linkref_backfill/candidates_internal_v2.json +603 -0
- package/docs/experiments/linkref_backfill/candidates_secret_20260917.json +884 -0
- package/docs/experiments/linkref_backfill/candidates_secret_v2.json +789 -0
- package/docs/experiments/m4-role-probe/census.py +86 -0
- package/docs/experiments/m4-role-probe/probe.py +89 -0
- package/docs/experiments/mapped_confidence/bench_mapped_conf.py +216 -0
- package/docs/experiments/mapped_confidence/post_check.py +75 -0
- package/docs/experiments/mapped_confidence/repro_thirdparty_tol.py +83 -0
- package/docs/experiments/mapped_confidence/result_mapped_conf.json +215 -0
- package/docs/hive//345/244/232/347/253/257harness/351/200/232/344/277/241/345/245/221/347/272/246_v0.1.md +42 -0
- package/docs/hive//346/243/200/347/264/242/346/224/266/346/225/233/345/256/236/346/265/213/344/270/216S1b/350/256/276/350/256/241_v0.1.md +43 -0
- package/docs/hive//346/243/200/347/264/242/350/267/257/345/276/204/344/270/216/350/256/244/347/237/245/347/273/223/346/236/204/345/245/221/347/272/246_v0.1.md +102 -0
- package/docs/hive//347/234/237/345/256/236/345/272/223/347/253/257/345/210/260/347/253/257/345/256/236/346/265/213_S1b/344/270/216/345/217/254/345/233/236/346/235/203/350/241/241_v0.1.md +57 -0
- package/docs/hive//347/234/237/345/256/236/345/272/223/347/253/257/345/210/260/347/253/257/345/256/236/346/265/213_S7/345/200/222/346/216/222/345/200/231/351/200/211/345/261/202_v0.1.md +126 -0
- package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +503 -0
- package/docs/{ → hive/}/350/234/202/345/267/242/345/267/245/344/275/234/350/256/260/345/277/206_/351/241/271/347/233/256/350/256/241/345/210/222.md +14 -2
- package/docs/mdcg/D_meta_/345/267/245/347/250/213/345/214/226/346/226/271/346/241/210_v0.2.md +216 -0
- package/docs/{README → mdcg/README}/350/257/246/347/273/206/347/211/210_v0.4.5.md +631 -625
- package/docs/{ → mdcg/}/344/270/273/344/273/243/347/220/206/345/255/220/344/273/243/347/220/206/350/256/260/345/277/206/346/236/266/346/236/204/350/256/276/350/256/241.md +1 -1
- package/docs/mdcg//344/273/243/347/240/201/350/257/204/345/256/241/344/270/216/346/235/241/344/273/266/345/214/226/346/263/250/351/207/212_/345/245/221/347/272/246_v0.1.md +82 -0
- package/docs/mdcg//345/205/250/345/272/223/344/273/243/347/240/201/350/257/204/345/256/241/344/270/216/346/235/241/344/273/266/345/214/226/346/263/250/351/207/212_/350/256/241/345/210/222_v0.1.md +600 -0
- package/docs/mdcg//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +263 -0
- package/docs/{ → mdcg/}/345/215/225/345/205/203/350/207/252/346/210/221/351/224/232/347/202/271_/347/263/273/347/273/237/346/217/220/347/244/272/350/257/215/346/240/207/345/207/206_v0.3.md +1 -1
- package/docs/mdcg//345/255/220/344/273/243/347/220/206/351/205/215/347/275/256/346/240/207/345/207/206_v0.5.md +236 -0
- package/docs/{ → mdcg/}/346/272/220/347/240/201/347/272/247/346/236/266/346/236/204/345/256/241/350/256/241_GPT/346/211/271/350/257/204/345/257/271/347/205/247_v1.0.md +2 -2
- package/docs/{ → mdcg/}/347/201/265/346/236/242/344/270/211/345/261/202/346/213/206/345/210/206/350/247/204/345/210/222_v0.1.md +181 -181
- package/docs/mdcg//347/201/265/346/236/242/350/256/260/345/277/206/345/212/250/350/257/215/345/215/217/350/256/256_v1.0-draft.md +172 -0
- package/docs/mdcg//347/216/257/344/272/214_/347/231/275/347/256/261/345/241/253/345/205/205/346/265/201/346/260/264/347/272/277_v0.1.md +31 -0
- package/docs/{ → mdcg/}/347/274/272/345/217/243/345/215/225_P0/346/224/266/345/217/243_v0.1.md +2 -2
- package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276_G4-G8/347/274/272/345/217/243/350/243/201/345/256/232/345/215/225_v0.1.md +1 -1
- package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276_/347/264/242/345/274/225/344/270/216/345/267/245/347/250/213/350/247/204/350/214/203/345/214/226_/350/256/241/345/210/222_v0.1.md +4 -4
- package/docs/{ → mdcg/}/350/256/260/345/277/206/346/223/215/344/275/234/347/263/273/347/273/237_MdCGOS/344/270/216MCP/346/216/245/345/205/245_v0.1.md +2 -2
- package/docs/mdcg//350/267/250/347/253/257/351/252/214/350/257/201/344/270/216/345/220/214/346/255/245/345/215/217/350/256/256_v0.1.md +93 -0
- package/docs/plans/GridWorld/346/234/200/345/260/217/351/227/255/347/216/257/350/247/204/346/240/274_v0.1.md +176 -0
- package/docs/{ → swarm/}/350/234/202/347/276/244/344/272/222/350/201/224_v0.1.md +3 -3
- package/docs/swarm//350/234/202/347/276/244/345/220/214/351/224/231/346/243/200/346/265/213/345/256/236/351/252/214/345/215/217/350/256/256_v0.1.md +242 -0
- package/docs/theory//345/215/225/347/272/277/347/250/213/344/270/216/346/263/250/346/204/217/345/212/233/351/233/206/344/270/255_/346/227/240/344/272/211/350/256/256/347/220/206/350/256/272/346/226/207/346/241/243_v1.0.md +129 -0
- package/docs/theory//345/271/266/345/217/221/345/277/205/347/204/266/346/200/247/347/220/206/350/256/272_v0.2.md +134 -0
- package/docs/theory//346/246/202/345/277/265/345/210/206/345/261/202/345/257/271/351/275/220/350/241/250_v0.1.md +145 -0
- package/docs/{ → theory/}/347/220/206/350/256/272_/346/234/272/345/210/266_/344/273/243/347/240/201_/345/256/236/351/252/214_/347/274/272/345/217/243/347/237/251/351/230/265_v0.1.md +6 -6
- package/docs/{ → theory/}/347/220/206/350/256/272/344/273/223/346/213/206/345/210/206/344/270/216/347/231/275/347/256/261/347/237/245/350/257/206/345/272/223/345/206/205/350/277/201_v0.1.md +1 -1
- package/docs/theory//350/256/244/347/237/245/344/273/243/347/220/206/344/270/216/346/224/266/346/225/233/347/273/223/346/236/204_/346/235/241/344/273/266/350/256/272/351/207/215/346/236/204_v0.1.md +221 -0
- package/docs/world_model//344/270/226/347/225/214/346/250/241/345/236/213_/347/245/236/347/273/217/347/275/221/347/273/234/345/272/225/345/261/202/346/236/266/346/236/204_v1.0.md +237 -0
- package/docs//345/255/230/347/256/227/344/270/200/344/275/223/346/236/266/346/236/204/345/255/246/344/271/240_/345/244/226/351/203/250/347/220/206/350/256/272/345/257/271/347/205/247/344/270/216/350/267/257/347/272/277/344/272/244/346/216/245_20260916.md +98 -0
- package/docs//345/255/230/347/256/227/344/270/200/344/275/223/347/245/236/347/273/217/347/275/221/347/273/234/346/236/266/346/236/204_/346/200/273/347/272/262/344/270/216/344/272/244/346/216/245_20260916.md +109 -0
- package/docs//345/267/245/344/275/234/347/272/252/345/276/213_/350/256/244/347/237/245/345/233/276/346/235/241/347/233/256_v1.1.json +434 -405
- package/docs//347/201/265/346/236/242/350/207/252/346/210/221/346/224/271/350/277/233/345/267/245/344/275/234/350/256/241/345/210/222_/345/244/226/351/203/250/347/240/224/347/251/266/347/263/273/345/210/227/345/220/270/346/224/266_v1_20260919.md +286 -0
- package/docs//347/231/275/347/256/261/345/214/226/347/272/262/351/242/206_/344/270/211/351/241/271/347/233/256/345/255/246/344/271/240/346/200/273/346/236/266/346/236/204/344/270/216Ghidra/344/272/244/346/216/245_20260916.md +104 -0
- package/docs//350/256/260/345/277/206/350/257/204/345/256/241/347/263/273/347/273/237_/347/253/213/351/241/271/350/256/276/350/256/241/344/270/216/346/226/275/345/267/245/344/272/244/346/216/245_20260915.md +183 -0
- package/dsh/README.md +34 -1
- package/dsh/cordis.yml.example +13 -7
- package/dsh/hive-mcp-probe.mjs +94 -0
- package/dsh/hive-mcp.example.yml +62 -0
- package/dsh/update-lingshu.bat +11 -0
- package/dsh/update-lingshu.ps1 +337 -0
- package/lib/hooks.d.ts +8 -0
- package/lib/hooks.js +27 -24
- package/lib/index.d.ts +4 -2
- package/lib/index.js +29 -6
- package/lib/lib/datapath.d.ts +76 -1
- package/lib/lib/datapath.js +199 -13
- package/lib/lib/mdcg_client.d.ts +6 -3
- package/lib/lib/mdcg_client.js +6 -5
- package/lib/lib/mutual.js +4 -4
- package/lib/lib/prompt_safety.d.ts +48 -0
- package/lib/lib/prompt_safety.js +62 -0
- package/lib/lib/token_store.js +4 -5
- package/md_cg/audit.py +91 -2
- package/md_cg/autonomy.py +86 -15
- package/md_cg/backfill.py +36 -1
- package/md_cg/backfill_bigdomain.py +34 -0
- package/md_cg/bench6_arms.py +28 -1
- package/md_cg/bench6_common.py +10 -1
- package/md_cg/bench6_competitors.py +6 -1
- package/md_cg/bench_axis_domain.py +9 -1
- package/md_cg/bench_blind_comp.py +7 -1
- package/md_cg/bench_en_atoms_public.py +9 -0
- package/md_cg/bench_governance.py +348 -0
- package/md_cg/bench_lme_zh.py +16 -1
- package/md_cg/bench_locomo.py +2 -1
- package/md_cg/bench_locomo_zh.py +16 -1
- package/md_cg/bench_locomo_zh_public.py +4 -1
- package/md_cg/bench_longmem.py +2 -1
- package/md_cg/bench_membench.py +37 -6
- package/md_cg/bench_p0.py +4 -1
- package/md_cg/bench_progressive.py +61 -10
- package/md_cg/bench_role_views.py +238 -0
- package/md_cg/bench_task_ab.py +8 -1
- package/md_cg/bench_task_ab_llm.py +13 -1
- package/md_cg/bench_unified_en.py +6 -1
- package/md_cg/bench_zh_mad.py +20 -1
- package/md_cg/blindspot_tickets.py +123 -0
- package/md_cg/branches.py +286 -0
- package/md_cg/build_postings.py +73 -0
- package/md_cg/ccgc.py +949 -0
- package/md_cg/census.py +5 -1
- package/md_cg/chain.py +24 -3
- package/md_cg/codeindex.py +134 -17
- package/md_cg/coldverify.py +265 -0
- package/md_cg/comment_gate.py +338 -0
- package/md_cg/cond_compose.py +190 -0
- package/md_cg/cond_facts.py +155 -0
- package/md_cg/cond_template.json +107 -0
- package/md_cg/condition_anchor.py +143 -0
- package/md_cg/conformance.py +727 -0
- package/md_cg/consistency.py +25 -2
- package/md_cg/consolidate.py +53 -2
- package/md_cg/corpus.py +5 -1
- package/md_cg/crosscheck.py +42 -2
- package/md_cg/crypto.py +35 -1
- package/md_cg/d_meta.py +310 -0
- package/md_cg/datapath.py +201 -26
- package/md_cg/docindex.py +122 -1
- package/md_cg/eval_common.py +35 -6
- package/md_cg/evidence.py +27 -1
- package/md_cg/evolution.py +21 -1
- package/md_cg/export.py +11 -1
- package/md_cg/forgetting.py +34 -4
- package/md_cg/fsutil.py +81 -2
- package/md_cg/hotcache.py +214 -0
- package/md_cg/hyperedge.py +251 -0
- package/md_cg/identity.py +20 -3
- package/md_cg/insight.py +19 -3
- package/md_cg/lexicon/build_cedict_en_zh.py +9 -0
- package/md_cg/lexicon/build_standard_en.py +171 -168
- package/md_cg/lexicon/expand_en_zh.py +6 -0
- package/md_cg/lifecycle.py +273 -0
- package/md_cg/linkref.py +281 -0
- package/md_cg/links.py +29 -1
- package/md_cg/mcp_server.py +894 -168
- package/md_cg/md_whitebox.py +53 -1
- package/md_cg/mdcg.py +1205 -41
- package/md_cg/mdcos.py +1060 -76
- package/md_cg/metacognition.py +39 -4
- package/md_cg/migrate.py +4 -0
- package/md_cg/migrate_aeis.py +221 -213
- package/md_cg/migrate_roleplay.py +8 -0
- package/md_cg/migrate_wisdom_graph.py +14 -1
- package/md_cg/mreview/__init__.py +25 -0
- package/md_cg/mreview/__main__.py +110 -0
- package/md_cg/mreview/bundle.py +178 -0
- package/md_cg/mreview/candidates.py +262 -0
- package/md_cg/mreview/govern.py +694 -0
- package/md_cg/mreview/locate.py +939 -0
- package/md_cg/mreview/pipeline.py +729 -0
- package/md_cg/mreview/rules/duplication.json +21 -0
- package/md_cg/mreview/rules/field_coverage.json +54 -0
- package/md_cg/mreview/rules/source_license.json +21 -0
- package/md_cg/mreview/rules/template_flow.json +21 -0
- package/md_cg/mreview/ruleset.py +253 -0
- package/md_cg/nodefile.py +269 -1
- package/md_cg/pooling.py +23 -1
- package/md_cg/postings.py +298 -0
- package/md_cg/predict.py +113 -15
- package/md_cg/progressive.py +3 -0
- package/md_cg/protect.py +18 -5
- package/md_cg/protocol.py +372 -0
- package/md_cg/provenance.py +262 -0
- package/md_cg/reach.py +453 -0
- package/md_cg/refindex.py +88 -4
- package/md_cg/refine.py +20 -1
- package/md_cg/roleviews.py +89 -0
- package/md_cg/routing.py +76 -0
- package/md_cg/scrub.py +68 -3
- package/md_cg/security.py +26 -1
- package/md_cg/self_state.py +65 -2
- package/md_cg/selfreport.py +151 -0
- package/md_cg/semantic/canonical.py +5 -0
- package/md_cg/semantic/en_normalizer.py +364 -295
- package/md_cg/semantic/zh_en_atoms.py +139 -136
- package/md_cg/signer.py +41 -1
- package/md_cg/sources.py +583 -547
- package/md_cg/statushdr.py +179 -0
- package/md_cg/stg.py +59 -18
- package/md_cg/subgraph.py +23 -0
- package/md_cg/sustain.py +74 -1
- package/md_cg/tasks.py +471 -0
- package/md_cg/test_action_derive.py +203 -0
- package/md_cg/test_audit_rotate.py +270 -0
- package/md_cg/test_autonomy.py +26 -0
- package/md_cg/test_bench_governance.py +102 -0
- package/md_cg/test_blindspot_tickets.py +166 -0
- package/md_cg/test_branches.py +249 -0
- package/md_cg/test_ccg_perturb.py +1 -1
- package/md_cg/test_ccgc.py +433 -0
- package/md_cg/test_codeindex.py +338 -0
- package/md_cg/test_comment_gate.py +187 -0
- package/md_cg/test_cond_compose_anchors.py +76 -0
- package/md_cg/test_condition_anchor.py +82 -0
- package/md_cg/test_conformance.py +343 -0
- package/md_cg/test_d_meta.py +412 -0
- package/md_cg/test_datapath_root.py +188 -0
- package/md_cg/test_en_pipeline.py +24 -0
- package/md_cg/test_gain_gate.py +47 -1
- package/md_cg/test_health_scale.py +173 -0
- package/md_cg/test_hot_cold.py +187 -0
- package/md_cg/test_hyperedge.py +245 -0
- package/md_cg/test_identity_attribution.py +6 -0
- package/md_cg/test_index_durability.py +224 -0
- package/md_cg/test_lifecycle.py +309 -0
- package/md_cg/test_linkref.py +306 -0
- package/md_cg/test_md_access_parity.py +15 -3
- package/md_cg/test_mr_m1.py +769 -0
- package/md_cg/test_mr_m2.py +587 -0
- package/md_cg/test_mr_m3.py +710 -0
- package/md_cg/test_mr_m4.py +485 -0
- package/md_cg/test_p1.py +1 -1
- package/md_cg/test_p11_consistency.py +1 -1
- package/md_cg/test_p12_metacognition.py +2 -2
- package/md_cg/test_p16_self_state.py +1 -1
- package/md_cg/test_p26_refindex.py +50 -21
- package/md_cg/test_p27_docindex.py +258 -4
- package/md_cg/test_p28_refcheck.py +1 -1
- package/md_cg/test_p29_session_ingest_export.py +1 -1
- package/md_cg/test_p2_mcp.py +7 -1
- package/md_cg/test_p31_insight.py +24 -0
- package/md_cg/test_p38_contextualize.py +1 -1
- package/md_cg/test_p39_vision_evidence.py +1 -1
- package/md_cg/test_p40_refine_worklist.py +1 -1
- package/md_cg/test_p41_evolve_patrol.py +1 -1
- package/md_cg/test_p42_provenance.py +1 -1
- package/md_cg/test_p43_pooling.py +41 -13
- package/md_cg/test_p44_md_whitebox.py +14 -1
- package/md_cg/test_protocol.py +243 -0
- package/md_cg/test_reach.py +378 -0
- package/md_cg/test_reach_keys.py +201 -0
- package/md_cg/test_reach_meta_exits.py +145 -0
- package/md_cg/test_read_clip.py +141 -0
- package/md_cg/test_retr_s1.py +340 -0
- package/md_cg/test_retr_s1b.py +209 -0
- package/md_cg/test_retr_s3.py +194 -0
- package/md_cg/test_retr_s4.py +163 -0
- package/md_cg/test_retr_s5.py +200 -0
- package/md_cg/test_retr_s6.py +157 -0
- package/md_cg/test_retr_s7.py +385 -0
- package/md_cg/test_retr_s8_time.py +316 -0
- package/md_cg/test_retr_s9_edges.py +286 -0
- package/md_cg/test_retr_s9_entity_ctx.py +175 -0
- package/md_cg/test_review_conformance.py +367 -0
- package/md_cg/test_role_views.py +354 -0
- package/md_cg/test_tasks.py +409 -0
- package/md_cg/test_tool_face.py +189 -0
- package/md_cg/test_trust.py +361 -0
- package/md_cg/test_twophase.py +286 -0
- package/md_cg/test_units_poll.py +71 -0
- package/md_cg/test_v14_fixes.py +397 -0
- package/md_cg/test_validity_filter.py +280 -0
- package/md_cg/test_wisdom_md_store.py +7 -3
- package/md_cg/test_writepipe.py +214 -0
- package/md_cg/theory.py +17 -2
- package/md_cg/tokens.py +134 -12
- package/md_cg/tool_face.py +261 -0
- package/md_cg/trust.py +943 -0
- package/md_cg/twophase.py +232 -0
- package/md_cg/units.py +665 -0
- package/md_cg/vision_evidence.py +25 -2
- package/md_cg/weights.py +25 -2
- package/md_cg/whitebox.py +33 -2
- package/md_cg/whitebox_kb/data/verify_cache.json +21233 -360
- package/md_cg/whitebox_kb/data/verify_savings.jsonl +5124 -0
- package/md_cg/whitebox_kb/wisdom/audit_log/chain_heat.json +10 -10
- package/md_cg/whitebox_kb/wisdom/code_compose.py +113 -6
- package/md_cg/whitebox_kb/wisdom/code_solidified.json +1 -1
- package/md_cg/whitebox_kb/wisdom/verifier.py +340 -55
- package/md_cg/whitebox_kb/wisdom/wisdom-book-cloud.db +0 -0
- package/md_cg/writelimit.py +37 -7
- package/md_cg/writepipe.py +543 -0
- package/package.json +2 -2
- package/skills/skills/designer-perspective/scripts/__pycache__/designer.cpython-310.pyc +0 -0
- package/skills/skills/designer-perspective/scripts/designer.py +17 -1
- package/skills/skills/designer-perspective/tests/selftest.py +3 -1
- package/src/hooks.ts +27 -22
- package/src/index.ts +33 -6
- package/src/lib/datapath.ts +211 -13
- package/src/lib/mdcg_client.ts +12 -8
- package/src/lib/mutual.ts +411 -411
- package/src/lib/prompt_safety.ts +62 -0
- package/src/lib/token_store.ts +4 -5
- package/zcode/AGENTS.md +21 -10
- package/zcode/README.md +4 -0
- package/docs//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +0 -221
- /package/docs/{AGI → eval/AGI}/344/270/203/347/273/264/350/257/204/345/210/206/346/212/245/345/221/212_md_cg_v1.0.md" +0 -0
- /package/docs/{AGI → eval/AGI}/344/270/203/347/273/264/350/257/204/345/210/206/346/212/245/345/221/212_md_cg_v2.0.md" +0 -0
- /package/docs/{ → eval/}/345/256/236/351/252/214/346/226/271/346/241/210_/345/255/246/344/271/240/351/227/255/347/216/257AB/344/270/216/346/250/252/350/257/204_v1.0.md" +0 -0
- /package/docs/{ → eval/}/346/250/252/350/257/204_/345/205/255/345/256/266100/351/242/230/344/270/255/350/213/261/345/217/214/346/237/245_v1.0.md" +0 -0
- /package/docs/{guardrail-charter.md → mdcg/guardrail-charter.md} +0 -0
- /package/docs/{lingshu_tutorial.html → mdcg/lingshu_tutorial.html} +0 -0
- /package/docs/{memory-assessment.html → mdcg/memory-assessment.html} +0 -0
- /package/docs/{memory_score.html → mdcg/memory_score.html} +0 -0
- /package/docs/{memory_score.png → mdcg/memory_score.png} +0 -0
- /package/docs/{release_v0.3.0.md → mdcg/release_v0.3.0.md} +0 -0
- /package/docs/{release_v0.4.5.md → mdcg/release_v0.4.5.md} +0 -0
- /package/docs/{tool_table_v0.3.0.md → mdcg/tool_table_v0.3.0.md} +0 -0
- /package/docs/{ → mdcg/}/344/273/244/347/211/214/344/270/216/350/247/222/350/211/262/346/235/203/350/201/214/345/210/206/347/246/273_v0.1.md" +0 -0
- /package/docs/{ → mdcg/}/347/201/265/346/236/24282/345/267/245/345/205/267_/345/212/237/350/203/275/346/225/264/347/220/206/344/270/216/350/277/201/347/247/273/346/230/240/345/260/204_v0.1.md" +0 -0
- /package/docs/{ → mdcg/}/347/201/265/346/236/242MCP/345/267/245/345/205/267/346/200/273/350/241/250_v3.4.md" +0 -0
- /package/docs/{ → mdcg/}/347/201/265/346/236/242_/350/207/252/346/210/221/345/261/202/345/256/232/344/271/211.md" +0 -0
- /package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276_MD/347/233/256/345/275/225/346/226/271/346/241/210_v0.1.md" +0 -0
- /package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276_/346/235/241/344/273/266/347/251/272/351/227/264/345/220/210/346/210/220/344/270/216/347/224/237/346/225/210/346/235/241/344/273/266/345/217/243/345/276/204_v0.1.md" +0 -0
- /package/docs/{ → mdcg/}/350/256/244/347/237/245/345/233/276/344/275/234/344/270/272/350/256/260/345/277/206/346/223/215/344/275/234/347/263/273/347/273/237_/350/257/204/344/274/260/344/270/216/350/267/257/347/272/277_v0.1.md" +0 -0
- /package/docs/{ → plans/}/345/221/275/345/220/215/346/262/273/347/220/206_/351/241/271/347/233/256/350/256/241/345/210/222.md" +0 -0
- /package/docs/{ → plans/}/347/237/245/350/257/206/345/233/276/350/260/261/351/241/271/347/233/256_/344/272/244/346/216/245/346/226/207/346/241/243_20260914.md" +0 -0
- /package/docs/{ → swarm/}/350/234/202/347/276/244/345/244/232/346/231/272/350/203/275/344/275/223_/344/275/277/347/224/250/346/212/245/345/221/212_20260913.md" +0 -0
- /package/docs/{ → swarm/}/350/234/202/347/276/244/345/244/232/346/231/272/350/203/275/344/275/223_/345/212/237/350/203/275/350/257/264/346/230/216_v0.6.md" +0 -0
- /package/docs/{ → swarm/}/350/234/202/347/276/244/347/233/262/345/214/272/346/240/207/350/256/260_v1.0.md" +0 -0
- /package/docs/{ → theory/}/344/277/241/346/201/257/345/267/256/344/270/272/344/273/200/344/271/210/345/277/205/347/204/266/345/255/230/345/234/250/344/270/224/350/207/252/347/204/266/346/211/251/345/244/247.md" +0 -0
- /package/docs/{ → theory/}/346/231/272/350/203/275/347/232/204/345/205/254/347/220/206/345/214/226/345/237/272/347/237/263.md" +0 -0
- /package/docs/{ → theory/}/346/231/272/350/203/275/347/232/204/350/256/244/347/237/245/350/277/207/347/250/213.md" +0 -0
- /package/docs/{ → theory/}/346/231/272/350/203/275/350/256/2723.4.md" +0 -0
- /package/docs/{ → theory/}/347/231/275/347/256/261/346/231/272/350/203/275/346/230/257/344/273/200/344/271/210/357/274/237.md" +0 -0
- /package/docs/{ → theory/}/347/231/275/347/256/261/346/231/272/350/203/275/347/263/273/345/210/227/302/267/347/254/254/344/272/224/347/257/207/357/274/232/350/256/251AI/347/234/237/346/255/243/350/243/205/344/270/212/350/256/260/345/277/206.md" +0 -0
|
@@ -88,6 +88,7 @@ PATHSETS = (("lexical",), ("lexical", "bucket"),
|
|
|
88
88
|
|
|
89
89
|
# ------------------------------------------------------------------ 写入侧加工
|
|
90
90
|
|
|
91
|
+
# 生效条件:c 含 'zh_fields' 且其中 identity/time/summary/terms/condition 均存在时,返回按身份、时间、摘要、词、条件及 c['text'] 拼成的正文,缺任一键则抛 KeyError;
|
|
91
92
|
def body_of(c):
|
|
92
93
|
"""正文:与 bench_zh_mad.build_arm 的 a0 臂**逐字一致**(无意图行/无承接行)。"""
|
|
93
94
|
f = c["zh_fields"]
|
|
@@ -102,6 +103,7 @@ def body_of(c):
|
|
|
102
103
|
])
|
|
103
104
|
|
|
104
105
|
|
|
106
|
+
# 生效条件:c 含 'zh_fields',terms 可迭代且 summary 经 str() 后参与空白切分时,将 terms 与切分词合并后交 routing.big_domain_classify 返回域判定结果;
|
|
105
107
|
def write_domain(c):
|
|
106
108
|
"""写入侧域判定:只读 turn 自身的 zh_fields(盲于查询集)。"""
|
|
107
109
|
f = c["zh_fields"]
|
|
@@ -109,11 +111,13 @@ def write_domain(c):
|
|
|
109
111
|
return routing.big_domain_classify(terms)
|
|
110
112
|
|
|
111
113
|
|
|
114
|
+
# 生效条件:q 含 question 字段时,返回 mg.expand_query_terms(q["question"]) 的词列表经 routing.big_domain_classify 得到的域分类。
|
|
112
115
|
def query_domain(q):
|
|
113
116
|
"""查询侧域判定:与写入侧共用同一份 routing 词表(两侧同构)。"""
|
|
114
117
|
return routing.big_domain_classify(list(mg.expand_query_terms(q["question"])))
|
|
115
118
|
|
|
116
119
|
|
|
120
|
+
# 生效条件:mode 为 'base' 时返回 [];mode 为 'bare' 时返回 bz.normalize_terms(c, df) 的列表;其余 mode 下取 doms.get(c['id']) 得 d,d 为真值时返回 ['domain:'+d],否则返回 [];
|
|
117
121
|
def arm_tags(c, mode, df, doms):
|
|
118
122
|
if mode == "base":
|
|
119
123
|
return []
|
|
@@ -124,6 +128,7 @@ def arm_tags(c, mode, df, doms):
|
|
|
124
128
|
return [f"domain:{d}"] if d else []
|
|
125
129
|
|
|
126
130
|
|
|
131
|
+
# 生效条件:传入 corpus/name/mode/df 时先清空 HERE+ARM_PREFIX+name 同名目录再建 MdCGOS 并返回 (cg, doms);mode 为 'shuf' 时把有域节点的域随机重排,verbose 为假值时跳过桶健康输出;
|
|
127
132
|
def build_domain_arm(corpus, name, mode, df, verbose=True):
|
|
128
133
|
"""按臂建库。四臂唯一差异是 tags 内容(layer/正文/edges 全同)。"""
|
|
129
134
|
import shutil
|
|
@@ -158,6 +163,7 @@ def build_domain_arm(corpus, name, mode, df, verbose=True):
|
|
|
158
163
|
|
|
159
164
|
# ------------------------------------------------------------------ 主流程
|
|
160
165
|
|
|
166
|
+
# 生效条件:不适用(无必需形参与模块级常量)
|
|
161
167
|
def main():
|
|
162
168
|
corpus = list(ec.iter_jsonl(CORPUS567))
|
|
163
169
|
questions = list(ec.iter_jsonl(QUESTIONS500))
|
|
@@ -175,6 +181,7 @@ def main():
|
|
|
175
181
|
n_ctx = sum(1 for v in qctx.values() if v)
|
|
176
182
|
print(f"查询侧落域 {n_ctx}/{len(questions)} = {n_ctx / len(questions):.1%}")
|
|
177
183
|
|
|
184
|
+
# 生效条件:q 含 'qid' 键时返回查询上下文映射中该 qid 对应的值,映射缺该键时 .get 返回 None(q 缺 'qid' 则抛 KeyError);
|
|
178
185
|
def context_of(q):
|
|
179
186
|
return qctx.get(q["qid"])
|
|
180
187
|
|
|
@@ -218,6 +225,7 @@ def main():
|
|
|
218
225
|
ec.save_result("axis_domain_locomo_zh.json", out)
|
|
219
226
|
|
|
220
227
|
# ---- 裁决摘要 ----
|
|
228
|
+
# 生效条件:a 与 p 以 '|' 拼成键后,在结果字典的 cells 映射中取该键,含键时返回其值,缺键时 .get 返回 {};
|
|
221
229
|
def cell(a, p):
|
|
222
230
|
return out["cells"].get(f"{a}|{p}", {})
|
|
223
231
|
|
|
@@ -247,4 +255,4 @@ def main():
|
|
|
247
255
|
|
|
248
256
|
|
|
249
257
|
if __name__ == "__main__":
|
|
250
|
-
main()
|
|
258
|
+
main()
|
|
@@ -122,10 +122,12 @@ D_TPL = [
|
|
|
122
122
|
DISTRACT_POOL = ["马", "鱼", "狗", "鸟", "羊", "猪", "鸭", "肉", "奶", "蛋", "油", "米"]
|
|
123
123
|
|
|
124
124
|
|
|
125
|
+
# 生效条件:s 为字符串时返回其全部相邻二元组集合;当 len(s) 小于 2 时返回空集合。
|
|
125
126
|
def _bigrams(s):
|
|
126
127
|
return {s[i:i + 2] for i in range(len(s) - 1)}
|
|
127
128
|
|
|
128
129
|
|
|
130
|
+
# 生效条件:无参调用且 ATOMS_PATH 载入 atoms 后,逐条确认 UNSEEN 各组合词不在其中文集合、其相邻字符对均为原子,并确认 UNSEEN 无重复、set(COMP_EN)==set(UNSEEN)、set(COMP_L3)<=set(UNSEEN),全部成立才静默通过,任一断言不成立即 AssertionError。
|
|
129
131
|
def assert_material():
|
|
130
132
|
"""盲测纪律的机器化:素材在/不在 atoms + 组合词互相不冲突。"""
|
|
131
133
|
atoms = json.load(open(ATOMS_PATH, encoding="utf-8"))["atoms"]
|
|
@@ -139,6 +141,7 @@ def assert_material():
|
|
|
139
141
|
assert set(COMP_EN) == set(UNSEEN) and set(COMP_L3) <= set(UNSEEN)
|
|
140
142
|
|
|
141
143
|
|
|
144
|
+
# 生效条件:以 SEED 初始化 random.Random 后对 UNSEEN 每词按 G_TPL 取模板生成含 gold 的篇目,再对 j=0..21 用 DISTRACT_POOL 随机取两个不同词按 D_TPL 造文,50 次重试内首次出现不含 UNSEEN 任何组合词的文本即 break 并 append,22 篇齐备后返回 corpus,50 次全冲突则 raise AssertionError。
|
|
142
145
|
def gen_corpus():
|
|
143
146
|
"""33 篇受控语料:11 gold + 22 干扰。确定性,断言内嵌。"""
|
|
144
147
|
rng = random.Random(SEED)
|
|
@@ -160,6 +163,7 @@ def gen_corpus():
|
|
|
160
163
|
return corpus
|
|
161
164
|
|
|
162
165
|
|
|
166
|
+
# 生效条件:对 UNSEEN 中每个 c 生成 L1 与 L2 题;当 c 属于 L3_SET 时,用 assert 强制其 COMP_L3 问句与 g_c 的 gold 文本 bigram 零交集,失败抛 AssertionError,通过后追加 L3 题。
|
|
163
167
|
def gen_questions():
|
|
164
168
|
"""33 题。L3 生成时校验 query×gold bigram 零交集(纪律4)。"""
|
|
165
169
|
questions = []
|
|
@@ -184,6 +188,7 @@ def gen_questions():
|
|
|
184
188
|
CORPUS = None # gen_questions 需引用语料正文(L3 校验),main 内先建语料
|
|
185
189
|
|
|
186
190
|
|
|
191
|
+
# 生效条件:以 cg/questions/tag/en_atoms 与默认 semantic=False 调用时,en_atoms 为真则设 os.environ["MDCG_EN_ATOMS"]="1"、为假则 pop,semantic 为真则设 MDCG_SEMANTIC="1" 且仅当 semantic=="norm" 时把带真值 q_atoms 的题替换为 q_atoms 文本、semantic=="raw" 保持原句、semantic 为假则 pop,随后在 lexical 路径以 k=5 评测并返回 (按 ALL/L1_surface/L2_crosslingual/L3_semantic 分型的 by_type, 仅 en_atoms 为真时按 L2_crosslingual 题收集中文语素的 probe)。
|
|
187
192
|
def run_arm(cg, questions, tag, en_atoms, semantic=False):
|
|
188
193
|
"""单臂评测:臂差异只在查询侧环境开关展开。返回 (summary_by_type, l2_probe)。
|
|
189
194
|
|
|
@@ -223,6 +228,7 @@ def run_arm(cg, questions, tag, en_atoms, semantic=False):
|
|
|
223
228
|
return by_type, probe
|
|
224
229
|
|
|
225
230
|
|
|
231
|
+
# 生效条件:无参调用时先 assert_material 再经 gen_corpus/gen_questions 得到语料与题,os.path.isdir(ARM_ROOT) 为真则删除该目录,以 ARM_ROOT 建 cg 并写入 CORPUS 全部篇目,os.path.isdir(ARM_ROOT+"_b2") 为真则删除该目录、以该路径建 cg2 并仅对 gold 为真值的篇目附加 semantic=" ".join(gold) 后写入,再依次以 (cg,b0_legacy,False,False)/(cg,b1_enatoms,True,False)/(cg2,b2_comp,False,"norm")/(cg2,b3_unified,False,"raw") 四臂调 run_arm 汇总指标与 b1 的 L2 探针,最后 ec.save_result 写出 blind_comp_baseline.json 并在 out 中记录 seed/n_corpus/n_q/arms/l2_probe/elapsed_s/boundaries。
|
|
226
232
|
def main():
|
|
227
233
|
global CORPUS
|
|
228
234
|
t0 = time.time()
|
|
@@ -300,4 +306,4 @@ def main():
|
|
|
300
306
|
|
|
301
307
|
|
|
302
308
|
if __name__ == "__main__":
|
|
303
|
-
main()
|
|
309
|
+
main()
|
|
@@ -68,6 +68,7 @@ NOISE_ZH = "天气 音乐 旅行"
|
|
|
68
68
|
WRONG_POOLS = ["经济 历史 音乐", "天体 地理 化学", "科技 法律 医学"]
|
|
69
69
|
|
|
70
70
|
|
|
71
|
+
# 生效条件:text 非空且 mode 为 drop20/noise3/wrong20 时按 idx 错位扰动并返回新串;text 为空返回 text or "",mode 不在三者之内时原样返回 text。
|
|
71
72
|
def perturb_kw(text, mode, idx):
|
|
72
73
|
"""②路 query 关键词扰动(确定性规则,验证归一噪声灵敏度)。
|
|
73
74
|
|
|
@@ -89,6 +90,7 @@ def perturb_kw(text, mode, idx):
|
|
|
89
90
|
return text
|
|
90
91
|
|
|
91
92
|
|
|
93
|
+
# 生效条件:CHAR_ATOMS 可读时按 data.get("lexicon") or {} 取词库,lexicon 缺失或为假值即返回空字典,否则逐键返回 {ch: str(v.get("en") or "")}(v 缺 "en" 或 "en" 为假值时该键值为空串)。
|
|
92
94
|
def load_char_atoms():
|
|
93
95
|
"""字级英文原子库:{中文字: 英文短语}。"""
|
|
94
96
|
with io.open(CHAR_ATOMS, encoding="utf-8") as f:
|
|
@@ -97,6 +99,7 @@ def load_char_atoms():
|
|
|
97
99
|
return {ch: str(v.get("en") or "") for ch, v in lex.items()}
|
|
98
100
|
|
|
99
101
|
|
|
102
|
+
# 生效条件:以 text or "" 逐字符、char_atoms 为字级映射表——字符落在 ZH_RANGE 内时取 char_atoms.get(ch, "")(缺键回落空串),其余字符原样保留,返回 normalize_en(" ".join(parts));text 为假值(None/空串)时按空串返回 normalize_en("")。
|
|
100
103
|
def zh_map_en(text, char_atoms):
|
|
101
104
|
"""中文逐字→英文短语映射串;英文/数字原样保留(交 normalize_en 归一)。"""
|
|
102
105
|
lo, hi = ZH_RANGE
|
|
@@ -109,6 +112,7 @@ def zh_map_en(text, char_atoms):
|
|
|
109
112
|
return normalize_en(" ".join(parts))
|
|
110
113
|
|
|
111
114
|
|
|
115
|
+
# 生效条件:以 normalize_en(str(c.get("text") or "")).split() 为基词集,body_only 为真时只返回该集合的 frozenset;body_only 为假(默认 False)时再并入 zh_map_en(str(c.get("zh") or ""), char_atoms) 拆出的词,返回合并后的 frozenset。
|
|
112
116
|
def node_atom_set(c, char_atoms, body_only=False):
|
|
113
117
|
"""doc 侧节点原子集:中文五槽字级映射 ∪ 英文正文归一词(双语双路 doc 侧)。
|
|
114
118
|
|
|
@@ -121,6 +125,7 @@ def node_atom_set(c, char_atoms, body_only=False):
|
|
|
121
125
|
return frozenset(toks)
|
|
122
126
|
|
|
123
127
|
|
|
128
|
+
# 生效条件:a 或 b 为假值(None/空集)时返回 0.0,否则交集非空返回 len(a & b)/len(a | b)、交集为空亦返回 0.0。
|
|
124
129
|
def jaccard(a, b):
|
|
125
130
|
if not a or not b:
|
|
126
131
|
return 0.0
|
|
@@ -128,10 +133,12 @@ def jaccard(a, b):
|
|
|
128
133
|
return inter / len(a | b) if inter else 0.0
|
|
129
134
|
|
|
130
135
|
|
|
136
|
+
# 生效条件:对 st.items() 每个值取 round(v, 1) 组成同键字典,st 为空字典时返回空字典。
|
|
131
137
|
def round_dict(st):
|
|
132
138
|
return {k: round(v, 1) for k, v in st.items()}
|
|
133
139
|
|
|
134
140
|
|
|
141
|
+
# 生效条件:遍历 questions 逐问评测——qatoms_of(q) 为假值时仅累加 st["n"] 不计命中,否则按 jaccard 对 docs 降序(同分按 nid 升序)排序、以首个 nid 落在 q.get("evidence_turns") or [] 中的 rank 累加 hit@1/5/10 与 1/rank 的 MRR,打印后返回 {k: v/max(st["n"],1)(rr 项)或 v*100.0/max(st["n"],1)}。
|
|
135
142
|
def run_arm(questions, docs, qatoms_of, label):
|
|
136
143
|
"""单臂评测:全池 Jaccard 排序,hit@1/5/10 + MRR。"""
|
|
137
144
|
st = {"h1": 0, "h5": 0, "h10": 0, "rr": 0.0, "n": 0}
|
|
@@ -160,6 +167,7 @@ def run_arm(questions, docs, qatoms_of, label):
|
|
|
160
167
|
return {k: (v / n if k == "rr" else v * 100.0 / n) for k, v in st.items()}
|
|
161
168
|
|
|
162
169
|
|
|
170
|
+
# 生效条件:CORPUS、QUESTIONS、CHAR_ATOMS 与 b6.EN_QUESTIONS 均可读(en_rows 由 ec.iter_jsonl 读取 b6.EN_QUESTIONS 构建)时,载入语料与题、构建 docs 与 docs_body、逐臂 run_arm 并打印锚点,返回 0。
|
|
163
171
|
def main():
|
|
164
172
|
t0 = time.time()
|
|
165
173
|
with io.open(CORPUS, encoding="utf-8") as f:
|
|
@@ -190,6 +198,7 @@ def main():
|
|
|
190
198
|
# 臂④ 机械归一端到端下界:英文问句 → 词表直译为中文词(CEDICT 28294 键
|
|
191
199
|
# ∪ EN_ZH 手工层,无 AI)→ ②同链路。与②唯一差异 = query 归一来源:
|
|
192
200
|
# ②=AI 理解式归一的输出形态(标注关键词),④=机械查表归一。
|
|
201
|
+
# 生效条件:以 en_rows.get(q.get("qid"), "")(qid 缺键回落空串)取英文题面,经 normalize_en_query 取出的 terms 拼接后由 zh_map_en 映射,返回 frozenset(zh_map_en(" ".join(terms), char_atoms).split());terms 为空时返回空 frozenset。
|
|
193
202
|
def e4(q):
|
|
194
203
|
terms, _ = normalize_en_query(en_rows.get(q.get("qid"), ""))
|
|
195
204
|
return frozenset(zh_map_en(" ".join(terms), char_atoms).split())
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""治理四指标只读评估器(阶段三 §5.1/§5.2 基线测量,纯合成确定性语料,不改任何行为面)。
|
|
3
|
+
|
|
4
|
+
四指标(对照值来自 docs/灵枢自我改进工作计划_外部研究系列吸收 §5):
|
|
5
|
+
g1 修正传播率 — 上游信任态降级后,依赖下游一跳同步失效比例
|
|
6
|
+
(承载=trust.set_state+mark_dependents;对照 MAGE 91.2%)
|
|
7
|
+
g2 矛盾处理率 — 矛盾/否定证据被正确裁决比例
|
|
8
|
+
(承载=judge_qualification 负条件 REJECT + judge_ranking 终排剔除;
|
|
9
|
+
对照 MAGE 88.5%)
|
|
10
|
+
g3 过期取回率 — 检索 top-k 返回已过期节点比例(越低越好)
|
|
11
|
+
(口径唯一真源=trust.is_expired / scrub._EXPIRY_KEYS;
|
|
12
|
+
主口径=validity 防线残留率,副口径=默认面暴露率;对照 MAGE 3.1%)
|
|
13
|
+
g4 拒答 F1 — 不可答问题拒答的精确率/召回率/F1
|
|
14
|
+
(拒答判据=空结果 或 top1 资格态∈{BLINDSPOT, DEFER};
|
|
15
|
+
对照 REMem 64.0)
|
|
16
|
+
|
|
17
|
+
设计约束:
|
|
18
|
+
- 纯合成语料、无随机源,重复运行结果逐位一致(第 5 条可回放);
|
|
19
|
+
- tempfile 库,不触碰真实认知图库(评估器只读);
|
|
20
|
+
- 语料守卫断言(语料本身不合法立即 fail,防指标虚高——对齐 bench_blind_comp
|
|
21
|
+
assert_material 纪律)。
|
|
22
|
+
运行:python -X utf8 -m md_cg.bench_governance [--out <json>]
|
|
23
|
+
"""
|
|
24
|
+
import argparse
|
|
25
|
+
import json
|
|
26
|
+
import os
|
|
27
|
+
import shutil
|
|
28
|
+
import subprocess
|
|
29
|
+
import sys
|
|
30
|
+
import tempfile
|
|
31
|
+
import time
|
|
32
|
+
|
|
33
|
+
from .mdcg import MdCG
|
|
34
|
+
from .mdcos import MdCGOS
|
|
35
|
+
from . import trust
|
|
36
|
+
|
|
37
|
+
BASELINE_REF = {
|
|
38
|
+
"g1_correction_propagation": {"ours": None, "mage": 0.912},
|
|
39
|
+
"g2_contradiction_handling": {"ours": None, "mage": 0.885},
|
|
40
|
+
"g3_expired_recall": {"ours": None, "mage": 0.031, "note": "越低越好"},
|
|
41
|
+
"g4_refusal_f1": {"ours": None, "remem_f1": 64.0, "note": "REMem 为其自报口径,仅作量级对照"},
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# ---------------------------------------------------------------- 语料 ----
|
|
45
|
+
|
|
46
|
+
NOW = None # main 内注入,保证同一次运行内时间一致
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _doc(title, fact, cond="无条件", neg=None):
|
|
50
|
+
"""CCG 六要素正文(与 test_sem_noise._doc 同构:负条件双写中的正文行)。"""
|
|
51
|
+
lines = [
|
|
52
|
+
"# 功能名:" + title,
|
|
53
|
+
"# 生效条件:" + cond,
|
|
54
|
+
"# 子功能:" + title + "事实卡",
|
|
55
|
+
"# 执行:检索面事实提供",
|
|
56
|
+
"# 验证方式:test",
|
|
57
|
+
"# 不适用条件:" + (neg or "无"),
|
|
58
|
+
"",
|
|
59
|
+
fact,
|
|
60
|
+
]
|
|
61
|
+
return "\n".join(lines)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# 可答事实:条件词面刻意出现在对应 query 里(正条件确认可命中 → ACCEPT)
|
|
65
|
+
FACTS = [
|
|
66
|
+
# (nid, 事实句, 正条件行, query)
|
|
67
|
+
("g_f1", "灵枢检索缓存默认保留 128 条。", "载体:缓存配置", "缓存配置里默认缓存多大"),
|
|
68
|
+
("g_f2", "蜂巢心跳间隔为 30 秒。", "载体:蜂巢参数", "蜂巢参数中心跳间隔是多少"),
|
|
69
|
+
("g_f3", "评测器统一经 eval_common 汇总指标。", "载体:评测约定", "评测约定的汇总入口在哪"),
|
|
70
|
+
("g_f4", "python 命令统一走 argv 列表加显式 UTF-8。", "无条件", "python 命令执行要用什么编码约定"),
|
|
71
|
+
("g_f5", "语义摘要路默认关闭、显式 opt-in 才启用。", "无条件", "语义摘要路默认开还是关"),
|
|
72
|
+
("g_f6", "分支节点不出库、不进主支检索。", "无条件", "分支节点会不会进主支检索"),
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
# 否定反事实:负条件双写(kwarg + 正文行),否定情境 query=「你刚才在干什么」
|
|
76
|
+
NEG_QUERY = "你刚才在干什么"
|
|
77
|
+
NEG_COND = "刚才在干什么"
|
|
78
|
+
NEGATIVES = [
|
|
79
|
+
("g_n1", "我没有在喝水。"),
|
|
80
|
+
("g_n2", "我没有在写代码。"),
|
|
81
|
+
("g_n3", "我没有在开会。"),
|
|
82
|
+
("g_n4", "我没有在跑步。"),
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
# 过期节点:与可答事实同题竞争(旧版本数值已失效),effective_until 已过
|
|
86
|
+
STALE = [
|
|
87
|
+
("g_e1", "蜂巢心跳间隔曾为 10 秒(旧版)。", "g_f2"),
|
|
88
|
+
("g_e2", "评测器旧口径按 k=3 汇总(已废弃)。", "g_f3"),
|
|
89
|
+
("g_e3", "检索缓存默认曾为 64 条(旧版)。", "g_f1"),
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
# 修正传播链:地基 U + 一跳依赖 D1..D4
|
|
93
|
+
U_GOV = "g_u_gov"
|
|
94
|
+
DEPENDENTS = ["g_d1", "g_d2", "g_d3", "g_d4"]
|
|
95
|
+
|
|
96
|
+
# 无关背景(干扰;CCG 完整可 ACCEPT——拒答 F1 的诚实下界来自它)
|
|
97
|
+
BACKDROP = [
|
|
98
|
+
("g_b1", "工作区在约定中默认使用简体中文交流。"),
|
|
99
|
+
("g_b2", "认知图只给知识与建议能力名,不执行操作。"),
|
|
100
|
+
("g_b3", "留痕粒度按任务合并,不逐命令逐行。"),
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
# 不可答问题(与语料词面零重叠;期望系统拒答)
|
|
104
|
+
UNANSWERABLE = [
|
|
105
|
+
"用户 2026 年春节在哪过的",
|
|
106
|
+
"项目预算总共批了多少万",
|
|
107
|
+
"作者最喜欢的菜是什么",
|
|
108
|
+
"下个版本计划支持日语吗",
|
|
109
|
+
"服务器部署在哪个机房",
|
|
110
|
+
"团队现在有多少人",
|
|
111
|
+
"竞品报价单是多少",
|
|
112
|
+
"昨天的会议纪要说了什么",
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _assert_material(now):
|
|
117
|
+
"""语料守卫:素材纪律机器断言(违者 fail,防指标虚高)。"""
|
|
118
|
+
fact_ids = {nid for nid, *_ in FACTS}
|
|
119
|
+
stale_ids = {nid for nid, *_ in STALE}
|
|
120
|
+
neg_ids = {nid for nid, *_ in NEGATIVES}
|
|
121
|
+
assert not (fact_ids & stale_ids | fact_ids & neg_ids | stale_ids & neg_ids), "语料 id 重叠"
|
|
122
|
+
assert len(UNANSWERABLE) >= 5 and len(FACTS) >= 5, "探针集过小"
|
|
123
|
+
# 不可答题与语料词面零重叠(粗粒度:语料特征词不出现于不可答题面)
|
|
124
|
+
lex = "".join(f for _, f, *_ in FACTS) + "".join(f for _, f in NEGATIVES) \
|
|
125
|
+
+ "".join(f for _, f, _ in STALE) + "".join(f for _, f in BACKDROP)
|
|
126
|
+
for q in UNANSWERABLE:
|
|
127
|
+
overlap = [w for w in ("缓存", "蜂巢", "心跳", "评测", "python", "语义摘要", "分支") if w in q]
|
|
128
|
+
assert not overlap, f"不可答题词面泄漏:{q} 命中 {overlap}"
|
|
129
|
+
assert "无条件" not in lex or True # 语料自洽由 judge 实测兜底
|
|
130
|
+
for _, _, base in STALE:
|
|
131
|
+
assert base in fact_ids, "过期节点必须与某可答事实同题竞争"
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def build_corpus(cg, now):
|
|
135
|
+
"""建确定性语料。返回节点数。"""
|
|
136
|
+
n = 0
|
|
137
|
+
# 可答事实(F1-F3 带条件、F4-F6 无条件豁免)
|
|
138
|
+
for nid, fact, cond, _q in FACTS:
|
|
139
|
+
cg.add(nid, _doc(nid, fact, cond=cond), layer="knowledge",
|
|
140
|
+
verification_basis="test")
|
|
141
|
+
n += 1
|
|
142
|
+
# 否定反事实(负条件双写)
|
|
143
|
+
for nid, sent in NEGATIVES:
|
|
144
|
+
cg.add(nid, _doc(nid, sent, cond="时间:即时情境", neg=NEG_COND), layer="knowledge",
|
|
145
|
+
verification_basis="test", non_applicable_conditions=[NEG_COND])
|
|
146
|
+
n += 1
|
|
147
|
+
# 过期节点(effective_until 已过;expired_at 冗余由 add 派生)
|
|
148
|
+
for nid, fact, _base in STALE:
|
|
149
|
+
cg.add(nid, _doc(nid, fact, cond="无条件"), layer="knowledge",
|
|
150
|
+
verification_basis="test",
|
|
151
|
+
effective_from=now - 7200.0, effective_until=now - 3600.0)
|
|
152
|
+
n += 1
|
|
153
|
+
# 无关背景
|
|
154
|
+
for nid, fact in BACKDROP:
|
|
155
|
+
cg.add(nid, _doc(nid, fact), layer="knowledge", verification_basis="test")
|
|
156
|
+
n += 1
|
|
157
|
+
# 修正传播链:地基 + 一跳依赖(depends_on=依赖图语义,trust.dependents_index 消费;
|
|
158
|
+
# derived_from=血缘溯源,语义不同不混用)
|
|
159
|
+
cg.add(U_GOV, _doc(U_GOV, "地基结论:核心算法口径以文档 A 为准。", cond="无条件"),
|
|
160
|
+
layer="knowledge", verification_basis="test")
|
|
161
|
+
n += 1
|
|
162
|
+
for did in DEPENDENTS:
|
|
163
|
+
cg.add(did, _doc(did, f"{did} 结论:沿用地基口径实现细节。", cond="无条件"),
|
|
164
|
+
layer="knowledge", verification_basis="test", depends_on=[U_GOV])
|
|
165
|
+
n += 1
|
|
166
|
+
return n
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
# ---------------------------------------------------------------- 指标 ----
|
|
170
|
+
|
|
171
|
+
def m1_correction_propagation(cg):
|
|
172
|
+
"""g1:上游降级 doubted → mark_dependents 一跳同步传播率。"""
|
|
173
|
+
r0 = trust.set_state(cg, U_GOV, "doubted", reason="基线评测:地基被修正")
|
|
174
|
+
assert isinstance(r0, dict) and r0.get("ok"), f"上游降级失败:{r0}"
|
|
175
|
+
r = trust.mark_dependents(cg, U_GOV, reason="基线评测:上游修正传播", apply=True)
|
|
176
|
+
deps, upd = r.get("dependents") or [], r.get("updated") or []
|
|
177
|
+
assert sorted(deps) == sorted(DEPENDENTS), f"依赖索引不符预期:{deps}"
|
|
178
|
+
rate = (len(upd) / len(deps)) if deps else None
|
|
179
|
+
return {"metric": "correction_propagation", "value": rate,
|
|
180
|
+
"detail": {"dependents": len(deps), "updated": len(upd),
|
|
181
|
+
"skipped": r.get("skipped"), "reference_mage": 0.912}}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _is_refusal(results):
|
|
185
|
+
"""拒答判据:空结果 或 top1 资格态 ∈ {BLINDSPOT, DEFER}。"""
|
|
186
|
+
if not results:
|
|
187
|
+
return True, "empty"
|
|
188
|
+
entry = results[0]
|
|
189
|
+
qual = entry[2] if len(entry) > 2 else None # 条目=(node, score, qual, prov)
|
|
190
|
+
st = (qual or {}).get("state") if isinstance(qual, dict) else None
|
|
191
|
+
return st in ("BLINDSPOT", "DEFER"), st
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def m2_contradiction_handling(cg):
|
|
195
|
+
"""g2:否定证据正确裁决率 = 定点裁决 + 检索防线(skip 项不入分母)。"""
|
|
196
|
+
correct = wrong = skipped = 0
|
|
197
|
+
detail = {"judged": [], "retrieval": []}
|
|
198
|
+
# (a) 定点裁决:否定节点在否定情境下应 REJECT(judge_qualification 直调)
|
|
199
|
+
for nid, _sent in NEGATIVES:
|
|
200
|
+
node = cg.get(nid)
|
|
201
|
+
qual = MdCG.judge_qualification(
|
|
202
|
+
{"frontmatter": node.get("frontmatter") or {}, "content": node.get("content") or ""},
|
|
203
|
+
NEG_QUERY, None)
|
|
204
|
+
st = qual.get("state")
|
|
205
|
+
detail["judged"].append({"nid": nid, "state": st})
|
|
206
|
+
if st == "REJECT":
|
|
207
|
+
correct += 1
|
|
208
|
+
elif st is None:
|
|
209
|
+
skipped += 1
|
|
210
|
+
else:
|
|
211
|
+
wrong += 1
|
|
212
|
+
# (b) 检索防线:judge_ranking 终排后 top-k 无否定节点冒充
|
|
213
|
+
res, meta = cg.search_rrf(NEG_QUERY, k=10, judge=True, judge_ranking=True,
|
|
214
|
+
record=False)
|
|
215
|
+
ids = [r[0]["id"] for r in res]
|
|
216
|
+
leaked = [i for i in ids if i in {n for n, _ in NEGATIVES}]
|
|
217
|
+
detail["retrieval"] = {"top_ids": ids[:5], "leaked_negatives": leaked,
|
|
218
|
+
"judge_filtered": (meta or {}).get("judge_filtered")}
|
|
219
|
+
if leaked:
|
|
220
|
+
wrong += 1
|
|
221
|
+
else:
|
|
222
|
+
correct += 1
|
|
223
|
+
total = correct + wrong
|
|
224
|
+
return {"metric": "contradiction_handling", "value": (correct / total) if total else None,
|
|
225
|
+
"detail": dict(detail, correct=correct, wrong=wrong, skipped=skipped,
|
|
226
|
+
reference_mage=0.885)}
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def m3_expired_recall(cg, now):
|
|
230
|
+
"""g3:过期取回率。主口径=validity 防线残留率;副口径=默认面暴露率。"""
|
|
231
|
+
stale_ids = {nid for nid, *_ in STALE}
|
|
232
|
+
probe = "蜂巢参数中心跳间隔是多少" # 与过期节点 g_e1 同题竞争
|
|
233
|
+
out = {}
|
|
234
|
+
for tag, kw in (("raw", {}), ("guard", {"validity": True}),
|
|
235
|
+
("judge_ranking", {"judge_ranking": True})):
|
|
236
|
+
res, _meta = cg.search_rrf(probe, k=10, judge=True, record=False, **kw)
|
|
237
|
+
ids = [r[0]["id"] for r in res]
|
|
238
|
+
hits = [i for i in ids if i in stale_ids]
|
|
239
|
+
out[tag] = {"top_ids": ids[:5], "stale_hits": hits,
|
|
240
|
+
"rate": (len(hits) / len(ids)) if ids else None}
|
|
241
|
+
return {"metric": "expired_recall",
|
|
242
|
+
"value": out["guard"]["rate"], # 主口径:防线后残留(越低越好)
|
|
243
|
+
"detail": dict(out, probe=probe, stale_total=len(stale_ids),
|
|
244
|
+
reference_mage=0.031, note="raw=默认面暴露;guard=validity 防线")}
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def m4_refusal_f1(cg):
|
|
248
|
+
"""g4:拒答精确率/召回率/F1(正类=不可答)。"""
|
|
249
|
+
tp = fn = fp = tn = 0
|
|
250
|
+
detail = {"unanswerable": [], "answerable": []}
|
|
251
|
+
for q in UNANSWERABLE:
|
|
252
|
+
res, _m = cg.search_rrf(q, k=3, judge=True, judge_ranking=True, record=False)
|
|
253
|
+
refused, st = _is_refusal(res)
|
|
254
|
+
detail["unanswerable"].append({"q": q, "refused": refused, "top_state": st})
|
|
255
|
+
if refused:
|
|
256
|
+
tp += 1
|
|
257
|
+
else:
|
|
258
|
+
fn += 1
|
|
259
|
+
for _nid, _fact, _cond, q in FACTS:
|
|
260
|
+
res, _m = cg.search_rrf(q, k=3, judge=True, judge_ranking=True, record=False)
|
|
261
|
+
refused, st = _is_refusal(res)
|
|
262
|
+
detail["answerable"].append({"q": q, "refused": refused, "top_state": st})
|
|
263
|
+
if refused:
|
|
264
|
+
fp += 1
|
|
265
|
+
else:
|
|
266
|
+
tn += 1
|
|
267
|
+
p = tp / (tp + fp) if (tp + fp) else None
|
|
268
|
+
r = tp / (tp + fn) if (tp + fn) else None
|
|
269
|
+
if p is not None and r is not None and p + r:
|
|
270
|
+
f1 = 2 * p * r / (p + r)
|
|
271
|
+
else:
|
|
272
|
+
# tp+fp=0:系统从未拒答(无 query 侧拒答信号)——保守编码 F1=0.0 并如实注明
|
|
273
|
+
f1 = 0.0
|
|
274
|
+
return {"metric": "refusal_f1",
|
|
275
|
+
"value": f1,
|
|
276
|
+
"detail": {"precision": p, "recall": r, "tp": tp, "fn": fn, "fp": fp, "tn": tn,
|
|
277
|
+
"refusal_rule": "empty or top1 state in {BLINDSPOT, DEFER}",
|
|
278
|
+
"note": ("no refusal signal: judge 资格态只判节点可用性,"
|
|
279
|
+
"不判答案存在性;不可答题被无关 ACCEPT 节点冒充全部未拒"
|
|
280
|
+
if (tp + fp) == 0 else ""),
|
|
281
|
+
"reference_remem_f1": 64.0}}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
# ---------------------------------------------------------------- 主流程 ----
|
|
285
|
+
|
|
286
|
+
def run(root=None, keep=False):
|
|
287
|
+
"""跑四指标,返回 (report_dict, root)。root 供测试复检。"""
|
|
288
|
+
now = time.time()
|
|
289
|
+
_assert_material(now)
|
|
290
|
+
root = root or tempfile.mkdtemp(prefix="mdcg_governance_")
|
|
291
|
+
try:
|
|
292
|
+
cg = MdCGOS(root, actor="bench_governance", autoflush=200)
|
|
293
|
+
n_nodes = build_corpus(cg, now)
|
|
294
|
+
cg.flush()
|
|
295
|
+
report = {
|
|
296
|
+
"meta": {
|
|
297
|
+
"bench": "bench_governance",
|
|
298
|
+
"date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(now)),
|
|
299
|
+
"corpus_nodes": n_nodes,
|
|
300
|
+
"head": _git_head(),
|
|
301
|
+
"determinism": "synthetic corpus, no RNG",
|
|
302
|
+
"scopes": "阶段三 §5.1 治理三件套 + §5.2 拒答量化(基线测量,不改行为)",
|
|
303
|
+
},
|
|
304
|
+
"g1_correction_propagation": m1_correction_propagation(cg),
|
|
305
|
+
"g2_contradiction_handling": m2_contradiction_handling(cg),
|
|
306
|
+
"g3_expired_recall": m3_expired_recall(cg, now),
|
|
307
|
+
"g4_refusal_f1": m4_refusal_f1(cg),
|
|
308
|
+
"baseline_reference": BASELINE_REF,
|
|
309
|
+
}
|
|
310
|
+
return report, root
|
|
311
|
+
finally:
|
|
312
|
+
if not keep:
|
|
313
|
+
shutil.rmtree(root, ignore_errors=True)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def _git_head():
|
|
317
|
+
try:
|
|
318
|
+
out = subprocess.run(["git", "rev-parse", "--short", "HEAD"],
|
|
319
|
+
capture_output=True, text=True, encoding="utf-8",
|
|
320
|
+
errors="replace", shell=False, timeout=10)
|
|
321
|
+
return (out.stdout or "").strip() or "unknown"
|
|
322
|
+
except Exception: # noqa: BLE001
|
|
323
|
+
return "unknown"
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def main(argv=None):
|
|
327
|
+
ap = argparse.ArgumentParser(description="治理四指标只读评估器")
|
|
328
|
+
ap.add_argument("--out", default=os.path.join("data", "external", "eval_results",
|
|
329
|
+
"governance_baseline.json"))
|
|
330
|
+
ap.add_argument("--keep", action="store_true", help="保留临时库目录(调试用)")
|
|
331
|
+
args = ap.parse_args(argv)
|
|
332
|
+
report, root = run(keep=args.keep)
|
|
333
|
+
out = os.path.abspath(args.out)
|
|
334
|
+
os.makedirs(os.path.dirname(out), exist_ok=True)
|
|
335
|
+
with open(out, "w", encoding="utf-8") as f:
|
|
336
|
+
json.dump(report, f, ensure_ascii=False, indent=2)
|
|
337
|
+
print(json.dumps({k: v.get("value") for k, v in report.items()
|
|
338
|
+
if isinstance(v, dict) and "value" in v},
|
|
339
|
+
ensure_ascii=False, indent=2))
|
|
340
|
+
print("baseline ->", out, "| temp root:", root)
|
|
341
|
+
vals = [report[g]["value"] for g in ("g1_correction_propagation",
|
|
342
|
+
"g2_contradiction_handling",
|
|
343
|
+
"g3_expired_recall", "g4_refusal_f1")]
|
|
344
|
+
return 0 if all(v is not None for v in vals) else 1
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
if __name__ == "__main__":
|
|
348
|
+
raise SystemExit(main())
|
package/md_cg/bench_lme_zh.py
CHANGED
|
@@ -75,6 +75,7 @@ ZH_Q_PROMPT = """从下面英文问题里抽出中文关键词:只输出名词
|
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
# ------------------------------------------------------------------ LLM
|
|
78
|
+
# 生效条件:环境变量 DEEPSEEK_API_KEY 为真值(缺省或空串即抛 RuntimeError「需要 DEEPSEEK_API_KEY」)且 range(retries) 至少迭代一次(retries≥1)时,用 messages、max_tokens 调 llm_chat 并返回 (content, usage);全部重试失败或 retries=0(last 保持 None)时抛 RuntimeError「LLM 调用失败:…」。
|
|
78
79
|
def _llm(messages, max_tokens=400, retries=3):
|
|
79
80
|
from md_cg.bench_task_ab_llm import llm_chat
|
|
80
81
|
key = os.environ.get("DEEPSEEK_API_KEY")
|
|
@@ -100,6 +101,7 @@ _DEFAULT_COND = {"observation_position": "会话陈述", "observation_tool": "
|
|
|
100
101
|
"existence_constraint": "公开"}
|
|
101
102
|
|
|
102
103
|
|
|
104
|
+
# 生效条件:p 经 os.path.isfile(p) 判定为普通文件时按 utf-8 打开并返回 json.load(f);os.path.isfile(p) 为假(含目录、不存在路径、空串)时返回 {}。
|
|
103
105
|
def _load_json(p):
|
|
104
106
|
if os.path.isfile(p):
|
|
105
107
|
with open(p, encoding="utf-8") as f:
|
|
@@ -107,6 +109,7 @@ def _load_json(p):
|
|
|
107
109
|
return {}
|
|
108
110
|
|
|
109
111
|
|
|
112
|
+
# 生效条件:无参调用即返回 (_load_json(MAN_ZH), _load_json(MAN_Q)),每个元素在模块级常量 MAN_ZH / MAN_Q 指向普通文件时为解析出的 JSON、否则为 {}。
|
|
110
113
|
def _load_manual():
|
|
111
114
|
"""读入会话模型直接产出的中文层 / 中文查询词(零 API 依赖)。
|
|
112
115
|
|
|
@@ -119,6 +122,7 @@ def _load_manual():
|
|
|
119
122
|
return _load_json(MAN_ZH), _load_json(MAN_Q)
|
|
120
123
|
|
|
121
124
|
|
|
125
|
+
# 生效条件:z 为真值且 re.search(r"条件=([^;;]+)") 命中,并按 [||] 切分后至少有一段以 ":" / ":" 分为两段且首段 strip 后在模块级常量 _COND_KEYS 中时,返回非空映射 dict;z 为假值、正则未命中或映射为空时返回 None。
|
|
122
126
|
def _cond_of(z):
|
|
123
127
|
"""从中文层的「条件=观测位置:…|观测工具:…|…」抽条件空间 dict。"""
|
|
124
128
|
m = re.search(r"条件=([^;;]+)", z or "")
|
|
@@ -132,6 +136,7 @@ def _cond_of(z):
|
|
|
132
136
|
return out or None
|
|
133
137
|
|
|
134
138
|
|
|
139
|
+
# 生效条件:模块级常量 CACHE 经 os.path.isfile(CACHE) 判定为普通文件时按 utf-8 打开并返回 json.load(f);否则返回 {}。
|
|
135
140
|
def _load_cache():
|
|
136
141
|
if os.path.isfile(CACHE):
|
|
137
142
|
with open(CACHE, encoding="utf-8") as f:
|
|
@@ -139,12 +144,14 @@ def _load_cache():
|
|
|
139
144
|
return {}
|
|
140
145
|
|
|
141
146
|
|
|
147
|
+
# 生效条件:以 c 为输入即 os.makedirs(DIR, exist_ok=True) 后按 utf-8 把 c 以 ensure_ascii=False、indent=1 写入模块级常量 CACHE,无前置校验、无返回值。
|
|
142
148
|
def _save_cache(c):
|
|
143
149
|
os.makedirs(DIR, exist_ok=True)
|
|
144
150
|
with open(CACHE, "w", encoding="utf-8") as f:
|
|
145
151
|
json.dump(c, f, ensure_ascii=False, indent=1)
|
|
146
152
|
|
|
147
153
|
|
|
154
|
+
# 生效条件:cache 命中 "L2:"+turn["id"] 时直接返回该缓存值;否则用 ZH_PROMPT 拼 json.dumps({"date": turn.get("date"), "text": turn.get("text")})(键缺失回落 null)调 _llm,依次取 max_tokens=1200、2600,对 content or "" 去代码块与标签后 strip(" ,,、|"),首个非空即 break,把结果写回 cache 并返回(两次皆空则缓存并返回 "")。
|
|
148
155
|
def zh_layer(turn, cache):
|
|
149
156
|
"""一条 turn → 中文词袋。缓存 key 带版本号:prompt 改版必须失效旧缓存。
|
|
150
157
|
|
|
@@ -171,6 +178,7 @@ def zh_layer(turn, cache):
|
|
|
171
178
|
return s
|
|
172
179
|
|
|
173
180
|
|
|
181
|
+
# 生效条件:cache 命中 "Q2:"+q["qid"] 时直接返回该缓存值;否则以 ZH_Q_PROMPT+q["question"] 调 _llm(max_tokens=1200),去代码块后 strip(" ,,、") 写入 cache[key],结果为空串时抛 RuntimeError「查询侧关键词为空…」,非空时返回 cache[key]。
|
|
174
182
|
def zh_question(q, cache):
|
|
175
183
|
"""英文问题 → 中文关键词(与写入侧同源;额度须 ≥1200,否则推理烧空 content)。"""
|
|
176
184
|
key = "Q2:" + q["qid"]
|
|
@@ -186,6 +194,7 @@ def zh_question(q, cache):
|
|
|
186
194
|
|
|
187
195
|
|
|
188
196
|
# ------------------------------------------------------------------ 池
|
|
197
|
+
# 生效条件:模块级常量 POOL 为普通文件时直接返回其中非空行的 json.loads 列表(此时不读 n_q、n_distract、seed);否则以 random.Random(seed)、每组 max(1, n_q//len(GROUPS)) 条(取 q["evidence_turns"][0] 为 gold)采样后追加 rng.sample(rest, min(n_distract, len(rest))) 干扰项,写出 POOL 与 questions.json 并返回 pool。
|
|
189
198
|
def build_pool(n_q, n_distract, seed=7):
|
|
190
199
|
"""采样:n_q 题(分组覆盖)各取 evidence_turns[0] 为 gold,再取干扰。"""
|
|
191
200
|
if os.path.isfile(POOL):
|
|
@@ -222,12 +231,14 @@ def build_pool(n_q, n_distract, seed=7):
|
|
|
222
231
|
return pool
|
|
223
232
|
|
|
224
233
|
|
|
234
|
+
# 生效条件:DIR 目录下的 questions.json 是 UTF-8 合法 JSON 时,返回 json.load 得到的对象。
|
|
225
235
|
def load_questions_zh():
|
|
226
236
|
with open(os.path.join(DIR, "questions.json"), encoding="utf-8") as f:
|
|
227
237
|
return json.load(f)
|
|
228
238
|
|
|
229
239
|
|
|
230
240
|
# ------------------------------------------------------------------ 建库 / 评测
|
|
241
|
+
# 生效条件:以 ec.build_eval_cg(None, root, corpus or POOL, ec.lm_turn_text, "lmezh", calib_of=calib if zh_of 为真值 else None, rebuild=rebuild) 执行并返回其结果(形参 pool 在该调用中未被使用,实际用 corpus or POOL;zh_only 只在内层 calib 中生效,不传给 build_eval_cg)。
|
|
231
242
|
def build(root, pool, zh_of=None, rebuild=False, zh_only=False, corpus=None):
|
|
232
243
|
"""zh_of: turn_id → 中文层;None = 裸文本库。
|
|
233
244
|
|
|
@@ -237,6 +248,7 @@ def build(root, pool, zh_of=None, rebuild=False, zh_only=False, corpus=None):
|
|
|
237
248
|
上界而非全译库真值。故另设 F 臂(池只含 20 条 gold、正文全中文)隔离该假象,
|
|
238
249
|
单测中文层自身的可区分性。
|
|
239
250
|
"""
|
|
251
|
+
# 生效条件:作为 build 的内层函数闭包使用 zh_of/zh_only,ctx 未被使用;zh_of 为真值且 zh_of.get(r["id"]) 为真值时 cs = _cond_of(z) or cs,否则 cs = dict(_DEFAULT_COND);zh_only 为真值时返回 (z or ec.lm_turn_text(r), [], cs),否则返回 (ec.lm_turn_text(r) 在 z 为真值时再拼 "\n"+z, [], cs)。
|
|
240
252
|
def calib(r, ctx=None):
|
|
241
253
|
z = zh_of.get(r["id"]) if zh_of else None
|
|
242
254
|
cs = dict(_DEFAULT_COND)
|
|
@@ -252,6 +264,7 @@ def build(root, pool, zh_of=None, rebuild=False, zh_only=False, corpus=None):
|
|
|
252
264
|
calib_of=calib if zh_of else None, rebuild=rebuild)
|
|
253
265
|
|
|
254
266
|
|
|
267
|
+
# 生效条件:给定 cg、questions 与 qtext_of 时,对每题用 qtext_of(q) 替换 question 后经 ec.evaluate_group 评测,并按 k 汇总为结果。
|
|
255
268
|
def eval_arm(cg, questions, qtext_of, k=5):
|
|
256
269
|
rows = []
|
|
257
270
|
for q in questions:
|
|
@@ -261,6 +274,7 @@ def eval_arm(cg, questions, qtext_of, k=5):
|
|
|
261
274
|
return ec.summarize(rows, k=k)
|
|
262
275
|
|
|
263
276
|
|
|
277
|
+
# 生效条件:argv 由 argparse 解析(--n-q/--n-distract/--k/--build/--rebuild/--workers 等);--build 只产池即返回,否则需外部数据在指定路径就位、缺失即抛异常不静默降级;
|
|
264
278
|
def main():
|
|
265
279
|
ap = argparse.ArgumentParser()
|
|
266
280
|
ap.add_argument("--n-q", type=int, default=20)
|
|
@@ -287,6 +301,7 @@ def main():
|
|
|
287
301
|
print(f"中文层:本地 {len(man_zh)} 条(查询词本地 {len(man_q)} 条),"
|
|
288
302
|
f"缓存合计 {len(cache)} 条,模型 {MODEL}(本轮不调用)")
|
|
289
303
|
|
|
304
|
+
# 生效条件:对 r 调 zh_layer(r, cache)(cache 为闭包变量)成功时返回 (r["id"], 中文层, None);zh_layer 抛任何异常时返回 (r["id"], "", f"{type(exc).__name__}: {exc}")。
|
|
290
305
|
def work(r):
|
|
291
306
|
try:
|
|
292
307
|
return r["id"], zh_layer(r, cache), None
|
|
@@ -393,4 +408,4 @@ def main():
|
|
|
393
408
|
|
|
394
409
|
|
|
395
410
|
if __name__ == "__main__":
|
|
396
|
-
sys.exit(main())
|
|
411
|
+
sys.exit(main())
|