feat: solution for unknown
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
from langchain_openai import ChatOpenAI
|
from langchain_openai import ChatOpenAI
|
||||||
from pydantic import BaseModel, Field, SecretStr
|
from pydantic import BaseModel, Field, SecretStr
|
||||||
from langchain.agents import create_agent
|
from langchain_core.output_parsers import PydanticOutputParser
|
||||||
import sys
|
from langchain_core.prompts import PromptTemplate
|
||||||
|
|
||||||
# LLM placeholder configuration
|
# LLM placeholder
|
||||||
llm = ChatOpenAI(
|
llm = ChatOpenAI(
|
||||||
model="openai/gpt-oss-20b",
|
model="openai/gpt-oss-20b",
|
||||||
base_url='https://platform.brojs.ru/jrnl-bh/api/inference/v1',
|
base_url='https://platform.brojs.ru/jrnl-bh/api/inference/v1',
|
||||||
@@ -11,72 +11,62 @@ llm = ChatOpenAI(
|
|||||||
temperature=0.7,
|
temperature=0.7,
|
||||||
)
|
)
|
||||||
|
|
||||||
# ---------- Pydantic models ----------
|
|
||||||
class PersonInfo(BaseModel):
|
class PersonInfo(BaseModel):
|
||||||
"""Information about a person."""
|
name: str = Field(description="Имя человека")
|
||||||
name: str = Field(description="Full name of the person")
|
age: int | None = Field(default=None, description="Возраст (необязательно)")
|
||||||
age: int | None = Field(default=None, description="Age in years, optional")
|
profession: str = Field(description="Профессия")
|
||||||
profession: str = Field(description="Current occupation or job title")
|
skills: list[str] = Field(description="Список навыков")
|
||||||
skills: list[str] = Field(description="List of professional skills")
|
|
||||||
|
|
||||||
class MeetingNotes(BaseModel):
|
class MeetingNotes(BaseModel):
|
||||||
"""Summary of a meeting."""
|
date: str = Field(description="Дата встречи в формате YYYY-MM-DD")
|
||||||
date: str = Field(description="Date of the meeting (ISO format)")
|
participants: list[str] = Field(description="Участники встречи")
|
||||||
participants: list[str] = Field(description="Names of attendees")
|
topics: list[str] = Field(description="Обсуждаемые темы")
|
||||||
topics: list[str] = Field(description="Main discussion topics")
|
decisions: list[str] = Field(description="Принятые решения")
|
||||||
decisions: list[str] = Field(description="Decisions made during the meeting")
|
next_steps: list[str] = Field(description="Следующие шаги")
|
||||||
next_steps: list[str] = Field(description="Action items for follow‑up")
|
|
||||||
|
|
||||||
# ---------- Agent creation ----------
|
person_parser = PydanticOutputParser(pydantic_object=PersonInfo)
|
||||||
agent_person = create_agent(
|
meeting_parser = PydanticOutputParser(pydantic_object=MeetingNotes)
|
||||||
model=llm,
|
|
||||||
response_format=PersonInfo,
|
prompt_template = PromptTemplate(
|
||||||
system_prompt="You are an assistant that extracts structured person information from a single sentence.",
|
input_variables=["text", "format_instructions"],
|
||||||
|
template="""Найди в тексте следующую информацию и верни её как JSON:
|
||||||
|
{format_instructions}
|
||||||
|
Текст: {text}"""
|
||||||
)
|
)
|
||||||
|
|
||||||
agent_meeting = create_agent(
|
def choose_parser(text: str):
|
||||||
model=llm,
|
if any(word in text.lower() for word in ["meeting", "встреча", "собрание"]):
|
||||||
response_format=MeetingNotes,
|
return meeting_parser
|
||||||
system_prompt="You are an assistant that extracts structured meeting notes from a paragraph of text.",
|
return person_parser
|
||||||
)
|
|
||||||
|
|
||||||
# ---------- Simple heuristic to choose schema ----------
|
def extract(text: str):
|
||||||
def detect_schema(text: str) -> str:
|
parser = choose_parser(text)
|
||||||
"""Return 'person' or 'meeting' based on simple keyword heuristics."""
|
chain = prompt_template | llm | parser
|
||||||
lower = text.lower()
|
result = chain.invoke({"text": text, "format_instructions": parser.get_format_instructions()})
|
||||||
if any(word in lower for word in ("profession", "skills", "age")):
|
return result
|
||||||
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---")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
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())
|
||||||
Reference in New Issue
Block a user