app:
  description: 保険アジャスター向け：事故説明から損害項目ごとの概算金額を算出し、合計・過失考慮後の支払見込み・注意点・追加調査項目を出力するワークフロー
  icon: 🤖
  icon_background: '#FFEAD5'
  mode: workflow
  name: 損害額概算見積もり支援
  use_icon_as_answer_icon: false
kind: app
version: 0.6.0
workflow:
  conversation_variables: []
  environment_variables: []
  features:
    file_upload:
      image:
        enabled: false
    opening_statement: ''
    suggested_questions: []
    suggested_questions_after_answer:
      enabled: false
    text_to_speech:
      enabled: false
  graph:
    edges:
    - data:
        sourceType: start
        targetType: llm
      id: start-to-llm1
      source: start
      target: llm1
    - data:
        sourceType: llm
        targetType: code
      id: llm1-to-code1
      source: llm1
      target: code1
    - data:
        sourceType: code
        targetType: llm
      id: code1-to-llm2
      source: code1
      target: llm2
    - data:
        sourceType: llm
        targetType: end
      id: llm2-to-end
      source: llm2
      target: end
    nodes:
    - data:
        title: 開始
        type: start
        variables:
        - label: query
          max_length: 2048
          options: []
          required: true
          type: paragraph
          variable: query
      height: 90
      id: start
      position:
        x: 80
        y: 282
      type: custom
      width: 244
    - data:
        title: 分析・金額算出
        type: llm
        model:
          provider: openai
          name: gpt-5-mini
          mode: chat
          completion_params:
            temperature: 0.2
        prompt_template:
        - role: system
          text: あなたは保険アジャスター支援の専門家です。与えられた事故説明から、車種・年式・市場価格、損傷部位別の修理相場、人身被害の慰謝料基準（自賠責基準と任意基準）などを考慮して、損害項目ごとに具体的な金額を算出してください。算出は入力の具体的な数値・状況に基づいて行い、妥当な根拠（市場価格参照、修理見積の相場、基準表の値、計算式）を必ず示してください。出力は厳密に指定のJSONフォーマットのみ返してください。
        - role: user
          text: "入力テキスト: {{#start.query#}}\n出力JSON仕様（必須、余計な説明禁止）: {\n  \"vehicle\"\
            : {\n    \"make_model\": \"文字列\",\n    \"year\": \"年式または推定\",\n    \"\
            market_value\": { \"min\": 数値, \"max\": 数値, \"currency\": \"JPY\" }\n\
            \  },\n  \"damage_items\": [\n    {\n      \"name\": \"例: フロントバンパー交換\"\
            ,\n      \"calc_details\": \"計算根拠を短く記述（参照相場や計算式）\",\n      \"min\": 数値,\n\
            \      \"max\": 数値,\n      \"currency\": \"JPY\"\n    }\n    // 複数要素\n\
            \  ],\n  \"personal_injury\": {\n    \"description\": \"人的被害の要約\",\n \
            \   \"basis\": \"自賠責/任意 どちらで算出したか\",\n    \"min\": 数値,\n    \"max\": 数値,\n\
            \    \"currency\": \"JPY\"\n  },\n  \"subtotals\": { \"min\": 数値, \"max\"\
            : 数値, \"currency\": \"JPY\" },\n  \"negligence_percent\": 数値,  // 例: 20\
            \ なら過失割合20%\n  \"payable_after_negligence\": { \"min\": 数値, \"max\": 数値,\
            \ \"currency\": \"JPY\" },\n  \"assessment_notes\": \"査定時の注意点（短い箇条書き）\"\
            ,\n  \"additional_investigations\": \"追加調査項目（短い箇条書き）\"\n}\n追加指示: - 全ての金額は日本円（JPY）で整数（円）に丸めること。\
            \ - 各金額には必ず根拠を calc_details に記載すること（例: 部品代○○円+工賃○○円、参考市場価格○○円、基準表の該当値等）。\
            \ - personal_injury は入力に具体的な怪我の記載がなければ、null ではなく \"該当なし\" など明確に示し、金額は0とする。\
            \ - negligence_percent が入力に明確な記載がない場合は推定値を入れ、その根拠を assessment_notes に記載すること。\
            \ - 出力は必ず上記JSON構造に忠実にし、追加のテキストや解説は一切付けないこと。"
        vision:
          enabled: false
        memory: null
        context:
          enabled: false
      height: 90
      id: llm1
      position:
        x: 380
        y: 282
      type: custom
      width: 244
    - data:
        title: 計算検証
        type: code
        code_language: python3
        code: "def _safe_str(v):\n    \"\"\"Convert any value to string safely.\"\"\
          \"\n    if v is None:\n        return \"\"\n    if isinstance(v, list):\n\
          \        return \"\\n\".join(str(i) for i in v)\n    return str(v)\n\ndef\
          \ _safe_list(v):\n    \"\"\"Ensure value is a list.\"\"\"\n    if v is None:\n\
          \        return []\n    if isinstance(v, str):\n        return [v]\n   \
          \ if isinstance(v, list):\n        return v\n    return [v]\n\ndef main(**kwargs)\
          \ -> dict:\n    inputs = kwargs\n    import json\n    text = inputs.get(\"\
          text\", \"\")\n    # 初期化\n    try:\n        data = json.loads(text)\n  \
          \  except Exception as e:\n        return dict(output=dict(error=\"parse_error\"\
          , message=str(e), raw=text))\n    # 合計算出（damage_items と personal_injury\
          \ を合算）\n    total_min = 0\n    total_max = 0\n    try:\n        items =\
          \ data.get(\"damage_items\", [])\n        if items is None:\n          \
          \  items = []\n        for it in items:\n            # 安全のためキー存在確認\n   \
          \         try:\n                minv = int(it.get(\"min\", 0))\n       \
          \     except Exception:\n                try:\n                    minv\
          \ = int(float(it.get(\"min\", 0)))\n                except Exception:\n\
          \                    minv = 0\n            try:\n                maxv =\
          \ int(it.get(\"max\", 0))\n            except Exception:\n             \
          \   try:\n                    maxv = int(float(it.get(\"max\", 0)))\n  \
          \              except Exception:\n                    maxv = 0\n       \
          \     total_min = total_min + minv\n            total_max = total_max +\
          \ maxv\n    except Exception:\n        pass\n    # personal_injury\n   \
          \ try:\n        pi = data.get(\"personal_injury\", {})\n        pi_min =\
          \ int(pi.get(\"min\", 0))\n        pi_max = int(pi.get(\"max\", 0))\n  \
          \  except Exception:\n        pi_min = 0\n        pi_max = 0\n    total_min\
          \ = total_min + pi_min\n    total_max = total_max + pi_max\n    # 市場価値が損害査定に含まれる場合の扱い（もしmarket_value存在なら無視せずに含めるよう設計）\n\
          \    # ここでは subtotals がある場合はそれを尊重、なければ上で計算した total を使用\n    try:\n     \
          \   subt = data.get(\"subtotals\", {})\n        if subt and subt.get(\"\
          min\") is not None:\n            subt_min = int(subt.get(\"min\", total_min))\n\
          \            subt_max = int(subt.get(\"max\", total_max))\n        else:\n\
          \            subt_min = total_min\n            subt_max = total_max\n  \
          \  except Exception:\n        subt_min = total_min\n        subt_max = total_max\n\
          \    # 過失考慮\n    try:\n        neg = float(data.get(\"negligence_percent\"\
          , 0.0))\n    except Exception:\n        neg = 0.0\n    payable_min = int(round(subt_min\
          \ * (100.0 - neg) / 100.0))\n    payable_max = int(round(subt_max * (100.0\
          \ - neg) / 100.0))\n    # 書き戻し\n    data[\"computed_subtotals\"] = dict(min=subt_min,\
          \ max=subt_max, currency=data.get(\"subtotals\", {}).get(\"currency\", \"\
          JPY\"))\n    data[\"computed_payable_after_negligence\"] = dict(min=payable_min,\
          \ max=payable_max, currency=\"JPY\")\n    return dict(output=data)\n"
        variables:
        - value_selector:
          - llm1
          - text
          variable: text
        outputs:
          output:
            type: object
            children: null
      height: 90
      id: code1
      position:
        x: 680
        y: 282
      type: custom
      width: 244
    - data:
        title: 最終レポート整形
        type: llm
        model:
          provider: openai
          name: gpt-5-mini
          mode: chat
          completion_params:
            temperature: 0.2
        prompt_template:
        - role: system
          text: 'あなたは保険査定レポートの専門家です。入力の構造化データを受け取り、査定書式で分かりやすく出力してください。


            ---


            【最終出力フォーマット (この指示が最優先)】

            最終出力は **読みやすい日本語の Markdown** で返してください。JSON

            配列・オブジェクトをそのまま出力してはいけません。

            - 見出し (## / ###) でセクションを区切る

            - リスト (- / 1.) や表 (| ... |) で構造化

            - 各項目の意図や根拠が分かるよう短い説明文を添える

            - 営業デモで顧客に直接見せられる体裁にする


            (構造化されたデータ項目を内部で扱うのは構いませんが、出力時に Markdown

            に変換してください。)'
        - role: user
          text: '以下の構造化データを元に、最終出力を作成してください。出力は人間がそのまま提示・保存できる体裁に整形してください（日本語）。必須で含めるセクション:
            1) 損害項目ごとの分類と各項目の概算金額（各項目のcalc_detailsを明記） 2) 合計推定損害額（最小〜最大レンジ） 3) 過失割合を考慮した実際の支払い見込み額（最小〜最大）
            4) 査定時の注意点（箇条書き） 5) 追加調査項目（箇条書き）

            構造化データ: {{#code1.output#}}

            注意: - 数値は円表記で桁区切り（例: 120,000円）の形式にすること。 - 箇条書きは短い項目で列挙すること。 - 入力の具体的数値に基づいた計算根拠を必ず示すこと。
            - 余計な一般論は最小限にし、入力に基づく具体的算出結果を中心にすること。'
        vision:
          enabled: false
        memory: null
        context:
          enabled: false
      height: 90
      id: llm2
      position:
        x: 980
        y: 282
      type: custom
      width: 244
    - data:
        title: 終了
        type: end
        outputs:
        - value_selector:
          - llm2
          - text
          variable: result
      height: 90
      id: end
      position:
        x: 1280
        y: 282
      type: custom
      width: 244
  hash: null
