v1.0
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
from typing import List
|
||||
|
||||
from agent.models import ProgramMeta
|
||||
|
||||
|
||||
class PromptBuilder:
|
||||
"""将解析后的程序元数据和规则组装成 API prompt。"""
|
||||
|
||||
def build(self, meta: ProgramMeta, rules_text: str,
|
||||
group_descriptions: List[str], group_count: int) -> str:
|
||||
"""构建完整的 API prompt。"""
|
||||
parts = []
|
||||
|
||||
parts.append(self._build_basic_info(meta))
|
||||
parts.append(self._build_process_detail(meta))
|
||||
parts.append(self._build_input_structures(meta))
|
||||
parts.append(self._build_output_records(meta))
|
||||
parts.append(rules_text)
|
||||
parts.append(self._build_output_format(meta))
|
||||
parts.append(self._build_generation_instruction(
|
||||
group_descriptions, group_count, meta.input_type
|
||||
))
|
||||
|
||||
return '\n\n'.join(parts)
|
||||
|
||||
def _build_basic_info(self, meta: ProgramMeta) -> str:
|
||||
lines = [
|
||||
f"## プログラム基本情報",
|
||||
f"- システム名: {meta.system_name}",
|
||||
f"- プログラムID: {meta.program_id}",
|
||||
f"- プログラム名: {meta.program_name}",
|
||||
f"- PGMパターン: {meta.pgm_pattern}",
|
||||
f"- 入力タイプ: {self._input_type_label(meta.input_type)}",
|
||||
]
|
||||
if meta.summary_lines:
|
||||
lines.append(f"- 機能概要: {' '.join(meta.summary_lines)}")
|
||||
return '\n'.join(lines)
|
||||
|
||||
def _build_process_detail(self, meta: ProgramMeta) -> str:
|
||||
return f"## 処理詳細\n\n```\n{meta.process_detail}\n```"
|
||||
|
||||
def _build_input_structures(self, meta: ProgramMeta) -> str:
|
||||
parts = ["## 入力構造"]
|
||||
|
||||
input_files = [f for f in meta.files if 'I' in f.io]
|
||||
for f in input_files:
|
||||
parts.append(f"### ファイル {f.identifier} (DD名: {f.dd_name}, COPY: {f.copy_group}, 媒体: {f.medium})")
|
||||
fields = meta.copy_fields.get(f.identifier, [])
|
||||
if fields:
|
||||
parts.append("| 項目名 | PIC | バイト数 |")
|
||||
parts.append("|--------|-----|----------|")
|
||||
for cf in fields:
|
||||
parts.append(f"| {cf.name} | {cf.pic_type} | {cf.pic_bytes} |")
|
||||
else:
|
||||
parts.append("(構造情報なし)")
|
||||
|
||||
db_inputs = [f for f in meta.files if 'I' in f.io and f.medium == 'DB']
|
||||
if db_inputs or meta.db_tables:
|
||||
parts.append("### DBテーブル構造")
|
||||
for table_name, table in meta.db_tables.items():
|
||||
parts.append(f"**表名: {table_name}**")
|
||||
pk_str = ', '.join(table.pk_columns)
|
||||
parts.append(f"主キー: {pk_str}")
|
||||
parts.append("| 項目名 | 英字名 | タイプ | 最大長 | KEY |")
|
||||
parts.append("|--------|--------|--------|--------|-----|")
|
||||
for col in table.columns:
|
||||
key_mark = '✓' if col.is_pk else ''
|
||||
parts.append(f"| {col.name_jp} | {col.name_en} | {col.type} | {col.max_len} | {key_mark} |")
|
||||
|
||||
return '\n\n'.join(parts)
|
||||
|
||||
def _build_output_records(self, meta: ProgramMeta) -> str:
|
||||
return f"## 出力レコード定義\n\n```\n{meta.output_records}\n```"
|
||||
|
||||
def _build_output_format(self, meta: ProgramMeta) -> str:
|
||||
lines = [
|
||||
"## 出力形式",
|
||||
"",
|
||||
"### JSON形式(ファイル入力の場合)",
|
||||
"",
|
||||
"JSON構造:",
|
||||
"```json",
|
||||
"{",
|
||||
' "program": "{プログラムID}",',
|
||||
' "records": [',
|
||||
' { "input": { "FD名": { "項目名": "値", ... } } },',
|
||||
' ...',
|
||||
' ]',
|
||||
"}",
|
||||
"```",
|
||||
"",
|
||||
"### 項目値のルール(PIC → JSON値)",
|
||||
"| PIC | JSON内表示 | 例 |",
|
||||
"|-----|-----------|-----|",
|
||||
"| PIC X(n) | 左詰め + スペース埋め | `\"A0000001\"` |",
|
||||
"| PIC 9(n) | 右詰め + 先行ゼロ | `\"00000101\"` |",
|
||||
"| PIC S9(n) | 符号 + 右詰め + 先行ゼロ | `\"+0000101\"` |",
|
||||
"| PIC S9(n)V9(m) | 符号 + 右詰め + 小数点含む | `\"+001234567\"` |",
|
||||
"| PIC S9(n) COMP | 通常の10進数文字列 | `\"300\"` |",
|
||||
"| PIC S9(n) COMP-3 | 通常の10進数文字列 | `\"1234\"` |",
|
||||
"| PIC 9(n) COMP-3 | 通常の10進数文字列 | `\"1234\"` |",
|
||||
"| FILLER(純粋予約) | グループIDとレコード番号を含むパターン | `\"D000000...001\"` |",
|
||||
"| FILLER(業務予約) | 全スペース(PIC X) または 全ゼロ(PIC 9) | |",
|
||||
"",
|
||||
"### SQL形式(DB入力の場合)",
|
||||
"各グループ1つのSQLファイル: `{program}_g{groupId}.sql`",
|
||||
"",
|
||||
"SQL例:",
|
||||
"```sql",
|
||||
"-- Group: 1",
|
||||
"INSERT INTO TABLE_NAME (COL1, COL2) VALUES",
|
||||
"('val1', 'val2');",
|
||||
"```",
|
||||
"",
|
||||
"### データ生成の注意",
|
||||
"- 項目名に意味がある場合(DATE→日付、NAME→氏名)、実際の形式に合った値を生成すること",
|
||||
"- 隣接するレコード間で、同じ項目に異なる値を設定すること",
|
||||
]
|
||||
return '\n'.join(lines)
|
||||
|
||||
def _build_generation_instruction(self, descriptions: List[str],
|
||||
count: int, input_type: str) -> str:
|
||||
lines = [
|
||||
"## 生成指示",
|
||||
f"生成するグループ数: {count}",
|
||||
"各グループの内容:",
|
||||
]
|
||||
for i, desc in enumerate(descriptions, 1):
|
||||
lines.append(f" - g{i}: {desc}")
|
||||
|
||||
if input_type == 'file':
|
||||
lines.append("出力: JSONファイル(1グループ=1JSONファイル)")
|
||||
elif input_type == 'db':
|
||||
lines.append("出力: SQL INSERTファイル(1グループ=1SQLファイル)")
|
||||
else:
|
||||
lines.append("出力: JSONファイル + SQL INSERTファイル")
|
||||
|
||||
lines.append("")
|
||||
lines.append("応答形式: JSONで返してください。最上位キー \"groups\" を使い、各グループを \"g1\", \"g2\" ... とします。")
|
||||
lines.append("例: {\"groups\": {\"g1\": {\"program\": \"XXX\", \"records\": [...]}, \"g2\": {...}}}")
|
||||
return '\n'.join(lines)
|
||||
|
||||
@staticmethod
|
||||
def _input_type_label(t: str) -> str:
|
||||
labels = {'file': 'ファイル', 'db': 'DB', 'mixed': '混合(ファイル+DB)'}
|
||||
return labels.get(t, t)
|
||||
Reference in New Issue
Block a user