– 教師ありデータを作成する(gptで生成)
– Llama 3.1(8Bパラメータ版でも)をLoRAでファインチューニング
(GPUでも異常に時間がかかる)
Month: November 2025
[LLM] Dify Pluginの作り方
# Difyプラグインのデプロイ方法
## デプロイ方法は3つあります
### 1. 🏪 Marketplaceから公開(公式配布)
### 2. 🔗 GitHubリポジトリから配布
### 3. 📦 ローカルファイルとして配布
—
## 前提条件
### Dify CLIツールのインストール
プラグインをパッケージ化するには、Dify CLIツールが必要です。
#### macOS/Linuxの場合(Homebrew)
“`bash
brew tap langgenius/dify
brew install dify
# インストール確認
dify version
“`
#### Windows/Linux/macOSの場合(バイナリ)
1. [Dify Plugin CLI Tool リリースページ](https://github.com/langgenius/dify-plugin-daemon/releases)からバイナリをダウンロード
2. ダウンロードしたファイルに実行権限を付与(macOS/Linux)
“`bash
chmod +x ./dify-plugin-darwin-arm64
mv ./dify-plugin-darwin-arm64 ./dify
“`
3. グローバルに使用する場合は `/usr/local/bin` に移動
“`bash
sudo mv ./dify /usr/local/bin/
“`
—
## 📦 ステップ1: プラグインのパッケージ化
プラグインプロジェクトのディレクトリで以下のコマンドを実行します:
“`bash
# プラグインディレクトリに移動
cd /path/to/your/plugin
# プラグインをパッケージ化
dify plugin package
“`
これにより、`.difypkg` ファイルが生成されます。
例: `weather_plugin-0.0.1.difypkg`
### パッケージング時の注意点
– `manifest.yaml` にバージョン情報が正しく記載されているか確認
– `requirements.txt` に必要な依存関係がすべて記載されているか確認
– プラグインコードにエラーがないか確認
—
## 🚀 ステップ2: デプロイ方法を選択
### 方法1: ローカルファイルとしてアップロード(最も簡単)
これが最も簡単で、開発・テスト段階に最適な方法です。
#### 手順:
1. **Difyの管理画面にアクセス**
– Difyプラットフォームにログイン
– 右上の「Plugins」をクリック
2. **プラグインをアップロード**
– 「+ Install plugin」ボタンをクリック
– 「INSTALL FROM」→「Local Package File」を選択
– 生成した `.difypkg` ファイルを選択してアップロード
3. **プラグインのインストール**
– アップロード後、自動的にインストールが開始されます
– インストールが完了すると、Workspaceで使用可能になります
#### メリット:
– ✅ 最も簡単で素早い
– ✅ レビュー不要
– ✅ 社内・チーム内での配布に最適
– ✅ テスト環境に最適
#### デメリット:
– ❌ ファイルを手動で配布する必要がある
– ❌ 一般公開されない
—
### 方法2: GitHubリポジトリから配布
オープンソースプロジェクトや、バージョン管理が必要な場合に推奨されます。
#### 手順:
1. **GitHubリポジトリを作成**
“`bash
# GitHubで新しいリポジトリを作成
# 例: https://github.com/your-username/dify-weather-plugin
“`
2. **プラグインコードをプッシュ**
“`bash
git init
git add .
git commit -m “Initial commit: Weather plugin”
git remote add origin https://github.com/your-username/dify-weather-plugin.git
git push -u origin main
“`
3. **GitHubリリースを作成**
“`bash
# パッケージ化
dify plugin package
# GitHubのUIでリリースを作成
# 1. GitHubリポジトリ → Releases → Create a new release
# 2. Tag: v0.0.1(manifest.yamlのバージョンと一致させる)
# 3. Title: Weather Plugin v0.0.1
# 4. .difypkg ファイルをアセットとしてアップロード
“`
4. **Difyからインストール**
– Dify管理画面 → Plugins → + Install plugin
– 「INSTALL FROM」→「GitHub」を選択
– リポジトリURL(またはリポジトリ名)を入力
– 例: `your-username/dify-weather-plugin`
– インストール実行
#### メリット:
– ✅ バージョン管理が容易
– ✅ オープンソース化できる
– ✅ GitHubのリリース機能を活用可能
– ✅ 公式レビュー不要
#### デメリット:
– ❌ リポジトリの作成とリリース手順が必要
—
### 方法3: Dify Marketplaceで公開(公式)
多くのユーザーに使ってもらいたい場合や、公式プラグインとして配布したい場合。
#### 手順:
1. **プラグインの準備**
“`bash
# プラグインをパッケージ化
dify plugin package
“`
2. **プライバシーポリシーの作成**
`PRIVACY.md` ファイルを作成し、プラグインのプライバシーポリシーを記載します。
“`markdown
# Weather Plugin Privacy Policy
## Data Collection
This plugin does not collect any personal information.
## External APIs
This plugin makes requests to weather APIs…
“`
3. **manifest.yaml にプライバシーポリシーへのパスを追加**
“`yaml
privacy:
en_US: ./PRIVACY.md
ja_JP: ./PRIVACY_JP.md
“`
4. **dify-pluginsリポジトリをフォーク**
“`bash
# GitHubでフォーク
https://github.com/langgenius/dify-plugins
“`
5. **プラグインを配置**
“`bash
# フォークしたリポジトリをクローン
git clone https://github.com/YOUR_USERNAME/dify-plugins.git
cd dify-plugins
# 組織ディレクトリとプラグインディレクトリを作成
mkdir -p your-organization/weather_plugin
# ソースコードと.difypkgファイルをコピー
cp /path/to/your/plugin/* your-organization/weather_plugin/
cp /path/to/weather_plugin-0.0.1.difypkg your-organization/weather_plugin/
# README.mdを作成(連絡先情報とリポジトリURLを含める)
“`
6. **Pull Requestを作成**
“`bash
git add .
git commit -m “Add Weather Plugin v0.0.1”
git push origin main
# GitHubでPull Requestを作成
# PRテンプレートに従って記入
“`
7. **レビュー待ち**
– Difyチームがコードレビューを実施
– 承認されるとmainブランチにマージ
– 自動的にMarketplaceに公開されます
#### メリット:
– ✅ 公式Marketplaceに掲載
– ✅ 信頼性が高い
– ✅ 多くのユーザーにリーチ可能
– ✅ ワンクリックインストール
#### デメリット:
– ❌ 公式レビューが必要(時間がかかる)
– ❌ プライバシーポリシーなど追加ドキュメントが必要
—
## 🔧 デバッグ方法(リモートデバッグ)
開発中は、リモートデバッグ機能を使うと便利です。
### 手順:
1. **Dify管理画面でデバッグキーを取得**
– Plugins → デバッグアイコンをクリック
– デバッグキーとリモートサーバーアドレスを取得
2. **プラグインプロジェクトで.envファイルを設定**
`.env.example` をコピーして `.env` を作成:
“`bash
cp .env.example .env
“`
`.env` ファイルを編集:
“`bash
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=debug.dify.ai # または localhost(Docker環境の場合)
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****
“`
3. **プラグインを起動**
“`bash
python -m main
“`
4. **リアルタイムでテスト**
– コードを編集
– 保存すると自動的に反映される
– Difyの管理画面でプラグインが使用可能になる
—
## 📝 更新・再デプロイ
### ローカルファイルの場合:
1. バージョン番号を更新(`manifest.yaml`)
2. 再度パッケージ化: `dify plugin package`
3. 新しい `.difypkg` をアップロード
### GitHubの場合:
1. バージョン番号を更新(`manifest.yaml`)
2. 再度パッケージ化: `dify plugin package`
3. 新しいGitHubリリースを作成
4. 新しい `.difypkg` をリリースに添付
### Marketplaceの場合:
1. バージョン番号を更新(`manifest.yaml`)
2. 再度パッケージ化: `dify plugin package`
3. 新しい `.difypkg` ファイルのみをPRとして提出
4. README.mdに破壊的変更を記載
—
## ⚠️ トラブルシューティング
### 署名検証エラーが出る場合
Marketplace以外のプラグインをインストールする場合、署名検証を無効化する必要があります。
Docker環境の場合、`.env` ファイルに追加:
“`bash
FORCE_VERIFYING_SIGNATURE=false
“`
### オフライン環境でのインストール
オフライン環境では、依存関係を含めた完全なパッケージを作成する必要があります。
“`bash
# dify-plugin-repackaging ツールを使用
git clone https://github.com/langgenius/dify-plugin-repackaging.git
cd dify-plugin-repackaging
# Python 3.12+をセットアップ
./plugin_repackaging.sh local ./your-plugin.difypkg
# 出力されたオフライン対応パッケージをインストール
“`
—
## 🎉 まとめ
**開発・テスト段階**: ローカルファイル または リモートデバッグ
**チーム内配布**: ローカルファイル
**オープンソース公開**: GitHub
**公式配布**: Marketplace
それぞれの用途に応じて、最適なデプロイ方法を選択してください!
手動でアップロードできるようになるのね。なるほど。
[デザイン] UIデザインパターン集
1. ナビゲーション(Navigation)
■ グローバルナビ(Top Navigation)
サイト全体のメインメニュー。
企業サイト・SaaS プロダクトで一般的。
■ サイドバー(Left Navigation)
情報量の多いサービス(管理画面、ダッシュボード)。
アイコン+ラベルが定番。
■ ハンバーガーメニュー(Hamburger Menu)
モバイルでメニューを隠すときの定番。
デスクトップでは避ける傾向が強い。
■ タブ(Tabs)
ページ切り替えやカテゴリ分けに利用。
水平タブ・垂直タブがある。
■ パンくずリスト(Breadcrumb)
ユーザーの現在地を示すために使う。
🔍 2. 検索・フィルタリング(Search & Filtering)
■ 検索バー(Search Bar)
オートコンプリート、検索候補などと組み合わせて UI が強化される。
■ 高度なフィルター(Advanced Filters)
EC、求人、管理画面で多用。
項目をアコーディオンで折りたたむのが一般的。
■ ソート(Sort)
並び替え:価格順、更新順など。
■ ファセットナビゲーション(Faceted Navigation)
ECサイトの定番。
複数の属性で絞り込む(価格・ブランド・サイズなど)。
📄 3. コンテンツ表示(Content Display)
■ カード(Card)
画像+タイトル+説明+ボタンの構成が一般的。
SNS・EC・ギャラリーで多用。
■ リスト(List)
テーブルより軽く、モバイルで定番。
■ テーブル(Data Table)
管理画面で最重要のUI。
ソート・フィルタ・ページネーションと組み合わせる。
■ グリッド(Grid)
写真、商品一覧、カテゴリ一覧など。
📝 4. 入力フォーム(Form Patterns)
■ ラベル+入力欄(Form Row)
横並び・縦並びの2パターン。
■ プレースホルダー入力(Floating Label / Placeholder)
マテリアルデザインに多い(入力時にラベルが浮き上がる)。
■ ステップフォーム(Step Form / Wizard)
入力内容が多いときにステップで分割。
■ バリデーション(Inline Validation)
入力中にリアルタイムでエラー表示。
⚠ 5. アラート・通知(Feedback)
■ トースト(Toast)
右上に一時表示される通知。
成功・エラー・警告など。
■ スナックバー(Snackbar)
画面下部に表示される短めの通知(モバイルによくある)。
■ モーダル(Modal)
重要な操作の確認などに使う。
頻用しすぎると UX が悪化。
■ バナー(Banner / Alert Bar)
ページ全体に関わるお知らせに使用。
💬 6. コミュニケーション(Messaging)
■ チャットUI(Chat Bubbles)
LINE・Messenger のような会話形式。
■ コメント欄(Comments)
SNS・ブログ・ナレッジツールなど。
🗃 7. データ可視化(Analytics / Dashboard)
■ カード型 KPI(Metric Cards)
数字+アイコン+前日比など。
■ チャート(Charts)
棒グラフ、折れ線、ドーナツ、ヒートマップなど。
■ テーブル+アクション(Data Table + Actions)
編集・削除・詳細などの操作がつく。
🎛 8. アクション(Actions)
■ プライマリーボタン(Primary Button)
最も重要なアクション。色で差別化。
■ セカンダリーボタン(Secondary)
補助的なアクション。
■ スピードダイヤル(Speed Dial / Floating Action Button)
モバイルで追加ボタンなどを浮かせて表示。
■ コンテキストメニュー(Context Menu)
右クリックや「…」メニュー。
🎚 9. 状態管理(States)
■ ローディング(Loading / Skeleton)
スケルトンやスピナーで読み込みを見せる。
■ エンプティステート(Empty State)
データがないときの説明+行動ボタン。
■ エラーステート(Error State)
404、500、フォームエラーなど。
🎨 10. ヒーローセクション(Hero Section)
LPやトップページの第一印象を作る。
タイトル・説明・CTA・ビジュアルの組み合わせ。
textToImageとdeeplearning
text-to-image(テキストから画像生成)では、Deep Learning が 文章の理解 → 画像の生成 までのすべての工程に使われています。代表的な仕組みを分かりやすくまとめます。
🌟 text-to-image における Deep Learning の使われ方
1. テキストを理解する(テキストエンコーダ)
入力された文章を数値ベクトルに変換するために Transformer(例:BERT、CLIP の Text Encoder) が使われます。
文章の「意味」や「スタイル」「関係性」を理解し、生成モデルに渡せる形にします。
2. 画像を生成する(拡散モデル or GAN など)
現在主流は 拡散モデル(Diffusion Models) です。
Stable Diffusion
DALL·E
Midjourney(内部構造は非公開だが拡散系と言われる)
📌 拡散モデルの流れ
ランダムノイズからスタート
「ノイズを少しずつ取り除いて画像に近づける」トレーニングを大量データで学習
テキストの意味を反映しながらノイズを除去して最終画像を生成
この「ノイズ除去」のステップを学習するのに Deep Learning(U-Net + Attention)が使われます。
3. テキストと画像を対応づける(クロスアテンション)
画像を作る時に
「文章のどの単語が、画像のどの部分に対応するか」
を学習する仕組みが必要です。
これに使われているのが Cross-Attention(クロスアテンション)
例:「a red cat sitting on a table」
“red”→猫の色
“cat”→動物の形
“table”→背景
といった対応を画像生成中に参照します。
4. 大規模データでの事前学習(Foundation Models)
text-to-image モデルは、
画像+キャプション(説明文) の巨大データセットで事前に学習されます。
これにより、
物体
スタイル
光
質感
写真の構図
などを深層学習が「理解」できるようになります。
🧠 全体構造まとめ
[テキスト] → Transformer(テキスト理解)
→ ベクトル
→ Diffusion Model(画像生成:U-Net + Cross-Attention)
→ [画像]
🔍 一言でまとめると
text-to-image は、
「テキスト理解 × ノイズから画像を作る技術 × アテンション」
を組み合わせた Deep Learning の応用です。
[Claude]契約リスク自動分析&要約ツール
"""
契約リスク自動分析&要約ツール - Webアプリケーション
Gradioを使用したユーザーインターフェース
"""
import gradio as gr
from contract_analyzer import ContractAnalyzer
import os
import json
def analyze_contract_pdf(pdf_file):
"""
契約書PDFを分析する関数
Args:
pdf_file: アップロードされたPDFファイル
Returns:
分析結果のテキスト
"""
if pdf_file is None:
return "PDFファイルをアップロードしてください。"
try:
# 分析器を初期化(初回のみ時間がかかる)
analyzer = ContractAnalyzer()
# PDFファイルのパスを取得
pdf_path = pdf_file.name
# 契約書を分析
result = analyzer.analyze_contract(pdf_path)
# 平易な要約を生成
summary = analyzer.generate_plain_summary(result)
# 詳細情報をJSON形式で追加
detailed_json = json.dumps(result, ensure_ascii=False, indent=2)
# 結果を組み合わせて返す
output = f"{summary}\n\n" + "="*50 + "\n"
output += "\n【詳細情報(JSON形式)】\n"
output += detailed_json
return output
except Exception as e:
return f"エラーが発生しました: {str(e)}\n\n詳細: {type(e).__name__}"
def create_demo():
"""Gradioデモを作成"""
with gr.Blocks(title="契約リスク自動分析ツール") as demo:
gr.Markdown(
"""
# 契約リスク自動分析&要約ツール
## 機能
- **PDF契約書のアップロード**: 契約書PDFを簡単にアップロード
- **AI自動分析**: Hugging Face LLMを使用して自動分析
- **リスク抽出**: リスク条項を自動検出
- **義務抽出**: 義務事項を明確化
- **期限管理**: 重要な期限・納期を抽出
- **平易な要約**: 専門用語を避けた分かりやすい説明
## 使い方
1. 下のボックスに契約書PDF(日本語または英語)をアップロード
2. 「分析開始」ボタンをクリック
3. 数秒~数十秒で分析結果が表示されます
**⚠️ 注意**: 初回実行時は、AIモデルのダウンロードに数分かかる場合があります。
"""
)
with gr.Row():
with gr.Column():
pdf_input = gr.File(
label="契約書PDF",
file_types=[".pdf"],
type="filepath"
)
analyze_btn = gr.Button("分析開始", variant="primary", size="lg")
with gr.Column():
output_text = gr.Textbox(
label="分析結果",
lines=30,
max_lines=50,
show_copy_button=True
)
# ボタンクリック時の処理
analyze_btn.click(
fn=analyze_contract_pdf,
inputs=[pdf_input],
outputs=[output_text]
)
gr.Markdown(
"""
---
### システム情報
- **使用モデル**:
- 要約: facebook/bart-large-cnn
- テキスト生成: google/flan-t5-base
- **処理時間**: 通常5〜30秒(モデル読み込み済みの場合)
- **対応言語**: 日本語、英語
### ヒント
- PDFのテキストが抽出可能である必要があります(画像のみのPDFは非対応)
- より正確な分析のため、契約書は明瞭な文章で記載されている必要があります
- 大きなファイルの場合、処理に時間がかかることがあります
"""
)
return demo
if __name__ == "__main__":
print("契約リスク自動分析ツールを起動中...")
print("ブラウザが自動的に開きます...")
demo = create_demo()
# アプリケーション起動
demo.launch(
share=False, # 公開リンクを生成しない(ローカルのみ)
server_name="0.0.0.0", # すべてのネットワークインターフェースでリッスン
server_port=7860,
show_error=True
)
"""
契約リスク自動分析ツール - コア機能
PDFから契約書を読み込み、Hugging Face LLMを使用してリスク分析を実行
"""
import PyPDF2
from typing import Dict, List
from transformers import pipeline
import re
class ContractAnalyzer:
"""契約書分析クラス"""
def __init__(self, model_name: str = "facebook/bart-large-cnn"):
"""
初期化
Args:
model_name: 使用するHugging Faceモデル名
"""
print(f"モデルを読み込み中: {model_name}")
# 要約用のパイプラインを初期化
self.summarizer = pipeline("summarization", model=model_name)
# テキスト生成用のパイプライン(リスク分析用)
# より軽量なモデルを使用
try:
self.text_generator = pipeline(
"text2text-generation",
model="google/flan-t5-base"
)
except:
# フォールバック: 要約モデルを使用
self.text_generator = self.summarizer
def extract_text_from_pdf(self, pdf_path: str) -> str:
"""
PDFファイルからテキストを抽出
Args:
pdf_path: PDFファイルのパス
Returns:
抽出されたテキスト
"""
try:
with open(pdf_path, 'rb') as file:
pdf_reader = PyPDF2.PdfReader(file)
text = ""
for page in pdf_reader.pages:
text += page.extract_text() + "\n"
return text
except Exception as e:
raise Exception(f"PDF読み込みエラー: {str(e)}")
def extract_risk_clauses(self, text: str) -> List[str]:
"""
リスク条項を抽出
Args:
text: 契約書テキスト
Returns:
リスク条項のリスト
"""
risk_keywords = [
"損害賠償", "違約金", "解除", "終了", "責任", "義務",
"禁止", "制限", "罰則", "ペナルティ", "補償",
"liability", "penalty", "termination", "obligation",
"prohibited", "restricted", "damages", "breach"
]
# 文章を分割
sentences = re.split(r'[。\.\n]', text)
risk_clauses = []
for sentence in sentences:
sentence = sentence.strip()
if not sentence:
continue
# リスクキーワードを含む文章を抽出
if any(keyword in sentence.lower() for keyword in risk_keywords):
risk_clauses.append(sentence)
return risk_clauses
def extract_obligations(self, text: str) -> List[str]:
"""
義務条項を抽出
Args:
text: 契約書テキスト
Returns:
義務条項のリスト
"""
obligation_patterns = [
r"(甲|乙|当事者|受注者|発注者|契約者)(?:は|が).*(?:しなければならない|する義務|する責任)",
r"shall\s+.*",
r"must\s+.*",
r"obligated to\s+.*"
]
sentences = re.split(r'[。\.\n]', text)
obligations = []
for sentence in sentences:
sentence = sentence.strip()
if not sentence:
continue
for pattern in obligation_patterns:
if re.search(pattern, sentence, re.IGNORECASE):
obligations.append(sentence)
break
return obligations
def extract_deadlines(self, text: str) -> List[str]:
"""
期限・日付を抽出
Args:
text: 契約書テキスト
Returns:
期限に関する条項のリスト
"""
deadline_patterns = [
r"\d{4}年\d{1,2}月\d{1,2}日",
r"\d{1,2}日以内",
r"\d+(?:日|週間|ヶ月|年)(?:以内|前|後|まで)",
r"期限|締切|納期|有効期限",
r"\d{4}-\d{2}-\d{2}",
r"within\s+\d+\s+(?:days|weeks|months|years)",
r"deadline|due date|expiration"
]
sentences = re.split(r'[。\.\n]', text)
deadlines = []
for sentence in sentences:
sentence = sentence.strip()
if not sentence:
continue
for pattern in deadline_patterns:
if re.search(pattern, sentence, re.IGNORECASE):
deadlines.append(sentence)
break
return deadlines
def summarize_text(self, text: str, max_length: int = 150) -> str:
"""
テキストを要約
Args:
text: 要約するテキスト
max_length: 要約の最大長
Returns:
要約されたテキスト
"""
if not text or len(text.strip()) == 0:
return "(テキストが空です)"
# テキストが短すぎる場合はそのまま返す
if len(text) < 100:
return text
try:
# 長すぎるテキストは分割
chunk_size = 1024
if len(text) > chunk_size:
text = text[:chunk_size]
summary = self.summarizer(
text,
max_length=max_length,
min_length=30,
do_sample=False
)
return summary[0]['summary_text']
except Exception as e:
# エラー時は先頭部分を返す
return f"要約エラー: {str(e)}\n\n元のテキスト(抜粋):\n{text[:300]}..."
def analyze_contract(self, pdf_path: str) -> Dict:
"""
契約書を総合的に分析
Args:
pdf_path: PDFファイルのパス
Returns:
分析結果の辞書
"""
print("PDF読み込み中...")
text = self.extract_text_from_pdf(pdf_path)
print("リスク条項を抽出中...")
risk_clauses = self.extract_risk_clauses(text)
print("義務条項を抽出中...")
obligations = self.extract_obligations(text)
print("期限情報を抽出中...")
deadlines = self.extract_deadlines(text)
print("要約を生成中...")
# 全体の要約
overall_summary = self.summarize_text(text[:2000], max_length=200)
# リスク条項の要約(上位5件)
risk_summary = []
for clause in risk_clauses[:5]:
try:
summary = self.summarize_text(clause, max_length=100)
risk_summary.append(summary)
except:
risk_summary.append(clause[:150] + "...")
result = {
"全体要約": overall_summary,
"リスク条項": {
"件数": len(risk_clauses),
"主要なリスク": risk_clauses[:10], # 上位10件
"要約": risk_summary
},
"義務条項": {
"件数": len(obligations),
"主要な義務": obligations[:10]
},
"期限・納期": {
"件数": len(deadlines),
"主要な期限": deadlines[:10]
},
"リスクレベル": self._calculate_risk_level(
len(risk_clauses),
len(obligations),
len(deadlines)
)
}
return result
def _calculate_risk_level(
self,
risk_count: int,
obligation_count: int,
deadline_count: int
) -> str:
"""
リスクレベルを計算
Args:
risk_count: リスク条項数
obligation_count: 義務条項数
deadline_count: 期限条項数
Returns:
リスクレベル(高/中/低)
"""
total_score = risk_count * 2 + obligation_count + deadline_count * 1.5
if total_score > 50:
return "高 - 詳細な法的レビューを推奨"
elif total_score > 20:
return "中 - 重要条項の確認を推奨"
else:
return "低 - 標準的な契約書"
def generate_plain_summary(self, analysis_result: Dict) -> str:
"""
平易な言葉で分析結果を要約
Args:
analysis_result: analyze_contractの結果
Returns:
平易な要約文
"""
summary_lines = []
summary_lines.append("=== 契約書分析結果 ===\n")
summary_lines.append(f"【総合リスクレベル】{analysis_result['リスクレベル']}\n")
summary_lines.append(f"\n【全体要約】\n{analysis_result['全体要約']}\n")
summary_lines.append(f"\n【リスク条項】({analysis_result['リスク条項']['件数']}件検出)")
if analysis_result['リスク条項']['主要なリスク']:
summary_lines.append("主な注意点:")
for i, risk in enumerate(analysis_result['リスク条項']['主要なリスク'][:5], 1):
summary_lines.append(f" {i}. {risk}")
summary_lines.append(f"\n【義務事項】({analysis_result['義務条項']['件数']}件検出)")
if analysis_result['義務条項']['主要な義務']:
summary_lines.append("主な義務:")
for i, obligation in enumerate(analysis_result['義務条項']['主要な義務'][:5], 1):
summary_lines.append(f" {i}. {obligation}")
summary_lines.append(f"\n【期限・納期】({analysis_result['期限・納期']['件数']}件検出)")
if analysis_result['期限・納期']['主要な期限']:
summary_lines.append("重要な期限:")
for i, deadline in enumerate(analysis_result['期限・納期']['主要な期限'][:5], 1):
summary_lines.append(f" {i}. {deadline}")
return "\n".join(summary_lines)
if __name__ == "__main__":
# テスト用
analyzer = ContractAnalyzer()
print("契約リスク分析ツールが初期化されました")
# 契約リスク自動分析&要約ツール - 必要パッケージ # PDF処理 PyPDF2>=3.0.0 # Hugging Face Transformers(LLM) transformers>=4.35.0 torch>=2.0.0 sentencepiece>=0.1.99 # Webインターフェース gradio>=4.0.0 # データ処理 numpy>=1.24.0
[LLM] Llama 3.1 × LoRA の流れ
Llama 3.1 × LoRA の流れ
ベースモデル読み込み(4bit量子化)
LoRA 設定(r=16 など)
指示データを用意(chat形式)
学習(300ステップくらい)
LoRA アダプタ保存(数十MB)
Base + LoRA で推論
これで 社内特化 LLM・商品説明特化 LLM・カスタマーサポート LLM
. 準備(必要なライブラリ)
Google Colab なら下記だけで準備OK:
!pip install transformers accelerate peft bitsandbytes datasets
2. ベースモデルを決める(例:Llama 3.1 8B)
軽くて実用的な LLama の OSS モデル:
meta-llama/Meta-Llama-3.1-8B
3. 学習データの形式
LoRA は「教師データ」が **指示形式(instruction format)」だと最も効果が出ます。
例:JSONL(1行1サンプル)
{“instruction”: “社内VPNの再接続方法を教えて”, “response”: “設定→ネットワーク→VPN→再接続ボタンを押すだけです。”}
{“instruction”: “見積書を再発行するには?”, “response”: “営業管理システムで案件番号を検索し、PDFを再生成できます。”}
例:ChatML 形式(最近はこちらが主流)
{
“messages”: [
{“role”: “user”, “content”: “返品の受付方法を教えて”},
{“role”: “assistant”, “content”: “返品受付画面で注文番号を入力し、ステータスを「返品受付」に変更します。”}
]
}
4. LoRA 設定(PEFT)
from peft import LoraConfig
lora_config = LoraConfig(
r=16, # Rank(一般的に 8 / 16)
lora_alpha=32,
lora_dropout=0.05,
bias=”none”,
task_type=”CAUSAL_LM”
)
5. モデル読み込み(4bit 量子化=QLoRA)
4bit QLoRA の標準書き方:
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
model_name = “meta-llama/Meta-Llama-3.1-8B”
model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.bfloat16,
quantization_config={“load_in_4bit”: True},
device_map=”auto”
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
これで GPU 8GB でも Llama3.1-8B を微調整できる状態になります。
6. データセット読み込み
from datasets import load_dataset
dataset = load_dataset(“json”, data_files=”train.jsonl”)
7. 学習データの前処理(プロンプト生成)
def format_chat(example):
messages = example[“messages”]
text = tokenizer.apply_chat_template(
messages,
add_generation_prompt=False
)
return {“text”: text}
dataset = dataset.map(format_chat)
8. Trainer で LoRA 学習開始
from transformers import TrainingArguments, Trainer
from peft import get_peft_model
peft_model = get_peft_model(model, lora_config)
args = TrainingArguments(
output_dir=”llama-lora”,
per_device_train_batch_size=1,
gradient_accumulation_steps=16,
warmup_steps=10,
max_steps=300, # 100~500 で充分効果出る
learning_rate=2e-4,
fp16=True,
logging_steps=10,
save_steps=100,
)
def collate(batch):
return tokenizer(batch[“text”], padding=True, truncation=True, return_tensors=”pt”)
trainer = Trainer(
model=peft_model,
args=args,
train_dataset=dataset,
data_collator=collate
)
trainer.train()
9. 結果の保存(LoRA のみ数十 MB)
peft_model.save_pretrained(“lora-out”)
出力されるのは adapter_config.json / adapter_model.bin
→ 30〜100MB 程度で Llama 3.1 がカスタムモデルになります。
10. 推論(本番利用)
from peft import PeftModel
base = AutoModelForCausalLM.from_pretrained(model_name, device_map=”auto”)
model = PeftModel.from_pretrained(base, “lora-out”)
prompt = “社内VPNに接続できない時の対処方法は?”
inputs = tokenizer(prompt, return_tensors=”pt”).to(“cuda”)
output = model.generate(**inputs, max_new_tokens=200)
print(tokenizer.decode(output[0], skip_special_tokens=True))
googleに漫画を作らせるとこうなる

[TTS] モデルのパラーメタファイルと設定ファイル
1. パラメータファイル (Model Checkpoint)
パラメータファイル(例:my_voice_model.pth)はバイナリデータなので中身をテキストで見ることはできませんが、概念的には以下のようなモデルの学習結果が数値の配列として格納されています。
項目概念的な内容役割
ジェネレーターの重み$W_G: [[0.12, -0.05, …], [0.99, 0.01, …], …]$音響特徴量から生の音声波形を生成するための数百万の数値。
エンコーダーの重み$W_E: [[-0.45, 0.22, …], [0.10, -0.87, …], …]$テキスト情報から音響特徴量を作り出すための数百万の数値。
話者埋め込みベクトル$V_{\text{speaker}}: [0.75, -0.11, 0.40, …]$このモデルが学習した**話者(声質)**を特徴づける固有の数値(声のDNAのようなもの)。
ポイント: このファイルは、提供された音声データとテキストの関係を学習したニューラルネットワークの脳そのものです。
2. 設定ファイル
"train": {
"log_interval": 200,
"eval_interval": 1000,
"seed": 1234,
"epochs": 1000
},
"data": {
"training_files": "filelists/train.txt",
"validation_files": "filelists/val.txt",
"max_wav_value": 32768.0,
"sampling_rate": 24000 // 💡重要:音声の品質(サンプリングレート)
},
"model": {
"inter_channels": 192,
"hidden_channels": 192,
"filter_channels": 768,
"n_heads": 2,
"n_layers": 6,
"kernel_size": 3,
"p_dropout": 0.1,
"gin_channels": 256, // 💡話者埋め込みベクトルの次元
"style_channels": 128 // 💡Style-Bert-VITS2のスタイル特徴量の次元
},
"speakers": {
"speaker01": 0,
"speaker02": 1
} // 💡話者IDとモデル内でのインデックスの対応
}
https://github.com/litagin02/Style-Bert-VITS2
config.jsonと.pthのセット
https://huggingface.co/RinneAi/Rinne_Style-Bert-VITS2
設定ファイル config.json モデルの構造、サンプリングレートなどの設計情報を定義するテキストファイル。
パラメータファイル Rinne.safetensors 学習によって得られた**モデルの重み(パラメータ)**を格納したファイル。従来の.pthに代わり、安全性の高い.safetensors形式が使われることが増えています。
スタイル情報 style_vectors.npy Style-Bert-VITS2特有の、声の**スタイル(話し方、感情など)**の特徴を格納したファイル。
これらのファイル3点セットをダウンロードし、Style-Bert-VITS2の実行環境に配置することで、テキストから指定した声(この場合は「Rinne」)で音声を合成できるようになります。
なるほど〜、
[3D] BlendShape
BlendShape(ブレンドシェイプ)とは、3Dキャラクターの表情や口の動きなどの“変形”を作るための仕組みです。
アニメーション制作やゲーム、VTuberの顔モデルなどで非常によく使われます。
🔷 BlendShape の基本的な考え方
1つの3Dモデルに対して、
笑顔
怒り顔
口を「あ」形に開ける
目を閉じる
など、**形が変化した複数のモデル(ターゲット形状)**を用意します。
そして、アニメーション中に
「元の形」+「ターゲット形状の混合量(0〜1)」
でモデルの形が変わる仕組みです。
例:
“Smile” ブレンドシェイプを 0 → 1 にすると、だんだん笑顔になる
“Mouth Open” を 0.5 にすると、口が半分開く
🔷 なぜBlensShapeが使われるのか?
自然な表情の作りやすさ
骨(ボーン)だけでは難しい細かな変形が可能
リアルタイムで軽い処理(ゲーム・VTuber向き)
複数の表情を混ぜられる(笑いながら目を閉じるなども簡単)
🔷 具体例:口のBlendShape
例えば「口」に関係するBlendShapeには:
A(あ)
I(い)
U(う)
E(え)
O(お)
口角上げ
口すぼめ
ニコッと笑う
などがあり、MMD・VTuber・ゲーム顔アニメで使われています。
🔷 まとめ
BlendShape=“複数の形を混ぜて表情や口の形を変える仕組み”
ボーンのアニメと違い、メッシュ自体が変形するので、細かい顔表現に最適です。
[デザイン] 基本原則
デザインの基本原則は、**誰でもデザインが上手に見えるための「土台」**になるルールです。
センスに依存しないので、エンジニアでも非デザイナーでも、これを理解すれば UI の質が一気に上がります。
ここでは「UIデザインで最も重要な5つ」に絞って、例つき・実践的に説明します。
🎨 デザインの基本原則(UIデザイン版)
1️⃣ コントラスト(Contrast)
「違いを強調してメリハリをつける」こと。
✔ 良い例
重要なボタンだけ濃い色
タイトルは太字、大きめ
背景が薄い → テキストは濃い
✘ 悪い例
背景#FFFFFF に #F5F5F5 の薄いグレー文字
ボタンの色が全部同じでクリック先が分からない
テキストの階層がどれも同じ大きさ
使い方(Figma)
文字の「大・中・小」の階層をつける
Primary ボタンはブランドカラーで統一
余白でもコントラストを作れる(→後述)
2️⃣ 整列(Alignment)
「要素の位置を揃える」こと。
UIの「高級感」と「プロっぽさ」は整列で決まると言っても過がありません。
✔ 良い例
テキスト左揃え
アイコンと文字の中央揃え
要素の開始位置が1列のガイドに沿っている
✘ 悪い例
テキストが微妙にズレている
ボタンの幅がバラバラ
カードの余白が整っていない
使い方(Figma)
Option + Click で整列ツール
Layout Grid を ON(8pt/4pt)
Auto Layout を使えばほぼズレない
3️⃣ 反復(Repetition)
「同じルールを繰り返す」こと。
✔ 良い例
ボタンの丸みは全て 8px
同じ色・フォントを繰り返す
カードUIのパターンを統一
✘ 悪い例
あるページだけボタンの角丸が違う
フォントが3種類以上ある
余白ルールがバラバラ
使い方(Figma)
Color Style / Text Style を使う
Auto Layout で間隔を固定(8/12/16 など)
Components と Variants で統一感を出す
4️⃣ 近接(Proximity)
「意味が近いものは近くに、違うものは離す」。
✔ 良い例
タイトルと説明文を近づける
セクションごとにまとまっている
ボタン → 前後の要素と十分な距離
✘ 悪い例
タイトルと関係ないテキストが近くにある
セクションの境目が分からない
使い方(Figma)
Auto Layout の「Padding / Gap」で距離を一定に
セクションごとに余白を大きくつける
→ 例:同じグループ「16px」、違うセクション「32px」
5️⃣ 余白(Whitespace)
「空間はデザインの一部」。
優れたデザインほど余白が広い。
✔ 良い例
ボタンの内側がしっかり余白
セクションの外側に大きな余白
縦の間隔を揃える(例:8/16/24)
✘ 悪い例
全部の要素がぎゅうぎゅう
見出しと本文が近すぎる
カードが狭くて読みにくい
使い方(Figma)
Auto Layout の「Padding」「Gap」を積極的に使う
余白にも階層を作る(例:8 → 小、16 → 中、32 → 大)
📘 これらを使って「良いUI」はこう作る
Before(悪い例)
フォントサイズが全部同じ
ボタンの色がバラバラ
余白が不揃い
テキストがズレている
After(良い例)
タイトル → 24px / Bold
本文 → 16px
ボタン → Primary Color
余白 → 16/32 で統一
整列 → Auto Layout + Grid
🎯 最重要ポイント(覚えるだけで UI が変わる)
1. 大事なものは大きく&濃く(コントラスト)
2. 全部きっちり揃える(整列)
3. 同じルールを繰り返す(反復)
4. 近い意味のものはくっつける(近接)
5. 迷ったら余白を増やす(Whitespace)