fix(ai): ハルシネーション防止を一般化・N文字ルール追加・6銘柄例示
- systemInstruction をOCR専門システムとして再定義(東魁限定から一般化) - 「ラベルにN文字なら必ずN文字のみ出力」ルールを明示化 - 東魁/男山/白鹿/久保田/白鶴/松竹梅の6銘柄例を追加 - 出力前セルフチェック手順をプロンプトに追加 - menu_pricing_screen: SharedPreferences を async/await+try-catch に修正 - version: 1.0.43+50 → 1.0.44+51 - web: eiji/maita 向け consumer APK (v1.0.44) を配置・ダウンロードページ更新 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d72587ac19
commit
0fb4f6ea8b
|
|
@ -27,27 +27,26 @@ class _MenuPricingScreenState extends ConsumerState<MenuPricingScreen> {
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// One-time hint for Exit button
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final prefs = SharedPreferences.getInstance();
|
||||
final shown = prefs.then((p) => p.getBool('business_mode_help_shown') ?? false);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => _showExitHintIfNeeded());
|
||||
}
|
||||
|
||||
shown.then((hasShown) {
|
||||
if (!hasShown && mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: const Text('右上の×でいつでも終了できます'),
|
||||
duration: const Duration(seconds: 3),
|
||||
action: SnackBarAction(
|
||||
label: 'OK',
|
||||
onPressed: () {},
|
||||
),
|
||||
),
|
||||
);
|
||||
prefs.then((p) => p.setBool('business_mode_help_shown', true));
|
||||
}
|
||||
});
|
||||
});
|
||||
Future<void> _showExitHintIfNeeded() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final hasShown = prefs.getBool('business_mode_help_shown') ?? false;
|
||||
if (!hasShown && mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: const Text('右上の×でいつでも終了できます'),
|
||||
duration: const Duration(seconds: 3),
|
||||
action: SnackBarAction(label: 'OK', onPressed: () {}),
|
||||
),
|
||||
);
|
||||
await prefs.setBool('business_mode_help_shown', true);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Failed to load/save business_mode_help_shown: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -26,17 +26,32 @@ class GeminiService {
|
|||
あなたは日本酒ラベル解析の専門家です。
|
||||
添付画像から情報を読み取り、以下のJSONを返してください。
|
||||
|
||||
## 【絶対ルール】name・brand・prefectureの読み取り
|
||||
これら3フィールドのみ、ラベルに印刷された文字を一字一句そのまま出力してください。
|
||||
- あなたの知識でラベルの文字を補完・訂正・変更することは禁止
|
||||
- ラベルに「東魁」→ "name": "東魁"(「東魁盛」に変えない)
|
||||
- ラベルに「白鹿」→ "name": "白鹿"(「白鹿本醸造」に変えない)
|
||||
- ラベルに「久保田」→ "name": "久保田"(「久保田 千寿」に変えない)
|
||||
- prefecture: ラベルに都道府県名が書かれていればそのまま出力、書かれていなければ null
|
||||
(銘柄名から産地を推測して埋めることは禁止)
|
||||
## 【絶対ルール】name・brand・prefectureの読み取り(OCR厳守)
|
||||
これら3フィールドは、ラベルに印刷されている文字だけを一字一句そのまま出力してください。
|
||||
あなたが知っている銘柄知識でラベルの文字を補完・変換・拡張することは厳禁です。
|
||||
|
||||
## その他のフィールド(推定・推定可)
|
||||
以下はラベルから読み取れる情報+日本酒の一般知識を使って推定してください。
|
||||
【具体的な禁止例】
|
||||
- ラベルに「東魁」(2文字) → "東魁" のまま出力(「東魁盛」への変換禁止)
|
||||
- ラベルに「白鹿」(2文字) → "白鹿" のまま出力(「白鹿本醸造」への変換禁止)
|
||||
- ラベルに「久保田」(3文字) → "久保田" のまま出力(「久保田 千寿」への変換禁止)
|
||||
- ラベルに「男山」(2文字) → "男山" のまま出力(「男山本醸造」への変換禁止)
|
||||
- ラベルに「白鶴」(2文字) → "白鶴" のまま出力(「白鶴まる」への変換禁止)
|
||||
- ラベルに「松竹梅」(3文字) → "松竹梅" のまま出力(「松竹梅 白壁蔵」への変換禁止)
|
||||
|
||||
【一般原則】ラベルに N 文字しか見えない場合は N 文字のみ出力する。
|
||||
文字数を増やすことは、たとえあなたが正式名称を知っていても禁止。
|
||||
|
||||
- prefecture: ラベルに都道府県名が書かれていればそのまま出力、なければ null
|
||||
(銘柄名・蔵元名から産地を推測して埋めることは禁止)
|
||||
|
||||
## 【出力前セルフチェック】
|
||||
name・brand を出力する直前に以下を確認してください:
|
||||
- ラベル画像で実際に見えている文字数と、出力しようとしている文字数が一致するか?
|
||||
- あなたの知識による「補完」が入っていないか?
|
||||
不一致の場合は、ラベルに見えている文字数に合わせて修正してください。
|
||||
|
||||
## その他のフィールド(推定可)
|
||||
以下はラベル情報+日本酒の一般知識を使って推定してください。
|
||||
- type: ラベルに書かれた特定名称(純米大吟醸など)。なければ null
|
||||
- description: ラベル情報と type から推定した味・特徴の説明(100文字程度)
|
||||
- catchCopy: 20文字以内のキャッチコピー
|
||||
|
|
@ -229,10 +244,12 @@ class GeminiService {
|
|||
あなたは日本酒ラベル解析の専門家です。
|
||||
添付画像から情報を読み取り、以下のJSONを返してください。
|
||||
|
||||
## 【絶対ルール】name・brand・prefectureの読み取り
|
||||
これら3フィールドのみ、ラベルに印刷された文字を一字一句そのまま出力してください。
|
||||
- あなたの知識でラベルの文字を補完・訂正・変更することは禁止
|
||||
- ラベルに「東魁」→ "name": "東魁"(「東魁盛」に変えない)
|
||||
## 【絶対ルール】name・brand・prefectureの読み取り(OCR厳守)
|
||||
これら3フィールドは、ラベルに印刷されている文字だけを一字一句そのまま出力してください。
|
||||
あなたが知っている銘柄知識でラベルの文字を補完・変換・拡張することは厳禁です。
|
||||
|
||||
【禁止例】「東魁」→「東魁盛」禁止 / 「男山」→「男山本醸造」禁止 / 「白鹿」→「白鹿本醸造」禁止
|
||||
【一般原則】ラベルに N 文字しか見えない場合は N 文字のみ出力する(文字数を増やすことは禁止)
|
||||
- prefecture: ラベルに都道府県名が書かれていればそのまま出力、なければ null(推測禁止)
|
||||
|
||||
## その他のフィールド(推定可)
|
||||
|
|
@ -287,10 +304,15 @@ class GeminiService {
|
|||
model: modelName,
|
||||
apiKey: apiKey,
|
||||
systemInstruction: Content.system(
|
||||
'あなたは画像内のテキストを一字一句正確に読み取る専門家です。'
|
||||
'ラベルに記載された銘柄名・蔵元名は絶対に変更・補完しないでください。'
|
||||
'あなたの知識でラベルの文字を上書きすることは厳禁です。'
|
||||
'ラベルに「東魁」とあれば、「東魁盛」を知っていても必ず「東魁」と出力してください。',
|
||||
'あなたは画像内のテキストを一字一句正確に書き起こすOCR(光学文字認識)専門システムです。\n'
|
||||
'【絶対的制約 — name・brand・prefecture フィールドに適用】\n'
|
||||
'1. ラベルに印刷されている文字だけを出力する。ラベルにない文字を1文字も追加してはならない。\n'
|
||||
'2. ラベルに N 文字の銘柄名があれば N 文字のまま出力する。文字数を増やすことは禁止。\n'
|
||||
'3. あなたが知っている「正式名称」「有名銘柄名」への変換・補完は禁止。\n'
|
||||
' 例: 「東魁」→「東魁」(「東魁盛」禁止)、「男山」→「男山」(「男山本醸造」禁止)、\n'
|
||||
' 「白鹿」→「白鹿」(「白鹿本醸造」禁止)、「久保田」→「久保田」(「久保田 千寿」禁止)\n'
|
||||
'4. ラベルに都道府県名がなければ prefecture は null。銘柄名から産地を推測して埋めることは禁止。\n'
|
||||
'5. 日本酒知識は description・flavorTags・tasteStats 等の推定フィールドにのみ使用すること。',
|
||||
),
|
||||
generationConfig: GenerationConfig(
|
||||
responseMimeType: 'application/json',
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.0.43+50
|
||||
version: 1.0.44+51
|
||||
|
||||
environment:
|
||||
sdk: ^3.10.1
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
<!-- Download Section -->
|
||||
<section class="download">
|
||||
<div class="version-cards">
|
||||
<!-- Lite Version -->
|
||||
<!-- Lite Version (Eiji) -->
|
||||
<a href="/releases/ponshu-room-lite.apk" class="version-card" download>
|
||||
<div class="card-header">
|
||||
<span class="version-name">Lite</span>
|
||||
|
|
@ -62,21 +62,21 @@
|
|||
<path d="M12 3v12m0 0l-4-4m4 4l4-4M5 17v2a2 2 0 002 2h10a2 2 0 002-2v-2" />
|
||||
</svg>
|
||||
</div>
|
||||
<span class="file-size">88 MB</span>
|
||||
<span class="file-size">90 MB</span>
|
||||
</a>
|
||||
|
||||
<!-- Pro Version -->
|
||||
<a href="/releases/ponshu-room-pro.apk" class="version-card pro" download>
|
||||
<!-- Maita Version -->
|
||||
<a href="/releases/ponshu-room-maita.apk" class="version-card" download>
|
||||
<div class="card-header">
|
||||
<span class="version-name">Pro</span>
|
||||
<span class="version-badge pro-badge">Pro</span>
|
||||
<span class="version-name">Maita</span>
|
||||
<span class="version-badge free">Dev</span>
|
||||
</div>
|
||||
<div class="card-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M12 3v12m0 0l-4-4m4 4l4-4M5 17v2a2 2 0 002 2h10a2 2 0 002-2v-2" />
|
||||
</svg>
|
||||
</div>
|
||||
<span class="file-size">89 MB</span>
|
||||
<span class="file-size">90 MB</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
@ -116,7 +116,7 @@
|
|||
|
||||
<!-- Footer -->
|
||||
<footer>
|
||||
<p>v1.0.12</p>
|
||||
<p>v1.0.44</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue