File size: 5,135 Bytes
52f8cc8
3adcf90
 
 
 
 
 
 
52f8cc8
 
 
 
 
 
 
3adcf90
 
 
52f8cc8
 
3adcf90
 
 
52f8cc8
 
3adcf90
 
 
52f8cc8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3adcf90
52f8cc8
3adcf90
52f8cc8
 
 
 
3adcf90
52f8cc8
 
 
 
 
 
3adcf90
52f8cc8
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import gradio as gr
import pandas as pd
import numpy as np
import os
from openai import OpenAI

# --- OpenAI設定 ---
api_key = os.getenv("OPENAI_API_KEY")

def analyze_cd_logic(m_file, p_file, target_brand):
    if not api_key:
        return "❌ OpenAI APIキーが設定されていません。Settings > Secretsを確認してください。"
    if m_file is None or p_file is None or not target_brand:
        return "⚠️ 原紙マスタ、製品マップの両方をアップロードし、銘柄名を入力してください。"

    client = OpenAI(api_key=api_key)

    try:
        # データ読み込み
        m_df = pd.read_csv(m_file.name)
        if '1' in m_df.columns:
            m_df.columns = m_df.iloc[0]
            m_df = m_df[1:].reset_index(drop=True)
            
        p_df = pd.read_csv(p_file.name)
        if '基礎情報' in p_df.columns:
            p_df.columns = p_df.iloc[0]
            p_df = p_df[1:].reset_index(drop=True)

        # 1. 銘柄特定ロジック
        mask = (m_df['親品番'].astype(str) == target_brand) | \
               (m_df['銘柄名'].astype(str) == target_brand) | \
               (m_df.iloc[:, 2].astype(str) == target_brand)
        
        brand_data = m_df[mask]
        if brand_data.empty:
            return f"❌ 銘柄「{target_brand}」は見つかりませんでした。"
        
        spec = brand_data.iloc[0]
        findings = []

        # --- ロジック抽出 ---
        # A. 共用銘柄化(単価差)
        all_same_parent = m_df[m_df['親品番'] == spec['親品番']].copy()
        all_same_parent['price'] = pd.to_numeric(all_same_parent['仕入単価(新)'], errors='coerce')
        if all_same_parent['製紙会社'].nunique() > 1:
            findings.append(f"【共用銘柄化】同一品番内で単価乖離あり(最大差:{all_same_parent['price'].max() - all_same_parent['price'].min()}円)。安値メーカーへの集約。")

        # B. 環境対応(1Gナレッジ)
        if str(spec.get('古紙使用フラグ')) == '1':
            findings.append("【環境対応見直し】古紙配合品からFSC認証紙へのスペック変更。1G成功事例(▲18M)に基づくコストダウン。")

        # C. 一般品化
        if '1' in [str(spec.get('特抄フラグ')), str(spec.get('特寸フラグ'))]:
            findings.append("【価値の再定義】特抄・特寸仕様を廃止し、汎用JIS規格品へ切り替え。競争環境の再構築。")

        # D. 坪量適正化
        gram = pd.to_numeric(spec['坪量 g/㎡'], errors='coerce')
        if not np.isnan(gram) and gram > 70:
            findings.append(f"【仕様変更】現行{gram}g/㎡。製品要件を再定義し薄物化による面積単価低減。")

        if not findings:
            return "💡 明確な自動判定ロジックに該当する施策が見つかりませんでした。個別交渉を検討してください。"

        # OpenAIによる詳細化
        prompt = f"""
        あなたは調達戦略スペシャリストです。以下の分析結果を、実務的な「CD施策シート」に変換してください。
        交渉メール、挨拶、反論対策は一切不要です。論理性と具体的アクションのみを出力してください。

        【対象銘柄】: {target_brand} ({spec['製紙会社']} / {spec['仕入単価(新)']}円)
        【抽出された事実】:
        {"/".join(findings)}

        【出力項目】
        各項目について以下を記載:
        1. 切り口
        2. 具体的な方法
        3. 現状の課題(データ根拠)
        4. 提案内容と期待効果(具体的アクション)
        """

        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[{"role": "system", "content": "論理的な調達分析官として振る舞ってください。"},
                      {"role": "user", "content": prompt}],
            temperature=0.3
        )
        return response.choices[0].message.content

    except Exception as e:
        return f"解析エラー: {str(e)}"

# --- Gradio UI ---
with gr.Blocks(title="CDG AI Strategist") as demo:
    gr.Markdown("# 🛡️ CDG AI Strategist - 資材1G論理分析")
    gr.Markdown("原紙マスタと製品マップから、利益貢献の切り口に基づいた具体的CD案を生成します。")
    
    with gr.Row():
        with gr.Column():
            m_input = gr.File(label="1. 原紙マスタ(CSV)をアップロード")
            p_input = gr.File(label="2. 製品マップ(CSV)をアップロード")
            brand_input = gr.Textbox(label="3. 分析対象の銘柄名を入力", placeholder="例: Jウメ70AC")
            btn = gr.Button("分析実行", variant="primary")
        
        with gr.Column():
            output = gr.Markdown(label="CD施策詳細レポート")

    btn.click(fn=analyze_cd_logic, inputs=[m_input, p_input, brand_input], outputs=output)

# HuggingFace用の起動設定
if __name__ == "__main__":
    demo.launch()