/** * WPML compatibility functions * * @global array $duplicated_posts Array to store the posts being duplicated. * * @package Yoast\WP\Duplicate_Post * @since 3.2 */ add_action( 'admin_init', 'duplicate_post_wpml_init' ); /** * Add handlers for WPML compatibility. */ function duplicate_post_wpml_init() { if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { add_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'shutdown', 'duplicate_wpml_string_packages', 11 ); } } global $duplicated_posts; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: Renaming a global variable is a BC break. $duplicated_posts = []; /** * Copy post translations. * * @global SitePress $sitepress Instance of the Main WPML class. * @global array $duplicated_posts Array of duplicated posts. * * @param int $post_id ID of the copy. * @param WP_Post $post Original post object. * @param string $status Status of the new post. */ function duplicate_post_wpml_copy_translations( $post_id, $post, $status = '' ) { global $sitepress; global $duplicated_posts; remove_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10 ); remove_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10 ); $current_language = $sitepress->get_current_language(); $trid = $sitepress->get_element_trid( $post->ID ); if ( ! empty( $trid ) ) { $translations = $sitepress->get_element_translations( $trid ); $new_trid = $sitepress->get_element_trid( $post_id ); foreach ( $translations as $code => $details ) { if ( $code !== $current_language ) { if ( $details->element_id ) { $translation = get_post( $details->element_id ); if ( ! $translation ) { continue; } $new_post_id = duplicate_post_create_duplicate( $translation, $status ); if ( ! is_wp_error( $new_post_id ) ) { $sitepress->set_element_language_details( $new_post_id, 'post_' . $translation->post_type, $new_trid, $code, $current_language ); } } } } // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: see above. $duplicated_posts[ $post->ID ] = $post_id; } } /** * Duplicate string packages. * * @global array() $duplicated_posts Array of duplicated posts. */ function duplicate_wpml_string_packages() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: renaming the function would be a BC-break. global $duplicated_posts; foreach ( $duplicated_posts as $original_post_id => $duplicate_post_id ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $original_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $original_post_id ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $new_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $duplicate_post_id ); if ( is_array( $original_string_packages ) ) { foreach ( $original_string_packages as $original_string_package ) { $translated_original_strings = $original_string_package->get_translated_strings( [] ); foreach ( $new_string_packages as $new_string_package ) { $cache = new WPML_WP_Cache( 'WPML_Package' ); $cache->flush_group_cache(); $new_strings = $new_string_package->get_package_strings(); foreach ( $new_strings as $new_string ) { if ( isset( $translated_original_strings[ $new_string->name ] ) ) { foreach ( $translated_original_strings[ $new_string->name ] as $language => $translated_string ) { do_action( // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. 'wpml_add_string_translation', $new_string->id, $language, $translated_string['value'], $translated_string['status'] ); } } } } } } } } DeciKG開発のためのDomainGuide項目一覧 – Raqqa

DeciKG開発のためのDomainGuide項目一覧

業務コンサル向け 入力項目一覧(View定義シート v1)

A. 基本情報(必須)

  1. action_xmlid(例:opportunity_detail
  2. query_keys(例:detail / rank / summary / calibration
  3. 画面名(日本語)(例:案件詳細)
  4. この画面が返す答え(日本語 1〜3行)
    • 例:「案件の現状(ステージ・金額)と、根拠(signals / email / phrase / outcome)を上位N件で返す」
  5. 想定ユーザー(営業/マネージャー/経営など)
  6. 利用シーン(箇条書き3つ)
    • 例:提案前の状況把握、案件会議、失注理由の確認

B. 自然文との対応(必須:将来のNLQに直結)

  1. 意図タグ(intents)(最大5)
    • 候補例:rank detail summary why evidence trend alert compare
  2. 自然文例(最低3つ)
    • 例:「op0104の状況と根拠を見せて」→ query_key=detail
    • 例:「今月危ない案件を上から」→ query_key=rank(+期間params)
  3. 自然文例ごとの“必要ID”が欠けてる場合の扱い
    • 例:「案件名しかない」→候補提示して選ばせる
    • 例:「担当者名だけ」→担当者候補→案件候補

C. 必須ID(slots)設計(必須)

  1. required slots(必須ID)
    • 例:company_id / opp_id / partner_id / rep_id
  2. optional slots(あれば)
  3. 各slotの意味(日本語)
    • opp_id:案件ID、partner_id:顧客ID など
  4. slotの値の例(実例を1つずつ)
  5. slot resolver(候補検索)が必要か(Yes/No)
  6. (必要なら)候補検索の仕様
    • 入力文字列 q で何を検索する?(例:案件名 contains)
    • 並び順(例:updated_at desc)
    • 返す候補の表示項目(例:id,label)

※ここは業務コンサルが “検索の業務ルール” を書く。
Cypherはエンジニアが後で実装してもOK(仕様だけあれば生成できる)。


D. パラメータ(params)設計(必須)

  1. params一覧(例:limit, evidence_limit, months_back
  2. 各paramの
  • 型(int/string/bool)
  • default
  • min/max
  • 意味(日本語)
  • UIで触らせる?(Yes/No)

例:

  • evidence_limit:根拠を何件見せるか(default 10、max 50)

E. 出力(shape_contract)設計(必須:UI契約)

  1. shape_normalized(例:opportunity_detail
  2. 必須フィールド一覧(上位画面で必ず表示する)
  • key / 型 / 意味(日本語)/ 例
  1. 任意フィールド一覧(あれば)
  2. evidenceの種類(配列キー)
  • signals / outcomes / email_events / phrase_stats など
  1. evidence_digest に必ず入れる要約
  • counts(必須)
  • top lines(signals_top など)
  • “0件のときのメッセージ仕様”(重要)

F. 根拠(evidence sources)定義(必須)

  1. evidence source を列挙(最低3つ)
  • entity名(例:ProposalSignal)
  • evidence_type(self_assessment / interaction / language_signal / ground_truth)
  • 見せたい項目(fields)
  • “この根拠が強い条件”(業務ルールがあれば)

例:

  • ProposalSignal:自己申告(確度、痛み、BANT)
  • EmailEvent:顧客とのやりとり(件名、方向、日付)
  • PhraseStat:キーワード頻度(phrase,count)

G. 固定Cypherの仕様(現状フェーズで必須)

  1. このViewの固定Cypherが“何を返すべきか”の要件
  • ノード起点(例:Opportunity)
  • 関連で取るエッジ種別(HAS_SIGNAL 等)
  • limitの適用場所(Cypher側でslice or postprocess)
  1. 並び順の業務ルール
  • signalsは何を優先?(確度/痛み/新しさ等)
  • emailは新しい順?
  • phraseは回数順?
  1. postprocessでやること(箇条書き)
  • sort / clip / digest生成 / 欠損補完

H. (将来)SQL生成フェーズ用の最小契約(任意:今は薄くてOK)

  1. base_grain(例:opp)
  2. tenant filter(例:company_id 必須)
  3. COUNT(*)禁止などのルール(Yes/No)
  4. join_profile_ref(RPC_VIEW_CATALOGのキーだけ)
  5. metrics/dimensions(必要なら)
  • KPI名、意味、grain、禁止パターン、式(分かる範囲で)

生成物(このシートから自動生成するもの)

  • packs/<action_xmlid>.yaml(decikgブロック入り)
  • (任意)registry.json(action_xmlid/query_key → shape/slots/params)
  • (任意)resolver用の cypher_resolvers/<action_xmlid>/*.cypher スケルトン

最小で埋めるなら(“業務コンサルの必須範囲”)

まずは A〜G を埋めれば **今の工程3(固定Cypher)**は回せます。
H は将来のNLQ/SQLフェーズで追加すればOKです。

了解です。ここでは **4 pack(opportunity_pipeline / opportunity_detail / customer_360 / rep_calibration)**について、先ほどの「業務コンサル向け入力シート」を **“完成記入例”**として埋めたものを出します。

前提(あなたの現状に合わせた仮定)

  • 起点ノード:(:Opportunity)(:Partner)(:SalesRep)
  • 根拠ノード:(:ProposalSignal) / (:Outcome) / (:EmailEvent) / (:PhraseStat)
  • テナント:company_id(必須)
  • 既に固定Cypher+postprocess(evidence_limit・digest)が動いている前提で、**業務側が決めるべき「意味」と「ルール」**を中心に書きます(Cypher文そのものは後で調整可)。

作成具体例

1) Pack: opportunity_pipeline(ランキング)

A. 基本情報

  • action_xmlid: opportunity_pipeline
  • query_key: rank
  • 画面名(JP): 案件ランキング(優先フォロー)
  • 返す答え(JP):
    「会社内の案件を、根拠(signals / email / phrase / outcome)量に基づいてスコア化し、上位N件を返す」
  • 想定ユーザー: 営業マネージャー / チームリーダー
  • 利用シーン:
    • 週次の案件会議の事前確認
    • フォロー優先度の決定
    • 根拠の薄い案件の洗い出し

B. 自然文との対応

  • intent tags: rank, priority, evidence
  • 自然文例 → 対応:
    1. 「今月、優先して追うべき案件を上から出して」→ rank(months_back=1)
    2. 「動きが多い案件トップ10」→ rank(limit=10)
    3. 「根拠が多い案件を見たい」→ rank(limit指定)
  • 必要IDが欠けている場合:
    • company_id が無い → UI側はログイン/選択して必ず付与(エラーにしてよい)

C. slots(必須ID)

  • required_slots: company_id
  • optional_slots: (将来)period_id(月指定)など
  • slot意味:
    • company_id: テナント会社ID(例: c001

D. params

  • limit: int, default=5, min=1, max=50
    • 表示件数
  • (将来)months_back: int, default=1, min=1, max=24
    • “対象期間”を導入するなら(固定Cypherを期間条件付きに拡張)

E. 出力(shape)

  • shape_normalized: rank_rows
  • 必須フィールド:
    • opp_id: str
    • partner_id: str
    • rep_id: str
    • name: str
    • score: number
    • signal_count/email_event_count/phrase_stat_count/outcome_count: int
    • rank: int(postprocessで付与)
  • 任意:
    • stage(あると便利)
  • evidence_digest:
    • counts(必須)
    • topの見せ方:ランキングは詳細ではないので、digestはcounts中心でOK(詳細は detail に委譲)

F. 根拠(evidence sources)

  • ProposalSignal(self_assessment): fit_grade / self_probability / BANT系 / pain_severity
  • EmailEvent(interaction): direction / subject / created_at
  • PhraseStat(language_signal): phrase / count / created_at
  • Outcome(ground_truth寄り): status / created_at

G. 固定Cypher仕様(業務要件)

  • 起点:Opportunity(company_idで絞る)
  • 関連:signals/outcomes/email/phrase を OPTIONAL MATCH
  • スコア(業務ルール)例:
    score = signal*3 + email*2 + phrase*1 + outcome*1
    (※この重みはコンサルが決める。今の実装と一致していればOK)
  • 並び順:score desc、同点は opp_id asc(安定)

2) Pack: opportunity_detail(1件詳細+根拠)

A. 基本情報

  • action_xmlid: opportunity_detail
  • query_key: detail
  • 画面名(JP): 案件詳細(根拠付き)
  • 返す答え(JP):
    「指定した案件1件について、基本情報(ステージ・金額など)と根拠(signals / email / phrase / outcome)を重要順に上位N件返す」
  • 想定ユーザー: 営業担当 / マネージャー
  • 利用シーン:
    • 案件会議での“現状説明”
    • 根拠(兆候・メール・キーワード)の確認
    • 次アクションの判断材料

B. 自然文との対応

  • intent tags: detail, why, evidence
  • 自然文例 → 対応:
    1. 「op0001の状況と根拠を見せて」→ detail(opp_id=op0001)
    2. 「案件“東和テクノ”の根拠を見たい」→ resolver(名前→opp候補→選択→detail)
    3. 「この案件、確度の根拠は?」→ detail(signals優先表示+digest)
  • 必要ID欠け:
    • opp_idが無い → 候補提示が必要(別クエリ/別機能)

C. slots

  • required_slots: company_id, opp_id
  • optional_slots: (将来)partner_id(あれば整合チェックに使う)
  • 意味:
    • opp_id: 案件ID(例: op0001

D. params

  • evidence_limit: int, default=10, min=0, max=50
    • 根拠を何件返すか(signals/outcomes/email/phraseに同じlimitを適用)
  • (将来)evidence_sort_mode: str, default=important
    • important|recent のように業務用途で切替

E. 出力(shape)

  • shape_normalized: opportunity_detail
  • 必須フィールド:
    • opp_id/partner_id/rep_id/name
    • stage(または status)
    • amount(expected_revenue)
    • evidence: {signals[], outcomes[], email_events[], phrase_stats[]}
    • evidence_digest(必須)
  • evidence_digest(必須仕様)
    • counts: signals/outcomes/email_events/phrase_stats の件数
    • signals_top: 上位数件の1行要約(例:signal_id fit=... p=0.82 TBDC
    • email_events_top: email_event_id direction subject(短縮)
    • phrase_stats_top: phrase_stat_id xN phrase(短縮)
    • outcomes_top: outcome_id status
    • 0件時メッセージ(重要):
      • 「(no signals) opp_id=… stage=… amount=…」みたいに **“空でも解析できる”**文字列を入れる

F. 根拠(evidence sources)

  • ProposalSignal(自己申告):
    • self_probability(確度)、pain_severity(痛み)、BANT(予算/決裁者/期限)、fit_grade
  • EmailEvent(やりとり):
    • 方向(in/out)、件名、日時(新しい順も可)
  • PhraseStat(言語兆候):
    • キーフレーズと頻度(countが無い場合はルールで “頻度=1扱い” としてもOK)
  • Outcome(結果):
    • 勝ち/負け/保留 など(statusが無いなら stage を代用しても良い)

G. 固定Cypher仕様

  • 起点:Opportunity(company_id, opp_id)
  • OPTIONAL:signals/outcomes/email/phrase を収集
  • evidence_limit は Cypher slice でも postprocess でもよいが、最終結果として必ず limit に一致すること

3) Pack: customer_360(顧客サマリ)

A. 基本情報

  • action_xmlid: customer_360
  • query_key: summary
  • 画面名(JP): 顧客360(案件・根拠の俯瞰)
  • 返す答え(JP):
    「顧客に紐づく案件数と、根拠(signals/email/phrase/outcome)の総量、さらに上位の案件(top_opportunities)を返す」
  • 想定ユーザー: 営業担当 / マネージャー / CS
  • 利用シーン:
    • 顧客との関係の温度感把握
    • 顧客内で動いている案件の全体像
    • 次の提案先/重点顧客の選定

B. 自然文との対応

  • intent tags: summary, customer_360, portfolio
  • 自然文例 → 対応:
    1. 「顧客35の全体状況を見せて」→ summary(partner_id=35)
    2. 「東和テクノの案件状況まとめて」→ resolver(顧客名→partner候補→summary)
    3. 「この顧客、案件動いてる?」→ summary(opportunity_count中心)

C. slots

  • required_slots: company_id, partner_id
  • 意味:
    • partner_id: 顧客ID

D. params

  • limit: int, default=10, min=1, max=50
    • top_opportunitiesの上限

E. 出力(shape)

  • shape_normalized: customer_360_summary
  • 必須フィールド:
    • partner_id, name
    • opportunity_count
    • signal_count/outcome_count/email_event_count/phrase_stat_count
    • partner_phrase_stat_count(顧客単位のPhraseがあれば)
    • top_opportunities[](上位案件の配列)
  • 任意:
    • evidence_bundles(上位案件ごとのミニ根拠まとめ:あるとUIが強くなる)
  • 0件の扱い:
    • counts系は必ず0で返す(null禁止)

F. 根拠(evidence sources)

  • Opportunity(顧客にぶら下がる案件)
  • ProposalSignal/EmailEvent/PhraseStat/Outcome(案件由来の根拠)
  • (任意)Partner直のPhraseStat(顧客全体の兆候)

G. 固定Cypher仕様

  • Partner(company_id, partner_id) を起点
  • 同一顧客の Opportunity を収集
  • top_opportunities は “案件ごとのスコア” でソートして上位 limit
    • スコア式は opportunity_pipeline と同型でOK(業務一貫性)

4) Pack: rep_calibration(担当者較正レポート)

A. 基本情報

  • action_xmlid: rep_calibration
  • query_key: calibration
  • 画面名(JP): 担当者較正(案件の偏り・根拠量)
  • 返す答え(JP):
    「担当者の案件数・根拠総量、ステージ分布、上位案件(top_opportunities)を返す」
  • 想定ユーザー: 営業マネージャー
  • 利用シーン:
    • 担当者の案件の偏り(初期ばかり/終盤ばかり)
    • 活動量や兆候量に比べて案件数が多すぎる/少なすぎるの把握
    • 指導・アサイン調整

B. 自然文との対応

  • intent tags: calibration, rep_dashboard, distribution
  • 自然文例 → 対応:
    1. 「u16の案件状況を較正して」→ calibration(rep_id=u16)
    2. 「担当者ごとの案件のステージ偏りを見たい」→ 将来は rank系/一覧系へ拡張
    3. 「この人、根拠の薄い案件が多い?」→ calibration(counts+top_opportunities)

C. slots

  • required_slots: company_id, rep_id

D. params

  • limit: int, default=10, min=1, max=50

E. 出力(shape)

  • shape_normalized: rep_calibration
  • 必須フィールド:
    • rep_id, name
    • opportunity_count
    • signal_count/outcome_count/email_event_count/phrase_stat_count
    • stage_buckets[](例:[{stage:”qualified”, count:12}, …])
    • top_opportunities[](上位案件)
  • 任意:
    • evidence_bundles(上位案件に紐づくミニ根拠)

F. 根拠(evidence sources)

  • Opportunity(担当者の案件)
  • signals/email/phrase/outcome(案件由来)
  • stage_buckets(“偏り”の根拠)

G. 固定Cypher仕様

  • SalesRep(company_id, rep_id)起点
  • Opportunity(company_id, rep_id)収集
  • stage_buckets は stage ごとに count
  • top_opportunities は案件スコア順

requests.jsonl / responses.jsonl の「具体例(言葉で)」

あなたが言っていた流れを、この4 packで“目で追える形”にするとこうです。

入力(requests_*.jsonl)で指定していること

  1. どの画面ロジックを使うかaction_xmlid
  2. その画面のどの固定クエリかquery_key
  3. 必須ID(DBを絞る鍵):slots(company_id/opp_id/partner_id/rep_id など)
  4. 表示の都合の調整params(limit / evidence_limit など)

つまり requests は “将来の自然文”の中身を、機械が実行できる形に正規化したものです。
将来NLQ(自然文)では、ここがこう変わります:

  • 自然文 →(分類)→ action_xmlid / query_key を決める
  • 自然文 →(抽出)→ slots(company_id, opp_id …)を埋める
  • 自然文 →(補完)→ params(limit/evidence_limit)を埋める
  • そして同じエンジンで実行する(固定Cypher or 将来SQL)

出力(responses_*.jsonl)で返しているもの

  • status=ok/error
  • 結果(画面が必要な形)
  • evidence(根拠の配列:signals/email/phrase/outcome)
  • digest(jqで件数や上位行を機械チェックできる “監査用要約”)

今あなたが直した TypeError(pp_opportunity_detail に slots が渡って落ちる問題)は、
「入力の正規形(requests)を将来拡張しても postprocess が壊れない」ために重要でした。
だからこそ “requests を入口にする意味” が出ます(後から slots/params が増えても壊れにくい)。


必要なら次に、上の「記入例」をそのまま YAML(decikgブロック)に落とす **生成後のサンプル(4ファイル)**も作ります。
ただ、まずはこの “業務コンサルに渡す1枚仕様” が理解できているかが最重要なので、ここまでで一旦OKです。


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です