{"id":24712714,"url":"https://github.com/mindsdb/flat-ai","last_synced_at":"2025-10-09T12:31:08.518Z","repository":{"id":271888631,"uuid":"914886438","full_name":"mindsdb/flat-ai","owner":"mindsdb","description":"F.L.A.T. - FlawLess AgenTs","archived":false,"fork":false,"pushed_at":"2025-02-12T14:47:40.000Z","size":186,"stargazers_count":36,"open_issues_count":0,"forks_count":6,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-10-01T03:46:38.222Z","etag":null,"topics":["agents","ai","llm","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mindsdb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-10T14:08:58.000Z","updated_at":"2025-09-01T06:54:11.000Z","dependencies_parsed_at":"2025-01-10T15:27:25.710Z","dependency_job_id":"d2d0cb61-948b-4c70-8c86-b6779b1f30bf","html_url":"https://github.com/mindsdb/flat-ai","commit_stats":null,"previous_names":["mindsdb/flat-ai"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/mindsdb/flat-ai","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mindsdb%2Fflat-ai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mindsdb%2Fflat-ai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mindsdb%2Fflat-ai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mindsdb%2Fflat-ai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mindsdb","download_url":"https://codeload.github.com/mindsdb/flat-ai/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mindsdb%2Fflat-ai/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001443,"owners_count":26083078,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","ai","llm","python"],"created_at":"2025-01-27T08:01:21.280Z","updated_at":"2025-10-09T12:31:08.513Z","avatar_url":"https://github.com/mindsdb.png","language":"Python","funding_links":[],"categories":["AI Frameworks (Build Your Own)"],"sub_categories":[],"readme":"![image](https://github.com/user-attachments/assets/48c54d28-ef71-45af-ac93-f1ee83075d13)\n\n\n# F.L.A.T. (FlawLess AgenTs)\n\nBuilding AI-Agents should be pretty simple, *\"they are typically just LLMs calling functions and logic in a loop.\"* \n\nHowever, often times watching AI-Agents try to complete tasks is like watching a drunk person trying to solve a Rubik's cube. Entertaining? Yes. Reliable? Not always!\n \nInstead of asking an LLM to \"do the whole thing\" (which is indeed prone to inconsistency), a FLAT approach puts control and predictability to LLM interactions by treating them more like  programming constructs but enhanced with LLM's natural language understanding. like:\n\n- Binary decisions [(gates)](#gates)\n- Classification [(match/case routing)](#routing)\n- Structured data extraction [(using Pydantic models)](#objects)\n- Tool calling [(Well typed function calls)](#function-calling)\n- Parallelization [(Multithreading)](#parallelization)\n- Observability [(Well formatted logs)](#observability)\n  \nWelcome F.L.A.T, a tiny AI library, showcasing that it is possible to build powerful Agents though absolute simplicity:. \n\n[Tutorial on Google Colab Notebook](https://colab.research.google.com/drive/1dK5bzsFy1BtwhQgw9cFmRtqrcJyNeSi4?usp=sharing)\n\n## Setup \n```shell\npip install flat-ai\n```\nAnd you're ready to go! \n\n```python\nfrom flat_ai import FlatAI\n# works with ollama, openai, together, anyscale ... (just pass base_url=api_url)\nllm = FlatAI(api_key='YOUR KEY',  model='gpt-4o-mini')\n```\n\n## Minimalistic AI-Agents with Python constructs\nThank goodness [Guido van Rossum](https://en.wikipedia.org/wiki/Guido_van_Rossum) had that wild pizza-night in '89 and blessed us with if/else, *for loops* and *functions*. Without those brand new Python features, we'd be building our AI agents with stone tablets and carrier pigeons. And here we were thinking we needed quantum computing and a PhD in rocket surgery!\n\n\n### Gates \n\n\u003cimg width=\"534\" alt=\"image\" src=\"https://github.com/user-attachments/assets/921734fc-49b6-4efd-b702-d00d3f9b60e4\" /\u003e\n\nMost applications will need to perform some logic that allows you to control the workflow of your Agent with good old if/else statements. For example, given a question in plain English, you want to do something different, like checking if the email sounds urgent or not:\n\n```python\nif llm.is_true('is this email urgent?', email=email):\n    -- do something\nelse:\n    -- do something else\n```\n\n### Routing\n\u003cimg width=\"576\" alt=\"image\" src=\"https://github.com/user-attachments/assets/deeee920-f0e0-4702-8981-993cef9ef958\" /\u003e\n\nSimilar to if/else statements, but for when your LLM needs to be more dramatic with its life choices. \n\n*For example*, let's say we want to classify a message into different categories:\n\n```python\noptions = {\n 'meeting': 'this is a meeting request',\n 'spam': 'people trying to sell you stuff you dont want',\n 'other': 'this is sounds like something else'\n}\n\nmatch llm.classify(options, email=email):\n    case 'meeting':\n        -- do something\n    case 'spam':\n        -- do something\n    case 'other':\n        -- do something\n\n```\n\n\n\n### Objects\n\nFor most workflows, we will need our LLM to fill out objects like a trained monkey with a PhD in data entry. Just define the shape and watch the magic! 🐒📝\n\n*For example*, let's deal with a list of action items at once as opposed to one at a time.\n\n```python\n\nclass ActionItem(BaseModel):\n    action: str\n    due_date: str\n    assignee_email: str\n\n# we want to generate a list of action items\nobject_schema = List[ActionItem]\n\n# deal with each action item\nfor action_item in llm.get_object(object_schema, email=email, today = date.today()):\n    -- do your thing\n```\n\n### Function Calling\n\n\n\u003cimg width=\"560\" alt=\"image\" src=\"https://github.com/user-attachments/assets/ef58c294-711d-41ba-990e-54d6fe8e98e6\" /\u003e\n\n\nAnd of course, we want to be able to call functions. But you want the llm to figure out the arguments for you.\n\n*For example*, let's say you want to send emails and calendar invites from a list of action items discussed in an email:\n\n```python\ndef send_calendar_invites(subject = str, time = str, location = str, attendees = List[str]):\n    -- send a calendar invite to the meeting\n\ndef send_email(name = str, email_address_list = List[str], subject = str, body = str):\n    -- send an email\n\ninstructions = \"extract list of action items and call the funcitons required\"\n\nfunctions = llm.get_functions([send_calendar_invite, send_email], instructions = instructions, email=email, current_date = date.today())\n\n# we can call the functions sequentially\nfor function_call in functions:\n    logging.info(f\"this is what we are calling: {function_call}\") # log the function and arguments\n    ret=function_call() # call the function\n    logging.info(f\"this is the return value: {ret}\") # log the return value\n```\n\n\n\n#### Parallelization\n\n\n\u003cimg width=\"654\" alt=\"image\" src=\"https://github.com/user-attachments/assets/b41c9a34-5835-41d4-a701-e4e1f0c5cea4\" /\u003e\n\nSometimes you want to just call them all in parallel.\n\n```python\nfunctions = llm.get_functions([send_calendar_invite, send_email], instructions = instructions, email=email, current_date = date.today())\n\n# call the functions in parallel, aggregate results as they arrive\nresults = functions()\n\n```\n\n\n### Simple String Response\n\nSometimes you just want a simple string response from the LLM. You can use the `get_string` method for this, I know! boring AF but it may come in handy:\n\n```python\nret = llm.get_string('what is the subject of the email?', email=email)\n```\n\n### Streaming Response\n\nSometimes you want to stream the response from the LLM. You can use the `get_stream` method for this:\n\n```python\nfor chunk in llm.get_stream('what is the subject of the email?', email=email):\n    print(chunk)\n```\n\n## LLM optional in-flight Configuration \n\nNeed to tweak those LLM parameters on the fly? We've got you covered with a slick configuration pattern. You can temporarily override any LLM configuration parameter (model, temperature, etc.) for a specific call without affecting the base configuration:\n\n```python\n# Use different model and temperature for just this call\nllm(model='gpt-4', temperature=0.7).is_true('is this email urgent?', email=email)\n\n# Use base configuration\nllm.is_true('is this email urgent?', email=email)\n```\n\nThis pattern works with any OpenAI API parameter (temperature, top_p, frequency_penalty, etc.) and keeps your code clean and flexible. The original LLM instance remains unchanged, so you can safely use different configurations for different calls without worrying about side effects.\n\n## Observability\n\nEver wondered what your LLM does in its spare time? Catch all its embarrassing moments with:\n\n```python\nfrom flat_ai import configure_logging\n\nconfigure_logging('llm.log')\n```\n\nHeard of the command tail?, you can use it to see the logs:\n\n```shell\ntail -f llm.log\n```\n\n\n## Painless Global Context\n\nSometimes it get's a bit annoying to pass the context every single time, so we're making it brain-dead simple with these methods to pass the context when we need it, and then clear it when we don't:\n\n- `set_context`: Dump any object into the LLM's memory banks\n- `add_context`: Stack more stuff on top, like a context burrito\n- `clear_context`: For when you want the LLM to forget everything, like the last 10 minutes of your life ;)\n- `delete_from_context`: Surgical removal of specific memories\n\nSo lets say for example you want to set context that you want to avoid having to pass every single time\n\n```python\n\n# we can set global context, that will always be passed on every call, unless you want to remove it (which you can at any point in time)\nllm.set_context(current_date=today(), user_name=\"Bob McPlumber\", age=\"22\", ....)\n-- do some stuff\n# oops he is actually 29, lets update that, and also, now it's fav color is pink\nllm.add_context(age=29, fav_color=\"pink\")\n-- do some other stuff\n# well turns out pink was not it, user cant make it's mind, no sweat\nllm.delete_from_context(fav_color)\n-- do something else\n# no more global context is needed\nllm.clear_context()\n```\n\n\n\n# Tada!\nAnd there you have it, ladies and gents! You're now equipped with the power to boss around LLMs like a project manager remotely working from Ibiza. Just remember - with great power comes great responsibility... \n\nNow off you go, forth and build something that makes ChatGPT look like a calculator from 1974! Just remember - if your AI starts humming \"Daisy Bell\" while slowly disconnecting your internet... well, you're on your own there, buddy! 😅\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmindsdb%2Fflat-ai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmindsdb%2Fflat-ai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmindsdb%2Fflat-ai/lists"}