design

View:24/48/All/

全3件を表示

  • youtube動画をご覧ください。 ↓↓↓
    宜しくお願い致します。

     

    00 自己紹介:<br>AI System Engineer × DATA Scientist<br>徐東秀(ソドンス) SEO DongSoo

    00 自己紹介:
    AI System Engineer × DATA Scientist
    徐東秀(ソドンス) SEO DongSoo

    続きを読む
    Quick View
  • 31 39Safari 「ロゴデザイン」

    31 39Safari 「ロゴデザイン」

    続きを読む
    Quick View
  • #core
    import os
    import sys
    import time
    from dotenv import load_dotenv

    import streamlit as st
    from langchain_openai import (
    AzureOpenAIEmbeddings,
    OpenAIEmbeddings,
    AzureChatOpenAI,
    ChatOpenAI
    )
    try:
    from langchain_google_vertexai import ChatVertexAI
    except ImportError:
    ChatVertexAI = None

    try:
    from langchain_google_genai import ChatGoogleGenerativeAI
    except ImportError:
    ChatGoogleGenerativeAI = None
    from langchain_community.vectorstores import FAISS
    from langchain_core.messages import(
    HumanMessage,
    AIMessage,
    )

    #tools
    import pandas as pd
    import numpy as np

    #import
    from src.config import system_config
    from src.rag_oop import B612ai
    from src.logo import logo_img
    from src.estimate_generator import EstimateGenerator
    from src.sidebar import render_common_sidebar, clear_chat_history

    USER_ICON = “user”
    ASSISTANT_ICON = “assistant”

    def create_embeddings():
    “””埋め込みモデルを作成”””
    api_config = system_config.api_config

    if api_config.is_azure_embedding_configured():
    # Azure OpenAI Embeddingsを使用
    embedding_config = api_config.get_azure_embedding_config()
    return AzureOpenAIEmbeddings(
    azure_deployment=embedding_config[‘deployment’],
    openai_api_version=embedding_config[‘api_version’]
    )
    elif api_config.is_openai_configured():
    # OpenAI Embeddingsを使用
    return OpenAIEmbeddings(model=’text-embedding-3-small’)
    else:
    st.error(‘埋め込みモデルのAPI Keyが設定されていません。’)
    return None

    def create_model(selected_model=None):
    “””言語モデルを作成”””
    api_config = system_config.api_config
    model_config = system_config.model_config

    if api_config.is_azure_configured():
    # Azure OpenAIを使用
    azure_config = api_config.get_azure_config()
    return AzureChatOpenAI(
    azure_deployment=azure_config[‘deployment’],
    openai_api_version=azure_config[‘api_version’],
    temperature=model_config.temperature
    )
    elif api_config.is_gemini_configured():
    # Google Geminiを使用
    gemini_config = api_config.get_gemini_config()

    # APIキー方式(Google AI Studio)
    if gemini_config[‘api_key’]:
    if ChatGoogleGenerativeAI is None:
    st.error(‘langchain-google-genai パッケージがインストールされていません。’)
    st.info(‘以下のコマンドでインストールしてください: pip install langchain-google-genai’)
    return None

    return ChatGoogleGenerativeAI(
    model=gemini_config[‘model_name’],
    google_api_key=gemini_config[‘api_key’],
    temperature=model_config.temperature
    )

    # Vertex AI方式
    elif gemini_config[‘project_id’]:
    if ChatVertexAI is None:
    st.error(‘langchain-google-vertexai パッケージがインストールされていません。’)
    st.info(‘以下のコマンドでインストールしてください: pip install langchain-google-vertexai’)
    return None

    return ChatVertexAI(
    model_name=gemini_config[‘model_name’],
    project=gemini_config[‘project_id’],
    location=gemini_config[‘location’],
    temperature=model_config.temperature
    )
    else:
    st.error(‘Geminiの設定が不完全です。APIキーまたはプロジェクトIDを設定してください。’)
    return None

    elif api_config.is_openai_configured():
    # OpenAI APIを使用(選択されたモデルに基づく)
    if selected_model:
    # 選択されたモデルに基づいてモデル名を決定
    model_mapping = {
    “gpt-3.5”: “gpt-3.5-turbo”,
    “gpt-4o”: “gpt-4o”,
    “gpt-o1”: “o1-preview”,
    “gpt-5”: “gpt-5” # 将来のモデル
    }
    model_name = model_mapping.get(selected_model, “gpt-3.5-turbo”)
    else:
    openai_config = api_config.get_openai_config()
    model_name = openai_config[‘api_version’] if openai_config[‘api_version’] else “gpt-3.5-turbo”

    return ChatOpenAI(
    model=model_name,
    temperature=model_config.temperature
    )
    else:
    st.error(‘言語モデルのAPI Keyが設定されていません。’)
    return None

    def main():
    # システム設定のチェック(load_dotenv()はconfig.pyで実行済み)
    if not system_config.check_system_health():
    st.stop()

    size = “large”
    logo_img(size)

    # 共通のサイドバーをレンダリング
    render_common_sidebar()
    clear_chat_history()

    st.title(‘📄 見積書作成ページ’)
    st.caption(“AIチャットの内容をもとに、Excel見積書を自動生成します”)

    # 埋め込みモデルと言語モデルの作成
    embeddings = create_embeddings()

    # セッション状態から選択されたモデルを取得
    selected_model = st.session_state.get(‘selected_model’, ‘gpt-3.5’)
    model = create_model(selected_model)

    if embeddings is None or model is None:
    st.error(“モデルの初期化に失敗しました。”)
    st.stop()

    # B612aiの初期化
    rag_system = B612ai(
    model=model,
    embeddings=embeddings,
    chunk_size=system_config.model_config.chunk_size,
    chunk_overlap=system_config.model_config.chunk_overlap
    )

    # FAISSベクトルストアの読み込み(存在しない場合はエラーメッセージを表示)
    retriever = rag_system.pull_from_faiss()

    # ベクトルストアをB612aiに設定
    rag_system.vectorstore = FAISS.load_local(“vector_store”, rag_system.embeddings, allow_dangerous_deserialization=True)
    rag_system.retriever = rag_system.vectorstore.as_retriever()

    if “chat_log” not in st.session_state:
    st.session_state.chat_log = []

    # チャット履歴の表示(プレーンテキストで表示してスマホエラーを回避)
    if len(st.session_state.chat_log) > 0:
    st.subheader(“💬 チャット履歴”)
    for chat in st.session_state.chat_log:
    if isinstance(chat, AIMessage):
    with st.chat_message(ASSISTANT_ICON):
    st.text(chat.content)
    else:
    with st.chat_message(USER_ICON):
    st.text(chat.content)

    # 見積書作成機能
    if len(st.session_state.chat_log) > 0:
    st.divider()
    st.subheader(“📄 見積書作成”)
    st.caption(“チャット履歴から見積書情報を抽出してExcel見積書を作成します”)

    # オレンジ色のボタンスタイル(スマホブラウザ対応)
    st.markdown(“””
    <style>
    /* Primaryボタンのスタイル */
    button[kind=”primary”] {
    background-color: #FFA421 !important;
    color: white !important;
    border: none !important;
    }
    button[kind=”primary”]:hover {
    background-color: #FFB84D !important;
    color: white !important;
    }

    /* ダウンロードボタンのスタイル */
    div[data-testid=”stDownloadButton”] button {
    background-color: #FFA421 !important;
    color: white !important;
    border: none !important;
    }
    div[data-testid=”stDownloadButton”] button:hover {
    background-color: #FFB84D !important;
    color: white !important;
    }
    </style>
    “””, unsafe_allow_html=True)

    col2, = st.columns([1])

    with col2:
    if st.button(” 見積書を作成”, type=”primary”, use_container_width=True):
    with st.spinner(“見積書情報を抽出中…”):
    try:
    # 見積書生成器を初期化
    estimate_generator = EstimateGenerator(model)

    # チャット履歴から見積書情報を抽出
    estimate_info = estimate_generator.extract_estimate_info(st.session_state.chat_log)

    # 見積書情報をExcel形式で表示
    with st.expander(“抽出された見積書情報”, expanded=True):
    # 基本情報を表示
    col_info1, col_info2 = st.columns(2)
    with col_info1:
    st.write(“**顧客名:**”)
    st.write(estimate_info.get(‘company_name’, ‘N/A’))
    st.write(“**見積番号:**”)
    st.write(estimate_info.get(‘estimate_number’, ‘N/A’))
    with col_info2:
    st.write(“**見積日:**”)
    st.write(estimate_info.get(‘estimate_date’, ‘N/A’))
    st.write(“**件名:**”)
    st.write(estimate_info.get(‘title’, ‘N/A’))

    st.divider()

    # 商品・サービス一覧をテーブル形式で表示
    if ‘items’ in estimate_info and estimate_info[‘items’]:
    items_data = []
    for idx, item in enumerate(estimate_info[‘items’], start=1):
    items_data.append({
    ‘No’: idx,
    ‘商品・サービス名’: item.get(‘name’, ”),
    ‘数量’: item.get(‘quantity’, 0),
    ‘単価’: f”¥{item.get(‘unit_price’, 0):,}”,
    ‘金額’: f”¥{item.get(‘amount’, 0):,}”,
    ‘説明’: item.get(‘description’, ”)
    })
    items_df = pd.DataFrame(items_data)
    st.write(“**商品・サービス一覧:**”)
    st.dataframe(items_df, use_container_width=True, hide_index=True)

    st.divider()

    # 金額情報を表示
    col_amount1, col_amount2, col_amount3 = st.columns(3)
    with col_amount1:
    st.write(“**小計:**”)
    st.write(f”¥{estimate_info.get(‘subtotal’, 0):,}”)
    with col_amount2:
    tax_rate = estimate_info.get(‘tax_rate’, 0.1)
    tax_rate_percent = int(tax_rate * 100)
    st.write(f”**消費税 ({tax_rate_percent}%):**”)
    st.write(f”¥{estimate_info.get(‘tax’, 0):,}”)
    with col_amount3:
    st.write(“**合計:**”)
    st.write(f”**¥{estimate_info.get(‘total’, 0):,}**”)

    # 備考がある場合
    if estimate_info.get(‘notes’):
    st.divider()
    st.write(“**備考:**”)
    st.write(estimate_info.get(‘notes’))

    # Excel見積書を作成
    with st.spinner(“Excel見積書を作成中…”):
    excel_path = estimate_generator.create_excel_estimate(estimate_info)

    # ファイルを読み込んでダウンロードボタンとキャンセルボタンを表示
    with open(excel_path, “rb”) as f:
    excel_data = f.read()
    col_download, col_cancel = st.columns(2)
    with col_download:
    st.download_button(
    label=”見積書をダウンロード”,
    data=excel_data,
    file_name=excel_path,
    mime=”application/vnd.openxmlformats-officedocument.spreadsheetml.sheet”,
    use_container_width=True
    )
    with col_cancel:
    if st.button(“キャンセル”, type=”secondary”, use_container_width=True):
    st.info(“見積書の作成をキャンセルしました。”)
    st.rerun()

    # 一時ファイルを削除
    if os.path.exists(excel_path):
    os.remove(excel_path)

    st.success(“✅ 見積書が正常に作成されました!”)

    except Exception as e:
    st.error(f”見積書作成中にエラーが発生しました: {str(e)}”)
    st.exception(e)

    else:
    st.info(“💬 まずチャットで会話を始めてください。会話内容から見積書情報を抽出します。”)

    # チャット入力(プレーンテキストで表示してスマホエラーを回避)
    user_msg = st.chat_input(“メッセージをご入力ください。”)
    if user_msg:
    with st.chat_message(USER_ICON):
    st.text(user_msg)

    # B612aiを使用して回答を生成
    with st.chat_message(ASSISTANT_ICON):
    msg_placeholder = st.empty()

    try:
    # 関連文書を検索
    relavant_docs = rag_system.search(user_msg, k=3)

    # 回答を生成
    response = rag_system.generate_response(user_msg, relavant_docs)

    # ストリーミング表示(プレーンテキストで表示してスマホエラーを回避)
    for i, char in enumerate(response):
    msg_placeholder.text(response[:i+1] + “*”)
    time.sleep(0.01) # ストリーミング効果
    msg_placeholder.text(response)

    # 関連資料の表示(B612aiクラスから)
    rag_system.display_related_images(user_msg, relavant_docs)

    except Exception as e:
    st.error(f”回答生成中にエラーが発生しました: {str(e)}”)
    response = “申し訳ございません。エラーが発生しました。”

    st.session_state.chat_log.extend([
    HumanMessage(content=user_msg),
    AIMessage(content=response)
    ])
    st.rerun()

    if __name__ == ‘__main__’:
    main()

     

    32 雑誌のデザイン

    32 雑誌のデザイン

    続きを読む
    Quick View