シンプルなチャットプログラムの作成
Node.jsのプロジェクトを初期化
npm init -y
@aws-sdk/client-bedrock-runtime
Bedrock Runtime API のリクエスト作成と送信するために@aws-sdk/client-bedrock-runtimeをインストール
npm install @aws-sdk/client-bedrock-runtime
- Node.js環境でAWS Bedrockサービスと通信するための公式ライブラリ(AWSが提供する公式SDK)
- 【開発環境の構築が容易】Node.jsのインストールだけで開発開始可能
- フロントエンド開発との親和性が高い、共通の言語(JavaScript/TypeScript)使用
1)Node.jsライブラリ(データの前処理や基本的な処理)
- Tesseract.js(OCR)
- Express(APIサーバー)
- Multer(ファイルアップロード)
- Sharp(画像処理)
2)プロンプト:AIに適切な指示を出す
App.jsを作成
// AWS SDKから必要な機能をインポート
// BedrockRuntimeClient: AWSのBedrockサービスに接続するためのクライアント
// InvokeModelCommand: AIモデルを呼び出すためのコマンド
const { BedrockRuntimeClient, InvokeModelCommand } = require('@aws-sdk/client-bedrock-runtime');
// AWS Bedrockクライアントの設定
// region: AWSのサービスを使用するリージョン(地域)
// credentials: AWS認証情報
const client = new BedrockRuntimeClient({
region: "us-east-1", // 米国東部(バージニア)リージョン
credentials: {
accessKeyId: "あなたのアクセスキー", // AWSアクセスキー
secretAccessKey: "あなたのシークレットキー" // AWSシークレットキー
}
});
// AIに質問するための関数
// async/await: 非同期処理を扱うための構文
async function askAI(question) {
try {
// AIモデルへのリクエスト内容を設定
const input = {
// 使用するAIモデルを指定(Amazon Titan)
modelId: "amazon.titan-text-express-v1",
// データの形式をJSON形式に指定
contentType: "application/json",
accept: "application/json",
// AIモデルへの具体的な指示内容
body: JSON.stringify({
// 質問文を設定
inputText: question,
// AIの応答設定
textGenerationConfig: {
maxTokenCount: 1000, // 最大応答長
temperature: 0.7 // 応答の創造性(0-1: 高いほど創造的)
}
})
};
// AIモデルを呼び出すコマンドを作成
const command = new InvokeModelCommand(input);
// コマンドを実行してAIからの応答を取得
const response = await client.send(command);
// AIからの応答(バイナリ)をテキストに変換
const responseBody = JSON.parse(new TextDecoder().decode(response.body));
// 応答を表示
console.log("回答:", responseBody.results[0].outputText);
} catch (error) {
// エラーが発生した場合の処理
console.error("エラーが発生しました:", error);
}
}
// プログラムのテスト実行
// ここの質問を変更することで、違う質問ができます
askAI("こんにちは!簡単な自己紹介をしてください。");
AWSが提供しているclient.send()
というメソッドが 内部でPromiseを使用していて 私たちはそれをawait
で待っている
AWSのアクセスキーとシークレットキーを取得する
IAMユーザーの作成
- 「ポリシーを直接アタッチする」を選択
- 検索ボックスに「Bedrock」と入力
- 「AmazonBedrockFullAccess」にチェック
- 「次へ」をクリック
- 作成したユーザー名をクリック
- 「セキュリティ認証情報」タブを選択
- 「アクセスキーを作成」ボタンをクリック
- 「ユースケース」で「サードパーティーのサービス」を選択
- 警告の確認チェックボックスにチェック
- 「次へ」をクリック
ファイルを実行
先ほど作成したapp.jsに取得したキーに更新してファイルを下記の通り実行すると、、
node app.js
回答:
私はAIです。人工知能の一種で、あなたの質問に答えたり、あなたの指示に従ったりすることができます。
私はあなたとチャットできることをうれしく思います。
テキスト校閲
使っているもの:
- AWS Bedrockのサービス
- Amazon TitanのAIモデル
- AWS SDKのクライアント
async function checkText(text) {
try {
// 1. AIへの指示(プロンプト)を作成
const input = {
modelId: "amazon.titan-text-express-v1", // Amazon TitanのAIモデル
contentType: "application/json",
accept: "application/json",
body: JSON.stringify({
// ここが重要:AIへの指示内容
inputText: `
以下の文章を校閲してください。
- 誤字脱字
- 文法の間違い
- より良い表現の提案
を箇条書きで指摘してください。
文章:${text}`,
textGenerationConfig: {
maxTokenCount: 1000,
temperature: 0.7
}
})
};
// 2. AIに送信して結果を待つ
const command = new InvokeModelCommand(input);
const response = await client.send(command);
// 3. 結果を表示
const responseBody = JSON.parse(new TextDecoder().decode(response.body));
console.log("校閲結果:", responseBody.results[0].outputText);
} catch (error) {
console.error("エラーが発生しました:", error);
}
}
上記のの校閲処理は特別な校閲ロジックは実装していないので、全てAIモデル(プロンプトの指示)に依存しています
より高度なプログラムにするために下記のようにします
- 独自の校閲ルール
- 形態素解析
- 文法チェックライブラリ などを組み合わせる
// 1. 独自の校閲ルールを追加
const customRules = {
"です/ます": "敬語の統一をチェック",
"こと/もの": "表現の統一をチェック",
// ... その他のルール
};
// 2. 形態素解析ライブラリの使用
// npm install kuromoji
const kuromoji = require('kuromoji');
// 3. 独自の校閲ロジックを実装
async function advancedCheck(text) {
// AIによる校閲
const aiResult = await checkText(text);
// 独自ルールによるチェック
const customResult = applyCustomRules(text);
// 形態素解析による確認
const morphResult = await morphologicalAnalysis(text);
return {
ai: aiResult,
custom: customResult,
morph: morphResult
};
}
独自の校閲ルール
// 独自の校閲ルールの実装例
class TextChecker {
constructor() {
// 基本的なルール定義
this.rules = {
// 表記ゆれチェック
styleRules: {
'とっても': 'とても',
'みたい': 'ような',
'すごく': '大変'
},
// 文末表現チェック
endingRules: {
'です・ます': /([てで]います|てます|です)(?![かが])/,
'である': /である(?![かが])/
},
// ビジネス文書チェック
businessRules: {
'不適切': ['思います', 'そうです', 'だと思います'],
'推奨': ['考えられます', '示唆されます', '推察されます']
}
};
}
// テキストをチェックするメソッド
checkText(text) {
const results = [];
// 表記ゆれチェック
for (const [incorrect, correct] of Object.entries(this.rules.styleRules)) {
if (text.includes(incorrect)) {
results.push(`「${incorrect}」は「${correct}」に修正することを推奨します`);
}
}
// その他のルールも同様にチェック
return results;
}
}
形態素解析
// npm install kuromoji
const kuromoji = require('kuromoji');
class MorphologicalAnalyzer {
async initialize() {
return new Promise((resolve, reject) => {
kuromoji.builder({ dicPath: 'node_modules/kuromoji/dict' })
.build((err, tokenizer) => {
if (err) {
reject(err);
} else {
this.tokenizer = tokenizer;
resolve();
}
});
});
}
analyze(text) {
const tokens = this.tokenizer.tokenize(text);
return this.processTokens(tokens);
}
processTokens(tokens) {
const analysis = {
wordTypes: {}, // 品詞の分布
conjugations: [], // 活用の問題
suggestions: [] // 改善提案
};
tokens.forEach(token => {
// 品詞の集計
const pos = token.pos;
analysis.wordTypes[pos] = (analysis.wordTypes[pos] || 0) + 1;
// 活用のチェック
if (token.pos === '動詞' && token.conjugated_form !== '基本形') {
analysis.conjugations.push({
word: token.surface_form,
basic: token.basic_form,
type: token.conjugated_form
});
}
});
return analysis;
}
}
文法チェックライブラリ
// npm install textlint textlint-rule-preset-japanese
const { TextLintEngine } = require('textlint');
class GrammarChecker {
constructor() {
this.engine = new TextLintEngine({
rules: {
// プリセットルールの使用
'preset-japanese': true,
// カスタムルールの追加
'max-ten': {
// 一文での「、」の数を制限
max: 3
},
'sentence-length': {
// 一文の長さを制限
max: 100
}
}
});
}
async check(text) {
try {
const results = await this.engine.executeOnText(text);
return this.formatResults(results);
} catch (error) {
console.error('文法チェックエラー:', error);
return [];
}
}
formatResults(results) {
return results[0].messages.map(message => ({
line: message.line,
column: message.column,
message: message.message,
ruleId: message.ruleId
}));
}
}
組み合わせた場合
class ComprehensiveTextChecker {
constructor() {
this.customChecker = new TextChecker();
this.morphAnalyzer = new MorphologicalAnalyzer();
this.grammarChecker = new GrammarChecker();
}
async initialize() {
await this.morphAnalyzer.initialize();
}
async checkText(text) {
const results = {
customRules: this.customChecker.checkText(text),
morphology: await this.morphAnalyzer.analyze(text),
grammar: await this.grammarChecker.check(text)
};
// AIの結果と組み合わせる
const aiResults = await checkText(text); // 先ほどのAI機能
results.ai = aiResults;
return this.summarizeResults(results);
}
summarizeResults(results) {
// 結果を整理して返す
return {
suggestions: [
...results.customRules,
...results.grammar.map(g => g.message)
],
analysis: {
wordTypes: results.morphology.wordTypes,
grammarIssues: results.grammar.length,
aiSuggestions: results.ai
}
};
}
}
使用例
async function main() {
const checker = new ComprehensiveTextChecker();
await checker.initialize();
const text = "私はとっても疲れたので、今日は早く帰りたいと思います。";
const results = await checker.checkText(text);
console.log(results);
}
補足)フォルダ構成
text-checker-project/
│
├── src/ # ソースコードのメインディレクトリ
│ ├── checkers/ # 各チェッカーの実装
│ │ ├── CustomChecker.js # 独自ルールチェッカー
│ │ ├── MorphAnalyzer.js # 形態素解析
│ │ ├── GrammarChecker.js # 文法チェッカー
│ │ └── AIChecker.js # AI利用のチェッカー
│ │
│ ├── rules/ # ルール定義
│ │ ├── styleRules.js # 表記ゆれルール
│ │ ├── grammarRules.js # 文法ルール
│ │ └── businessRules.js # ビジネス文書ルール
│ │
│ ├── utils/ # ユーティリティ関数
│ │ ├── formatter.js # 結果フォーマット
│ │ └── logger.js # ログ処理
│ │
│ └── index.js # メインのエントリーポイント
│
├── config/ # 設定ファイル
│ ├── default.json # デフォルト設定
│ └── textlint-rules.json # textlintルール設定
│
├── tests/ # テストファイル
│ ├── customChecker.test.js
│ ├── morphAnalyzer.test.js
│ └── grammarChecker.test.js
│
├── examples/ # 使用例
│ └── basic-usage.js
│
├── docs/ # ドキュメント
│ ├── API.md
│ └── RULES.md
│
├── node_modules/ # 依存パッケージ
├── package.json
├── package-lock.json
└── README.md
src/index.js
const ComprehensiveTextChecker = require('./checkers/ComprehensiveChecker');
const config = require('../config/default.json');
module.exports = ComprehensiveTextChecker;
src/checkers/CustomChecker.js
const styleRules = require('../rules/styleRules');
const businessRules = require('../rules/businessRules');
class CustomChecker {
constructor(config = {}) {
this.rules = {
style: styleRules,
business: businessRules,
...config.rules
};
}
checkText(text) {
// 実装
}
}
module.exports = CustomChecker;
src/rules/styleRules.js
module.exports = {
// 表記ゆれルール
corrections: {
'とっても': 'とても',
'みたい': 'ような'
},
// その他のルール
};
package.json
{
"name": "text-checker",
"version": "1.0.0",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js",
"test": "jest",
"lint": "eslint src/"
},
"dependencies": {
"kuromoji": "^1.0.0",
"textlint": "^12.0.0",
"textlint-rule-preset-japanese": "^7.0.0",
"@aws-sdk/client-bedrock-runtime": "^3.0.0"
},
"devDependencies": {
"jest": "^27.0.0",
"eslint": "^8.0.0"
}
}
examples/basic-usage.js
const TextChecker = require('../src/index');
async function example() {
const checker = new TextChecker();
await checker.initialize();
const text = "私はとっても疲れたので、今日は早く帰りたいと思います。";
const results = await checker.checkText(text);
console.log(results);
}
example().catch(console.error);