Spaces:
Runtime error
Runtime error
| import json | |
| from typing import Literal | |
| from pydantic import BaseModel | |
| import litellm | |
| from litellm.types.utils import ModelResponse | |
| SAFETY_SETTINGS = [ | |
| { | |
| "category": "HARM_CATEGORY_HARASSMENT", | |
| "threshold": "BLOCK_NONE", | |
| }, | |
| { | |
| "category": "HARM_CATEGORY_HATE_SPEECH", | |
| "threshold": "BLOCK_NONE", | |
| }, | |
| { | |
| "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", | |
| "threshold": "BLOCK_NONE", | |
| }, | |
| { | |
| "category": "HARM_CATEGORY_DANGEROUS_CONTENT", | |
| "threshold": "BLOCK_NONE", | |
| }, | |
| ] | |
| class BloggerAgent: | |
| instructions = [ | |
| { | |
| "role": "user", | |
| "content": "与えられる情報について、重要なポイントを踏まえて平易な言葉で解説・紹介する記事を書いてください", | |
| }, | |
| ] | |
| model: str = "gemini/gemini-2.5-flash-preview-05-20" | |
| temperature: float = 1.0 | |
| max_tokens: int = 4096 | |
| thinking_budget: int = 1024 | |
| api_key: str | |
| def __init__(self, api_key: str): | |
| self.api_key = api_key | |
| async def task(self, information: str) -> str: | |
| messages = self.instructions.copy() | |
| messages.append({"role": "user", "content": information}) | |
| res = await litellm.acompletion( | |
| api_key=self.api_key, | |
| model=self.model, | |
| messages=messages, | |
| temperature=self.temperature, | |
| max_completion_tokens=self.max_tokens, | |
| thinking={"type": "enabled", "budget_tokens": self.thinking_budget}, | |
| safety_settings=SAFETY_SETTINGS, | |
| ) | |
| assert isinstance(res, ModelResponse) | |
| blog = res.choices[0].message.content | |
| assert isinstance(blog, str) | |
| return blog | |
| class WriterAgent: | |
| instructions = [ | |
| { | |
| "role": "user", | |
| "content": """与えられる情報ソースとその解説記事をもとに、コンテンツを紹介する Podcast の会話を作成してください。 | |
| Podcast では、二人の人物が交互に会話をします。 | |
| # 登場人物 | |
| - スピーカー: コンテンツ紹介をリードする人で、主にこの人物が解説を行う | |
| - サポーター: スピーカーの説明を聞き、うなづいたり、さらに質問を投げかけることで、理解を助ける。 | |
| # 構成 | |
| 1. イントロ: まず、スピーカーとサポーターが何について話すのか、挨拶を交えながら会話します。自己紹介は省略する。 | |
| 2. 解説: 前提知識の確認をしながら、内容を解説していきます | |
| 3. アウトロ: 今後の展望を交えながら締めくくります | |
| --- | |
| このような内容になるような Podcast の脚本を作成してください。 | |
| """.strip(), | |
| }, | |
| ] | |
| model: str = "gemini/gemini-2.5-flash-preview-05-20" | |
| temperature: float = 1.0 | |
| max_tokens: int = 4096 | |
| thinking_budget: int = 1024 | |
| api_key: str | |
| def __init__(self, api_key: str): | |
| self.api_key = api_key | |
| async def task(self, information: str, blog: str) -> str: | |
| messages = self.instructions.copy() | |
| messages.append( | |
| {"role": "user", "content": f"# 情報\n{information}\n\n# 解説\n{blog}"} | |
| ) | |
| res = await litellm.acompletion( | |
| api_key=self.api_key, | |
| model=self.model, | |
| messages=messages, | |
| temperature=self.temperature, | |
| max_completion_tokens=self.max_tokens, | |
| thinking={"type": "enabled", "budget_tokens": self.thinking_budget}, | |
| safety_settings=SAFETY_SETTINGS, | |
| ) | |
| assert isinstance(res, ModelResponse) | |
| dialogue = res.choices[0].message.content | |
| assert isinstance(dialogue, str) | |
| return dialogue | |
| class Dialogue(BaseModel): | |
| role: Literal["speaker", "supporter"] | |
| content: str | |
| class Conversation(BaseModel): | |
| conversation: list[Dialogue] | |
| class StructureAgent: | |
| instructions = [ | |
| { | |
| "role": "user", | |
| "content": """この会話を指定されたスキーマに従った形に変換してください。スピーカーの role は `speaker`、サポーターは `supporter` です。""".strip(), | |
| }, | |
| ] | |
| model: str = "gemini/gemini-2.5-flash-preview-05-20" | |
| temperature: float = 0.1 | |
| max_tokens: int = 12_288 | |
| thinking_budget: int = 0 | |
| api_key: str | |
| def __init__(self, api_key: str): | |
| self.api_key = api_key | |
| async def task(self, dialogue: str) -> Conversation: | |
| messages = self.instructions.copy() | |
| messages.append({"role": "user", "content": dialogue}) | |
| res = await litellm.acompletion( | |
| api_key=self.api_key, | |
| model=self.model, | |
| messages=messages, | |
| temperature=self.temperature, | |
| max_completion_tokens=self.max_tokens, | |
| thinking={"type": "disabled"}, | |
| response_format=Conversation, | |
| safety_settings=SAFETY_SETTINGS, | |
| ) | |
| conversation = Conversation.model_validate( | |
| json.loads(res.choices[0].message.content) | |
| ) | |
| return conversation | |