はじめに
突然ですが、外国の社員とのメールやチャットのやり取りのある方なら、一度はこのように思ったことがあるのではないでしょうか?
- 翻訳ツールを使っても、断片的で前の会話に沿った表現になっているかどうか再翻訳で確認するという二重の手間がかかる
- チャットやメールなど、各形式で異なる形式やニュアンスの文章を作成できているか不安
- チャット型AIツールでLLMを用いて翻訳に指示を追加して上の2つが改善できても、セッションが途切れると「新しいチャット」として立ち上がるので過去のやり取りを探すのが大変
私事ですが、ここ最近グローバルの社員とやると利する機会が増え、私自身もこのような悩みを抱えていました。
そこで、Agent駆動開発アシスタントIBM Bobを使って、これらの課題を解決するビジネス翻訳アプリ「BizTranslate」を開発しました。
本記事では、作成したアプリケーションの概要やソースコードの共有、Bobを活用した開発体験記を紹介します。
⚠️ 留意事項
このまとめは作成者個人の活動になり、必ずしも私の所属団体・企業における立場、戦略、意見を代表するものではありません。
IBM Bobとは
IBMが提供するAIエージェント駆動開発ツールです。
- 安全性が確保されたエンタープライズ志向
- オンプレミス、クラウドなどハイブリッドな拡張性
- 全方向のモダナイゼーション
が特徴のAIファーストな開発支援ツールシステムとして、開発者の皆さんのコーディング作業を支援するために設計されています。
詳細はこちらの公式サイトでチェック!
BizTranslateとは
BizTranslateは、外国の社員とのチャットやメールのコミュニケーションを円滑にするための翻訳アプリケーションです。
主な機能
- ✅ ビジネスニュアンスでの翻訳: DeepL APIを使用
- ✅ 会話管理: やり取りをスレッド化して時系列で保存(名前をつけることも可)
- ✅ AI返信提案: メッセージ内容を分析して適切な返信を提案
- ✅ 形式変換: チャット/メール形式に適した翻訳出力
- ✅ 履歴検索: 過去のやり取りを検索・参照
- ✅ トーン調整: フォーマル/カジュアルなど、相手や場面に応じて文体を切り替え可能
システムアーキテクチャ
少し分かりにくいですが。。。
Bobを使った開発体験記
Bobが特に役立った場面
1. プロジェクト構造の設計
最初に「外国の社員とのメール・チャットのやり取りを円滑にする翻訳アプリを作りたい」と伝えただけで、Bobが以下を提案してくれました:
- モノレポ構成(client/server分離)
- 適切なディレクトリ構造
- 必要な依存パッケージ
などなど
2. 複雑なロジックの実装
特に「AI返信提案機能」の実装では、Bobが以下のような洗練されたコードを生成してくれました:
// メッセージタイプを自動分析
private analyzeMessageType(message: string): string {
const lowerMessage = message.toLowerCase();
// 質問
if (
lowerMessage.includes('?') ||
lowerMessage.match(/^(what|when|where|who|why|how|can|could|would)/i)
) {
return 'question';
}
// 依頼・リクエスト
if (
lowerMessage.match(/^(please|could you|would you|can you)/i) ||
lowerMessage.includes('request')
) {
return 'request';
}
// 感謝
if (lowerMessage.match(/(thank|thanks|appreciate|grateful)/i)) {
return 'thanks';
}
return 'general';
}
このように、メッセージの内容を分析して適切な返信パターンを選択する仕組みを、自然言語での指示だけで実装できました。(そのため実装時間はほぼ0)
3. TypeScriptの型安全性
Bobは型定義も自動的に生成してくれるため、開発中の型エラーを大幅に削減できました:
export interface Message {
_id: string;
threadId: string;
text: string;
translatedText: string;
direction: 'incoming' | 'outgoing';
platform: Platform;
tone?: Tone;
sourceLang: Language;
targetLang: Language;
formattedText?: string;
suggestions?: string[];
createdAt: Date;
}
export type Platform = 'chat' | 'email';
export type Tone = 'formal' | 'casual';
export type Language = 'en' | 'ja' | 'zh' | 'ko' | 'es' | 'fr' | 'de' | 'pt';
実装のポイント
今回のこのアプリケーションの実装は、自然言語での指示でBobにほぼ任せたので、「今回の実装のポイントは?」と聞いてみると、以下とのこと。
1. DeepL API連携
DeepL APIを使った翻訳サービスの実装例:
class DeepLService {
private translator: deepl.Translator | null = null;
async translate(
text: string,
targetLang: string,
sourceLang?: string
): Promise<{ translatedText: string; detectedSourceLang: string }> {
const result = await this.getTranslator().translateText(
text,
sourceLang as deepl.SourceLanguageCode | null ?? null,
targetLang as deepl.TargetLanguageCode,
{
splitSentences: '0' as any, // 文の分割を無効化
preserveFormatting: true, // フォーマットを保持
}
);
return {
translatedText: result.text,
detectedSourceLang: result.detectedSourceLang || sourceLang || 'unknown',
};
}
}
ポイント:
-
splitSentences: '0'で文の分割を無効化し、元の文章構造を保持 -
preserveFormatting: trueで改行やインデントを維持 - シングルトンパターンでTranslatorインスタンスを再利用
2. AI返信提案の仕組み
受信メッセージを分析して、適切な返信候補を自動生成します:
async generateSuggestions(
incomingMessage: string,
platform: 'chat' | 'email',
tone: 'formal' | 'casual' = 'formal'
): Promise<string[]> {
const suggestions: string[] = [];
// メッセージタイプを分析
const messageType = this.analyzeMessageType(incomingMessage);
// タイプに応じた日本語の返信候補を生成
switch (messageType) {
case 'question':
suggestions.push(...this.getQuestionResponses(tone));
break;
case 'request':
suggestions.push(...this.getRequestResponses(tone));
break;
// ... 他のケース
}
// 日本語の提案を英語に翻訳
const translatedSuggestions = await Promise.all(
suggestions.map(async (suggestion) => {
const result = await deeplService.translate(suggestion, 'en-US', 'ja');
return result.translatedText;
})
);
return translatedSuggestions;
}
ポイント:
- 正規表現でメッセージタイプを自動判定
- トーン(フォーマル/カジュアル)に応じた返信候補を用意
- DeepL APIで自然な英語に翻訳
3. Zustandによる状態管理
Reduxよりもシンプルで、TypeScriptとの相性も良いZustandを採用:
interface AppState {
// スレッド関連
threads: Thread[];
currentThread: Thread | null;
setCurrentThread: (thread: Thread | null) => void;
// UI状態
selectedPlatform: Platform;
selectedTone: Tone;
sourceLang: Language;
targetLang: Language;
swapLanguages: () => void;
}
export const useStore = create<AppState>((set) => ({
threads: [],
currentThread: null,
setCurrentThread: (thread) => set({ currentThread: thread }),
selectedPlatform: 'chat',
selectedTone: 'formal',
sourceLang: 'en',
targetLang: 'ja',
swapLanguages: () =>
set((state) => ({
sourceLang: state.targetLang,
targetLang: state.sourceLang,
})),
}));
ポイント:
- ボイラープレートが少なく、直感的に使える
- TypeScriptの型推論が効く
- React Queryと組み合わせてサーバー状態とクライアント状態を分離
4. プラットフォーム別フォーマット変換
Slack/メール形式に適した出力を生成:
class FormatterService {
formatForPlatform(
text: string,
platform: 'chat' | 'email',
tone: 'formal' | 'casual'
): string {
if (platform === 'email') {
return this.formatForEmail(text, tone);
}
return this.formatForChat(text, tone);
}
private formatForEmail(text: string, tone: 'formal' | 'casual'): string {
const greeting = tone === 'formal'
? 'Dear [Name],'
: 'Hi [Name],';
const closing = tone === 'formal'
? 'Best regards,\n[Your Name]'
: 'Thanks,\n[Your Name]';
return `${greeting}\n\n${text}\n\n${closing}`;
}
private formatForChat(text: string, _tone: 'formal' | 'casual'): string {
// チャット形式はシンプルに
return text;
}
}
ソースコードについて
本アプリケーションのソースコードは、GitHubにて公開しています:
GitHubリポジトリはこちら
リポジトリには以下が含まれています:
- 完全なソースコード: フロントエンド・バックエンドの全実装
- 詳細なREADME: セットアップ手順、使い方、トラブルシューティング
-
環境設定例:
.env.exampleファイル - コメント付きコード: 各機能の実装詳細
実装の詳細を知りたい方は、以下のファイルをご覧ください:
| ファイル | 説明 |
|---|---|
server/src/services/deepl.service.ts |
DeepL API連携の実装 |
server/src/services/suggestion.service.ts |
AI返信提案のロジック |
server/src/services/formatter.service.ts |
プラットフォーム別フォーマット変換 |
client/src/store/useStore.ts |
Zustandによる状態管理 |
client/src/components/Chat/MessageInput.tsx |
メッセージ入力UIの実装 |
server/src/controllers/thread.controller.ts |
スレッド管理のビジネスロジック |
クイックスタート
詳細なセットアップ手順は、リポジトリのREADMEをご参照ください。
必要な環境:
- Node.js 18以上
- MongoDB 6.0以上
- DeepL API キー(無料プラン可)
基本的な起動コマンド:
npm install
npm run dev
実際に動かしてみて、コードを読みながら理解を深めることをおすすめします!
💭 Bobを使ってみた感想
良かった点
- 開発速度の向上: Bobが適切なコードを提案してくれるため、実装が非常にスムーズ
- コード品質: TypeScriptの型定義やエラーハンドリングも適切に実装される
- 学習効果: Bobが生成したコードから、ベストプラクティスを学べる
改善の余地
- UI/UXデザイン: デザインの細かい調整は人間の判断が必要
- ビジネスロジック: ドメイン固有の要件は詳細な指示が必要
- パフォーマンス最適化: 大規模データの処理は追加のチューニングが必要
まとめ
複雑なロジック(AI返信提案、メッセージ分析など)の実装であっても、『こんなことできるようにしたいんだけど』というように曖昧なプロンプトであっても、要件の確認等を丁寧かつ素早く進め、わずか数分で追加実装でき、「私たちがAIに求めている便利さ」を体感できたように思います。
また今回作成したBiztranslateで言うと、ビジネスコミュニケーションの効率化という実用的な課題を、最新のAI技術を活用して解決できたことは、大きな成果だと感じています。
皆さんもBobを使って、日々の業務から出たアイデアを素早く形にしてみませんか?
リンク集
プロジェクト
-
GitHubリポジトリ
- 完全なソースコード
- 詳細なREADME
- セットアップガイド
使用技術
- DeepL API - 高品質な翻訳API
- React - UIフレームワーク
- Zustand - 状態管理ライブラリ
- TailwindCSS - CSSフレームワーク
- MongoDB - NoSQLデータベース
- Express - Node.jsフレームワーク
さいごに
この記事が参考になりましたら、ハートやストックをいただけると嬉しいです!
質問やフィードバックもお気軽にコメントください。