add agent.py
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
"""
|
||||
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:
|
||||
Free‑form 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"]
|
||||
Reference in New Issue
Block a user