Adds initial files]
This commit is contained in:
156
code/app.py
Normal file
156
code/app.py
Normal file
@@ -0,0 +1,156 @@
|
||||
from fastapi import FastAPI,Header
|
||||
import uvicorn
|
||||
"""
|
||||
Simple LangGraph Agent using @tool decorator
|
||||
|
||||
Clean implementation with decorator-based tool definitions.
|
||||
"""
|
||||
|
||||
from typing import Annotated, TypedDict
|
||||
from langgraph.graph import StateGraph, START, END
|
||||
from langgraph.graph.message import add_messages
|
||||
from langgraph.prebuilt import ToolNode, tools_condition
|
||||
from langchain_core.messages import HumanMessage, SystemMessage
|
||||
from langchain_core.tools import tool
|
||||
from langchain_aws import ChatBedrock
|
||||
app = FastAPI()
|
||||
|
||||
# Define tools using @tool decorator
|
||||
rules="""- Mulheres acima de 45 anos ou menopausada
|
||||
- Homens com mais de 70 anos;
|
||||
- Osteogênese imperfeita (para esta patologia, poderá haver a liberação de (02) dois
|
||||
exames ao ano - cada 180 dias);
|
||||
- RX com osteopenia ou fratura patológica;
|
||||
- Antecedente pessoal de fratura após os 40 anos: punho, ombros, vértebras, quadril;
|
||||
- Parente de primeiro grau com osteoporose.
|
||||
- Mulheres com massa corporal <20kg/m2 ou peso < 57,8kg;
|
||||
- Menopausa antes dos 45 anos ou hipogonasismo crônico (falência ovariana
|
||||
precoce);
|
||||
- Uso de glicocorticóides (>=7,5 prednizona/ dia equivalente por mais três meses, ou
|
||||
presença de síndrome de cushing;
|
||||
- Hiperparatireoidismo primário;
|
||||
- Uso prolongado de anticonvulsivantes (< 10 anos);
|
||||
- Síndrome de má absorção crônica ou desnutrição doenças inflamatória intestinal
|
||||
(independente da causa: bariatrica, celiacos, intolerancia a lactose).
|
||||
- Quimioterapia, se sobrevida esperada for longa (< 5 anos);
|
||||
- Diminuição documentada de altura;
|
||||
- Presença de cifose após menopausa.
|
||||
- Imobilização prolongada"""
|
||||
SYSTEM_PROMPT="""
|
||||
You are a assisant, your job is to aprove or not a procedure based on the following rules:"""
|
||||
+rules+"""
|
||||
Your input will be a json, evaluate it based on the rules and return:
|
||||
Aproved: If one of the criteira is met
|
||||
Reproved: If not a single one of the criterias are met."""
|
||||
@tool
|
||||
def add(a: int, b: int) -> int:
|
||||
"""Add two numbers together.
|
||||
|
||||
Args:
|
||||
a: First number
|
||||
b: Second number
|
||||
"""
|
||||
return a + b
|
||||
|
||||
|
||||
@tool
|
||||
def multiply(a: int, b: int) -> int:
|
||||
"""Multiply two numbers.
|
||||
|
||||
Args:
|
||||
a: First number
|
||||
b: Second number
|
||||
"""
|
||||
return a * b
|
||||
|
||||
|
||||
@tool
|
||||
def get_word_length(word: str) -> int:
|
||||
"""Get the length of a word.
|
||||
|
||||
Args:
|
||||
word: The word to measure
|
||||
"""
|
||||
return len(word)
|
||||
|
||||
|
||||
@tool
|
||||
def search_info(topic: str) -> str:
|
||||
"""Search for information about a topic (mock implementation).
|
||||
|
||||
Args:
|
||||
topic: The topic to search for
|
||||
"""
|
||||
# Mock response - replace with actual search/API
|
||||
return f"Information about {topic}: This is a mock response. In production, this would return real data."
|
||||
|
||||
|
||||
# Define agent state
|
||||
class AgentState(TypedDict):
|
||||
messages: Annotated[list, add_messages]
|
||||
|
||||
|
||||
# Define tools list
|
||||
tools = [add, multiply, get_word_length, search_info]
|
||||
|
||||
|
||||
# Agent node
|
||||
def call_model(state: AgentState):
|
||||
"""Call the LLM with current state and tools."""
|
||||
|
||||
model = ChatBedrock(
|
||||
model_id="arn:aws:bedrock:us-east-2:232048051668:application-inference-profile/uy4xskop19zn",
|
||||
region_name="us-east-2",
|
||||
provider="anthropic"
|
||||
)
|
||||
|
||||
model_with_tools = model.bind_tools(tools)
|
||||
|
||||
messages = [
|
||||
SystemMessage(content=SYSTEM_PROMPT)
|
||||
] + state["messages"]
|
||||
|
||||
response = model_with_tools.invoke(messages)
|
||||
|
||||
return {"messages": [response]}
|
||||
|
||||
|
||||
# Build the graph
|
||||
def create_agent():
|
||||
"""Create and compile the agent graph."""
|
||||
|
||||
workflow = StateGraph(AgentState)
|
||||
|
||||
# Add nodes
|
||||
workflow.add_node("agent", call_model)
|
||||
workflow.add_node("tools", ToolNode(tools))
|
||||
|
||||
# Add edges
|
||||
workflow.add_edge(START, "agent")
|
||||
workflow.add_conditional_edges("agent", tools_condition)
|
||||
workflow.add_edge("tools", "agent")
|
||||
|
||||
return workflow.compile()
|
||||
|
||||
|
||||
# Main execution
|
||||
|
||||
|
||||
@app.post("/")
|
||||
async def root(json:str= Header(...)):
|
||||
agent = create_agent()
|
||||
query=json
|
||||
result = agent.invoke(
|
||||
{"messages": [HumanMessage(content=query)]},
|
||||
config={"recursion_limit": 10}
|
||||
)
|
||||
|
||||
final_message = result["messages"][-1]
|
||||
return {"status": "success", "message": final_message.content}
|
||||
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
return {"status": "healthy"}
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
Reference in New Issue
Block a user