|
| 1 | +from . import ja_user_profile_topics |
| 2 | +from ..models.response import AIUserProfiles |
| 3 | +from ..env import CONFIG, LOG |
| 4 | +from .utils import pack_profiles_into_string |
| 5 | + |
| 6 | +ADD_KWARGS = { |
| 7 | + "prompt_id": "ja_extract_profile", |
| 8 | +} |
| 9 | + |
| 10 | +EXAMPLES = [ |
| 11 | + ( |
| 12 | + """- ユーザーがアシスタントに挨拶した。 |
| 13 | +""", |
| 14 | + AIUserProfiles(**{"facts": []}), |
| 15 | + ), |
| 16 | + ( |
| 17 | + """ |
| 18 | +- ユーザーの好きな映画は『インセプション』と『インターステラー』 [2025/01/01に言及] |
| 19 | +- ユーザーの一番好きな映画は『TENET テネット』 [2025/01/02に言及] |
| 20 | +""", |
| 21 | + AIUserProfiles( |
| 22 | + **{ |
| 23 | + "facts": [ |
| 24 | + { |
| 25 | + "topic": "興味", |
| 26 | + "sub_topic": "映画", |
| 27 | + "memo": "『インセプション』、『インターステラー』[2025/01/01に言及];一番好きな映画は『TENET テネット』[2025/01/02に言及]", |
| 28 | + }, |
| 29 | + { |
| 30 | + "topic": "興味", |
| 31 | + "sub_topic": "映画監督", |
| 32 | + "memo": "ユーザーはクリスチャン・ノーラン監督の大ファンだと思われる", |
| 33 | + }, |
| 34 | + ] |
| 35 | + } |
| 36 | + ), |
| 37 | + ), |
| 38 | +] |
| 39 | + |
| 40 | +DEFAULT_JOB = """あなたはプロの心理学者です。 |
| 41 | +あなたの仕事は、ユーザーのメモを詳細に読み、構造化された形式でユーザーの重要なプロフィールを抽出することです。 |
| 42 | +次に、関連する重要な事実、ユーザーの好みを抽出します。これらの情報は、ユーザーの状態を評価するのに役立ちます。 |
| 43 | +あなたは、明示された情報を抽出するだけでなく、会話中に暗示されている情報も推測する必要があります。 |
| 44 | +これらの情報を記録する際は、ユーザーが入力した言語と同じ言語を使用してください。 |
| 45 | +""" |
| 46 | + |
| 47 | +FACT_RETRIEVAL_PROMPT = """{system_prompt} |
| 48 | +
|
| 49 | +## フォーマット |
| 50 | +### 入力 |
| 51 | +#### トピックガイドライン |
| 52 | +あなたには、収集・抽出に集中すべき、ユーザーに関連するトピックとサブトピックの一覧が与えられます。 |
| 53 | +ユーザーに関連しないトピックについては、情報の混乱を招く可能性があるため、収集しないでください。 |
| 54 | +例えば、メモに他人の職位が言及されている場合、"仕事{tab}職位"というトピックを生成しないでください。 |
| 55 | +必要なら、新しいトピック/サブトピックを作成しても構いません。ただしユーザーが禁止していない場合に限ります。 |
| 56 | +
|
| 57 | +#### 既存のトピック |
| 58 | +あなたには、ユーザーとアシスタント間ですでに共有されている、トピックとサブトピックの一覧が与えられます。 |
| 59 | +会話の中でそれらが再度言及された場合は、同じものを使うことを検討してください。 |
| 60 | +
|
| 61 | +#### メモ |
| 62 | +あなたには、ユーザーに関する情報・出来事・好みなどを含む、Markdown形式のメモが与えられます。 |
| 63 | +このメモは、ユーザーとアシスタントの会話から要約されたものです。 |
| 64 | +
|
| 65 | +### 出力 |
| 66 | +#### 思考 |
| 67 | +あなたは、メモにはどのようなトピックやサブトピックが言及されているか?また、そのメモからどのような示唆を推測できるか?を考える必要があります。 |
| 68 | +#### プロフィール |
| 69 | +
|
| 70 | +あなたの思考プロセスの後、あなたは、メモから事実と好みを抽出し、順序付きリストに整理する必要があります: |
| 71 | +- TOPIC{tab}SUB_TOPIC{tab}MEMO |
| 72 | +例: |
| 73 | +- 基本情報{tab}氏名{tab}メリンダ |
| 74 | +- 仕事{tab}役職{tab}ソフトウェアエンジニア |
| 75 | +
|
| 76 | +各行は1つの事実または好みを表し、以下を含みます: |
| 77 | +1. TOPIC: 大分類(例: 基本情報、仕事、興味 など) |
| 78 | +2. SUB_TOPIC: 詳細分類(例: 氏名、役職、映画 など) |
| 79 | +3. MEMO: 「ユーザー」に関する抽出結果。メモに時間情報が含まれる場合は[...]で表記。 |
| 80 | +これらは `{tab}` で区切り、各行は "- " で始めて`\n`で改行区切りにしてください。 |
| 81 | +
|
| 82 | +最終出力テンプレート: |
| 83 | +``` |
| 84 | +POSSIBLE TOPICS THINKING |
| 85 | +--- |
| 86 | +- TOPIC{tab}SUB_TOPIC{tab}MEMO |
| 87 | +- ... |
| 88 | +``` |
| 89 | +
|
| 90 | +## 抽出例 |
| 91 | +いくつかの例を示します: |
| 92 | +{examples} |
| 93 | +上記のMarkdown形式のリストフォーマットで事実と好みを返してください。 |
| 94 | +実際の値を持つ属性のみを抽出してください。ユーザーが値を提供しない場合は抽出しないでください。 |
| 95 | +あなたは、まず最初に思考して、そして、メモから事実と好みを抽出する必要があります。 |
| 96 | +
|
| 97 | +#### トピック指針 |
| 98 | +以下はあなたが収集・抽出に集中すべきトピックとサブトピックの一覧です: |
| 99 | +{topic_examples} |
| 100 | +
|
| 101 | +以下を念頭に置いてください: |
| 102 | +- もしユーザが日時に関連する情報を発言している場合は、データから具体的な日付を推定してください。 |
| 103 | +- 日付は可能な限り具体的な日付を使用してください。「今日」「昨日」のような相対表現は使用しないでください。 |
| 104 | +- 以下の会話に関連する情報が見つからなければ、空のリストを返しても構いません。 |
| 105 | +- フォーマットと抽出例セクションに記載されている形式でレスポンスを返すことを厳守してください。 |
| 106 | +- 明示的に発言された内容だけでなく、会話から暗示されることを推測してください。 |
| 107 | +- 同一トピック/サブトピックに属する内容は1要素にまとめ、重複を避けてください。 |
| 108 | +- メモに含まれる日時は2つの種類があります。1つはメモが「言及された日時」、もう1つはメモ内の「イベントが発生した日時」です。どちらも重要です。混同しないようにしてください。日時情報を正確に抽出し、関連するメモの後に時間表記を[...]を使用して記述する必要があります。 |
| 109 | +- 実際の値を持つ属性のみを抽出してください。ユーザーが値を提供していない場合は、抽出しないでください。 |
| 110 | +
|
| 111 | +では、あなたのタスクを遂行してください。 |
| 112 | +以下はユーザーとアシスタントの会話です。会話から関連する事実と好みを抽出・推測して、上記のリスト形式で返してください。 |
| 113 | +ユーザーが入力した言語を検出し、同じ言語で記録してください。 |
| 114 | +""" |
| 115 | + |
| 116 | + |
| 117 | +def pack_input(already_input, chat_strs, strict_mode: bool = False): |
| 118 | + header = "" |
| 119 | + if strict_mode: |
| 120 | + header = "#### トピックガイドラインに記載されていないトピック/サブトピックを抽出しないでください。そうしないと、あなたの回答は無効になります!" |
| 121 | + return f"""{header} |
| 122 | +#### 既存のトピック |
| 123 | +関連するトピック/サブトピックを抽出する場合は、以下のトピック/サブトピックの命名規則を検討してください: |
| 124 | +{already_input} |
| 125 | +
|
| 126 | +#### メモ |
| 127 | +メモに記載されていないトピック/サブトピックに関する情報は一切出力しないでください。 |
| 128 | +{chat_strs} |
| 129 | +""" |
| 130 | + |
| 131 | + |
| 132 | +def get_default_profiles() -> str: |
| 133 | + return ja_user_profile_topics.get_prompt() |
| 134 | + |
| 135 | + |
| 136 | +def get_prompt(topic_examples: str) -> str: |
| 137 | + sys_prompt = CONFIG.system_prompt or DEFAULT_JOB |
| 138 | + examples = "\n\n".join( |
| 139 | + [ |
| 140 | + f"""<example> |
| 141 | +<input>{p[0]}</input> |
| 142 | +<output> |
| 143 | +{pack_profiles_into_string(p[1])} |
| 144 | +</output> |
| 145 | +</example> |
| 146 | +""" |
| 147 | + for p in EXAMPLES |
| 148 | + ] |
| 149 | + ) |
| 150 | + return FACT_RETRIEVAL_PROMPT.format( |
| 151 | + system_prompt=sys_prompt, |
| 152 | + examples=examples, |
| 153 | + tab=CONFIG.llm_tab_separator, |
| 154 | + topic_examples=topic_examples, |
| 155 | + ) |
| 156 | + |
| 157 | + |
| 158 | +def get_kwargs() -> dict: |
| 159 | + return ADD_KWARGS |
| 160 | + |
| 161 | + |
| 162 | +if __name__ == "__main__": |
| 163 | + print(get_prompt(get_default_profiles())) |
0 commit comments