Files
2026-05-28 18:08:43 +00:00

77 lines
2.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Agent module that performs structured extraction using LangChain and Pydantic.
The module exposes a single public function `extract_structured_output` which:
1. Detects whether the input text describes a person or a meeting.
2. Builds an appropriate prompt with format instructions from the chosen parser.
3. Sends the request to the LLM via LangChain and returns the parsed Pydantic model instance.
"""
from __future__ import annotations
import re
from typing import Union, List
from langchain_core.output_parsers import PydanticOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from models import PersonInfo, MeetingNotes
# LLM configuration BroJS endpoint
llm = ChatOpenAI(
model="openai/gpt-oss-20b:free",
base_url="https://platform.brojs.ru/jrnl-bh/api/inference/v1",
api_key=None, # will be taken from env var JOURNAL_MCP_PAT
temperature=0.0,
)
# Prompt template the same for both schemas; format instructions are injected.
PROMPT = PromptTemplate(
input_variables=["text", "format_instructions"],
template="""
You are a data extraction assistant.
Extract structured information from the following text and return it as JSON that matches the provided schema.
Text:
{text}
Schema format instructions:
{format_instructions}
Respond only with valid JSON. Do not add any extra text.
""",
)
def _detect_schema(text: str) -> type:
"""Heuristically determine whether the input describes a person or a meeting.
Returns the corresponding Pydantic model class.
"""
# Simple keyword checks can be extended
if re.search(r"\bmeeting\b|\bdate\b|\bparticipants?\b", text, re.I):
return MeetingNotes
return PersonInfo
def extract_structured_output(text: str) -> Union[PersonInfo, MeetingNotes]:
"""Return a Pydantic model instance extracted from *text*.
Parameters
----------
text:
Freeform input string.
Returns
-------
PersonInfo | MeetingNotes
Parsed data as a validated Pydantic object.
"""
schema = _detect_schema(text)
parser = PydanticOutputParser(pydantic_object=schema)
prompt = PROMPT.format(text=text, format_instructions=parser.get_format_instructions())
response = llm.invoke([prompt])
# The LLM returns a string; parse it
return parser.parse(response.content)
__all__ = ["extract_structured_output"]