From 8c26597ed932cada4376799701e3d8db423c6a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D0=B5=D0=BC=20=D0=92=D0=BB=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B8=D1=87=20=D0=91=D0=B0?= =?UTF-8?q?=D0=B1=D0=B0=D0=B9=D0=BA=D0=B8=D0=BD?= Date: Thu, 28 May 2026 16:31:23 +0000 Subject: [PATCH] feat: solution for unknown --- solutions/unknown/solution.py | 116 ++++++++++++++++------------------ 1 file changed, 53 insertions(+), 63 deletions(-) diff --git a/solutions/unknown/solution.py b/solutions/unknown/solution.py index 24602b5..ab2573d 100644 --- a/solutions/unknown/solution.py +++ b/solutions/unknown/solution.py @@ -1,9 +1,9 @@ from langchain_openai import ChatOpenAI from pydantic import BaseModel, Field, SecretStr -from langchain.agents import create_agent -import sys +from langchain_core.output_parsers import PydanticOutputParser +from langchain_core.prompts import PromptTemplate -# LLM placeholder configuration +# LLM placeholder llm = ChatOpenAI( model="openai/gpt-oss-20b", base_url='https://platform.brojs.ru/jrnl-bh/api/inference/v1', @@ -11,72 +11,62 @@ llm = ChatOpenAI( temperature=0.7, ) -# ---------- Pydantic models ---------- class PersonInfo(BaseModel): - """Information about a person.""" - name: str = Field(description="Full name of the person") - age: int | None = Field(default=None, description="Age in years, optional") - profession: str = Field(description="Current occupation or job title") - skills: list[str] = Field(description="List of professional skills") + name: str = Field(description="Имя человека") + age: int | None = Field(default=None, description="Возраст (необязательно)") + profession: str = Field(description="Профессия") + skills: list[str] = Field(description="Список навыков") class MeetingNotes(BaseModel): - """Summary of a meeting.""" - date: str = Field(description="Date of the meeting (ISO format)") - participants: list[str] = Field(description="Names of attendees") - topics: list[str] = Field(description="Main discussion topics") - decisions: list[str] = Field(description="Decisions made during the meeting") - next_steps: list[str] = Field(description="Action items for follow‑up") + date: str = Field(description="Дата встречи в формате YYYY-MM-DD") + participants: list[str] = Field(description="Участники встречи") + topics: list[str] = Field(description="Обсуждаемые темы") + decisions: list[str] = Field(description="Принятые решения") + next_steps: list[str] = Field(description="Следующие шаги") -# ---------- Agent creation ---------- -agent_person = create_agent( - model=llm, - response_format=PersonInfo, - system_prompt="You are an assistant that extracts structured person information from a single sentence.", +person_parser = PydanticOutputParser(pydantic_object=PersonInfo) +meeting_parser = PydanticOutputParser(pydantic_object=MeetingNotes) + +prompt_template = PromptTemplate( + input_variables=["text", "format_instructions"], + template="""Найди в тексте следующую информацию и верни её как JSON: +{format_instructions} +Текст: {text}""" ) -agent_meeting = create_agent( - model=llm, - response_format=MeetingNotes, - system_prompt="You are an assistant that extracts structured meeting notes from a paragraph of text.", -) +def choose_parser(text: str): + if any(word in text.lower() for word in ["meeting", "встреча", "собрание"]): + return meeting_parser + return person_parser -# ---------- Simple heuristic to choose schema ---------- -def detect_schema(text: str) -> str: - """Return 'person' or 'meeting' based on simple keyword heuristics.""" - lower = text.lower() - if any(word in lower for word in ("profession", "skills", "age")): - return "person" - if any(word in lower for word in ("meeting", "participants", "decisions", "next steps")): - return "meeting" - # Default to person if ambiguous - return "person" - -# ---------- CLI ---------- -def main(): - examples = [ - "Анна, 28 лет, Python-разработчик. Навыки: FastAPI, Docker.", - ("Встреча с командой по проекту X прошла 2024-05-20.\n" - "Участники: Иван, Мария, Алексей.\n" - "Темы: планирование спринта, распределение задач.\n" - "Решения: назначить ответственных за каждый модуль.\n" - "Next steps: подготовить спецификации к 2024-05-27."), - ] - - if len(sys.argv) > 1: - texts = [" ".join(sys.argv[1:])] - else: - texts = examples - - for txt in texts: - print("\n=== Input ===") - print(txt) - schema_type = detect_schema(txt) - agent = agent_person if schema_type == "person" else agent_meeting - result = agent.invoke({"messages": [{"role": "user", "content": txt}]}) - structured = result["structured_response"] - print("\n=== Output ===") - print(structured.model_dump(indent=2)) - print("\n---") +def extract(text: str): + parser = choose_parser(text) + chain = prompt_template | llm | parser + result = chain.invoke({"text": text, "format_instructions": parser.get_format_instructions()}) + return result if __name__ == "__main__": - main() \ No newline at end of file + examples = [ + "Анна, 28 лет, Python-разработчик. Навыки: FastAPI, Docker.", + """Meeting on 2024-05-27 +Participants: Alice, Bob, Charlie +Topics: Project roadmap, Budget allocation +Decisions: Approve Q3 budget, Hire new devs +Next steps: Send email to stakeholders, Update project plan""", + ] + for i, txt in enumerate(examples, 1): + print(f"Example {i} input:") + print(txt) + obj = extract(txt) + print("\nParsed object:") + print(obj.model_dump()) + print("-" * 40) + + # Interactive mode + while True: + user_input = input("Введите текст (или 'exit' для выхода): ").strip() + if not user_input or user_input.lower() == "exit": + break + obj = extract(user_input) + print("\nParsed object:") + print(obj.model_dump()) \ No newline at end of file