flo_ai 0.0.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flo_ai-0.0.6/PKG-INFO +555 -0
- flo_ai-0.0.6/README.md +533 -0
- flo_ai-0.0.6/flo_ai/__init__.py +13 -0
- flo_ai-0.0.6/flo_ai/builders/__init__.py +0 -0
- flo_ai-0.0.6/flo_ai/builders/yaml_builder.py +74 -0
- flo_ai-0.0.6/flo_ai/callbacks/__init__.py +15 -0
- flo_ai-0.0.6/flo_ai/callbacks/flo_callbacks.py +223 -0
- flo_ai-0.0.6/flo_ai/callbacks/flo_execution_logger.py +277 -0
- flo_ai-0.0.6/flo_ai/common/__init__.py +0 -0
- flo_ai-0.0.6/flo_ai/common/flo_langchain_logger.py +68 -0
- flo_ai-0.0.6/flo_ai/common/flo_logger.py +122 -0
- flo_ai-0.0.6/flo_ai/constants/__init__.py +0 -0
- flo_ai-0.0.6/flo_ai/constants/common_constants.py +4 -0
- flo_ai-0.0.6/flo_ai/constants/flo_node_contants.py +2 -0
- flo_ai-0.0.6/flo_ai/constants/prompt_constants.py +1 -0
- flo_ai-0.0.6/flo_ai/core.py +152 -0
- flo_ai-0.0.6/flo_ai/error/flo_exception.py +16 -0
- flo_ai-0.0.6/flo_ai/factory/agent_factory.py +151 -0
- flo_ai-0.0.6/flo_ai/helpers/utils.py +13 -0
- flo_ai-0.0.6/flo_ai/models/__init__.py +0 -0
- flo_ai-0.0.6/flo_ai/models/delegate.py +7 -0
- flo_ai-0.0.6/flo_ai/models/exception.py +8 -0
- flo_ai-0.0.6/flo_ai/models/flo_agent.py +117 -0
- flo_ai-0.0.6/flo_ai/models/flo_base_agent.py +31 -0
- flo_ai-0.0.6/flo_ai/models/flo_delegation_agent.py +102 -0
- flo_ai-0.0.6/flo_ai/models/flo_executable.py +56 -0
- flo_ai-0.0.6/flo_ai/models/flo_llm_agent.py +91 -0
- flo_ai-0.0.6/flo_ai/models/flo_member.py +4 -0
- flo_ai-0.0.6/flo_ai/models/flo_node.py +330 -0
- flo_ai-0.0.6/flo_ai/models/flo_reflection_agent.py +75 -0
- flo_ai-0.0.6/flo_ai/models/flo_routed_team.py +11 -0
- flo_ai-0.0.6/flo_ai/models/flo_team.py +31 -0
- flo_ai-0.0.6/flo_ai/models/flo_tool_agent.py +59 -0
- flo_ai-0.0.6/flo_ai/parsers/__init__.py +5 -0
- flo_ai-0.0.6/flo_ai/parsers/flo_json_parser.py +160 -0
- flo_ai-0.0.6/flo_ai/parsers/flo_parser.py +12 -0
- flo_ai-0.0.6/flo_ai/parsers/flo_pydantic_parser.py +27 -0
- flo_ai-0.0.6/flo_ai/retrievers/__init__.py +0 -0
- flo_ai-0.0.6/flo_ai/retrievers/flo_compression_pipeline.py +43 -0
- flo_ai-0.0.6/flo_ai/retrievers/flo_multi_query.py +55 -0
- flo_ai-0.0.6/flo_ai/retrievers/flo_retriever.py +229 -0
- flo_ai-0.0.6/flo_ai/router/__init__.py +0 -0
- flo_ai-0.0.6/flo_ai/router/flo_agent_router.py +52 -0
- flo_ai-0.0.6/flo_ai/router/flo_linear.py +86 -0
- flo_ai-0.0.6/flo_ai/router/flo_llm_router.py +126 -0
- flo_ai-0.0.6/flo_ai/router/flo_router.py +174 -0
- flo_ai-0.0.6/flo_ai/router/flo_router_factory.py +67 -0
- flo_ai-0.0.6/flo_ai/router/flo_supervisor.py +101 -0
- flo_ai-0.0.6/flo_ai/state/__init__.py +4 -0
- flo_ai-0.0.6/flo_ai/state/flo_json_output_collector.py +97 -0
- flo_ai-0.0.6/flo_ai/state/flo_output_collector.py +26 -0
- flo_ai-0.0.6/flo_ai/state/flo_session.py +145 -0
- flo_ai-0.0.6/flo_ai/state/flo_state.py +27 -0
- flo_ai-0.0.6/flo_ai/storage/data_collector.py +40 -0
- flo_ai-0.0.6/flo_ai/tools/__init__.py +3 -0
- flo_ai-0.0.6/flo_ai/tools/flo_tool.py +38 -0
- flo_ai-0.0.6/flo_ai/yaml/config.py +124 -0
- flo_ai-0.0.6/flo_ai/yaml/validators.py +11 -0
- flo_ai-0.0.6/pyproject.toml +44 -0
flo_ai-0.0.6/PKG-INFO
ADDED
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: flo_ai
|
|
3
|
+
Version: 0.0.6
|
|
4
|
+
Summary: A easy way to create structured AI agents
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: rootflo
|
|
7
|
+
Author-email: *@rootflo.ai
|
|
8
|
+
Requires-Python: >=3.10,<4.0
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Requires-Dist: httpx (==0.27.0)
|
|
15
|
+
Requires-Dist: langchain (>=0.3.3,<4.0)
|
|
16
|
+
Requires-Dist: langchain-community (==0.3.2)
|
|
17
|
+
Requires-Dist: langgraph (==0.2.38)
|
|
18
|
+
Requires-Dist: pillow (>=10.3.0,<11.0.0)
|
|
19
|
+
Requires-Dist: pydantic (>=2.9.2,<3.0.0)
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
<p align="center">
|
|
23
|
+
<img src="./images/rootflo-logo.png" alt="Rootflo" width="150" />
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<h1 align="center">Composable AI Agentic Workflow</h1>
|
|
27
|
+
|
|
28
|
+
<p align="center">
|
|
29
|
+
Rootflo is an alternative to <b>Langgraph</b>, and <b>CrewAI</b>. It lets you easily build composable agentic workflows from using simple components to any size, unlocking the full potential of LLMs.
|
|
30
|
+
</p>
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
<a href="https://github.com/rootflo/flo-ai/stargazers"><img src="https://img.shields.io/github/stars/rootflo/flo-ai?style=for-the-badge" alt="GitHub stars"></a>
|
|
34
|
+
<a href="https://github.com/rootflo/flo-ai/releases">
|
|
35
|
+
<img src="https://img.shields.io/github/v/release/rootflo/flo-ai?display_name=release&style=for-the-badge" alt="GitHub release (latest)">
|
|
36
|
+
</a>
|
|
37
|
+
<a href="https://github.com/rootflo/flo-ai/graphs/commit-activity"><img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/m/rootflo/flo-ai/develop?style=for-the-badge">
|
|
38
|
+
</a>
|
|
39
|
+
<a href="https://github.com/rootflo/flo-ai/blob/develop/LICENSE"><img src="https://img.shields.io/github/license/rootflo/flo-ai?style=for-the-badge" alt="License">
|
|
40
|
+
</a>
|
|
41
|
+
<br/>
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<br/>
|
|
46
|
+
<a href="https://flo-ai.rootflo.ai" rel="" target="_blank"><strong>Checkout the docs »</strong></a>
|
|
47
|
+
<br/>
|
|
48
|
+
<br/>
|
|
49
|
+
<a href="https://github.com/rootflo/flo-ai">Github</a>
|
|
50
|
+
•
|
|
51
|
+
<a href="https://rootflo.ai" target="_blank">Website</a>
|
|
52
|
+
•
|
|
53
|
+
<a href="https://github.com/rootflo/flo-ai/blob/develop/ROADMAP.md" target="_blank">Roadmap</a>
|
|
54
|
+
</p>
|
|
55
|
+
|
|
56
|
+
<hr />
|
|
57
|
+
|
|
58
|
+
# Flo AI 🌊
|
|
59
|
+
|
|
60
|
+
> Build production-ready AI agents and teams with minimal code
|
|
61
|
+
|
|
62
|
+
Flo AI is a Python framework that makes building production-ready AI agents and teams as easy as writing YAML. Think "Kubernetes for AI Agents" - compose complex AI architectures using pre-built components while maintaining the flexibility to create your own.
|
|
63
|
+
|
|
64
|
+
## ✨ Features
|
|
65
|
+
|
|
66
|
+
- 🔌 **Truly Composable**: Build complex AI systems by combining smaller, reusable components
|
|
67
|
+
- 🏗️ **Production-Ready**: Built-in best practices and optimizations for production deployments
|
|
68
|
+
- 📝 **YAML-First**: Define your entire agent architecture in simple YAML
|
|
69
|
+
- 🔧 **Flexible**: Use pre-built components or create your own
|
|
70
|
+
- 🤝 **Team-Oriented**: Create and manage teams of AI agents working together
|
|
71
|
+
- 📚 **RAG Support**: Built-in support for Retrieval-Augmented Generation
|
|
72
|
+
- 🔄 **Langchain Compatible**: Works with all your favorite Langchain tools
|
|
73
|
+
|
|
74
|
+
## 🚀 Quick Start
|
|
75
|
+
|
|
76
|
+
FloAI follows an agent team architecture, where agents are the basic building blocks, and teams can have multiple agents and teams themselves can be part of bigger teams.
|
|
77
|
+
|
|
78
|
+
Building a working agent or team involves 3 steps:
|
|
79
|
+
1. Create a session using `FloSession`, and register your tools and models
|
|
80
|
+
2. Define you agent/team/team of teams using yaml or code
|
|
81
|
+
3. Build and run using `Flo`
|
|
82
|
+
|
|
83
|
+
### Installation
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install flo-ai
|
|
87
|
+
# or using poetry
|
|
88
|
+
poetry add flo-ai
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Create Your First AI Agent in 30 secs
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from flo_ai import Flo, FloSession
|
|
95
|
+
from langchain_openai import ChatOpenAI
|
|
96
|
+
from langchain_community.tools.tavily_search.tool import TavilySearchResults
|
|
97
|
+
|
|
98
|
+
# init your LLM
|
|
99
|
+
llm = ChatOpenAI(temperature=0)
|
|
100
|
+
|
|
101
|
+
# create a session and register your tools
|
|
102
|
+
session = FloSession(llm).register_tool(name="TavilySearchResults", tool=TavilySearchResults())
|
|
103
|
+
|
|
104
|
+
# define your agent yaml
|
|
105
|
+
simple_weather_checking_agent = """
|
|
106
|
+
apiVersion: flo/alpha-v1
|
|
107
|
+
kind: FloAgent
|
|
108
|
+
name: weather-assistant
|
|
109
|
+
agent:
|
|
110
|
+
name: WeatherAssistant
|
|
111
|
+
job: >
|
|
112
|
+
Given the city name you are capable of answering the latest whether this time of the year by searching the internet
|
|
113
|
+
tools:
|
|
114
|
+
- name: InternetSearchTool
|
|
115
|
+
"""
|
|
116
|
+
flo = Flo.build(session, yaml=simple_weather_checking_agent)
|
|
117
|
+
|
|
118
|
+
# Start streaming results
|
|
119
|
+
for response in flo.stream("Write about recent AI developments"):
|
|
120
|
+
print(response)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Lets create the same agent using code
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from flo_ai import FloAgent
|
|
127
|
+
|
|
128
|
+
session = FloSession(llm)
|
|
129
|
+
|
|
130
|
+
weather_agent = FloAgent.create(
|
|
131
|
+
session=session,
|
|
132
|
+
name="WeatherAssistant",
|
|
133
|
+
job="Given the city name you are capable of answering the latest whether this time of the year by searching the internet",
|
|
134
|
+
tools=[TavilySearchResults()]
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
agent_flo: Flo = Flo.create(session, weather_agent)
|
|
138
|
+
result = agent_flo.invoke("Whats the whether in New Delhi, India ?")
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Create Your First AI Team in 30 Seconds
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from flo_ai import Flo, FloSession
|
|
145
|
+
from langchain_openai import ChatOpenAI
|
|
146
|
+
from langchain_community.tools.tavily_search.tool import TavilySearchResults
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# Define your team in YAML
|
|
150
|
+
yaml_config = """
|
|
151
|
+
apiVersion: flo/alpha-v1
|
|
152
|
+
kind: FloRoutedTeam
|
|
153
|
+
name: research-team
|
|
154
|
+
team:
|
|
155
|
+
name: ResearchTeam
|
|
156
|
+
router:
|
|
157
|
+
name: TeamLead
|
|
158
|
+
kind: supervisor
|
|
159
|
+
agents:
|
|
160
|
+
- name: Researcher
|
|
161
|
+
role: Research Specialist
|
|
162
|
+
job: Research latest information on given topics
|
|
163
|
+
tools:
|
|
164
|
+
- name: TavilySearchResults
|
|
165
|
+
- name: Writer
|
|
166
|
+
role: Content Creator
|
|
167
|
+
job: Create engaging content from research
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
# Set up and run
|
|
171
|
+
llm = ChatOpenAI(temperature=0)
|
|
172
|
+
session = FloSession(llm).register_tool(name="TavilySearchResults", tool=TavilySearchResults())
|
|
173
|
+
flo = Flo.build(session, yaml=yaml_config)
|
|
174
|
+
|
|
175
|
+
# Start streaming results
|
|
176
|
+
for response in flo.stream("Write about recent AI developments"):
|
|
177
|
+
print(response)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Note:** You can make each of the above agents including the router to use different models, giving flexibility to combine the power of different LLMs.
|
|
181
|
+
To know more, check multi-model integration in detailed [documentation](https://flo-ai.rootflo.ai/advanced/model-switching)
|
|
182
|
+
|
|
183
|
+
### Lets Create a AI team using code
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
from flo_ai import FloSupervisor, FloAgent, FloSession, FloTeam, FloLinear
|
|
187
|
+
from langchain_openai import ChatOpenAI
|
|
188
|
+
from langchain_community.tools.tavily_search.tool import TavilySearchResults
|
|
189
|
+
|
|
190
|
+
llm = ChatOpenAI(temperature=0, model_name='gpt-4o')
|
|
191
|
+
session = FloSession(llm).register_tool(
|
|
192
|
+
name="TavilySearchResults",
|
|
193
|
+
tool=TavilySearchResults()
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
researcher = FloAgent.create(
|
|
197
|
+
session,
|
|
198
|
+
name="Researcher",
|
|
199
|
+
role="Internet Researcher", # optional
|
|
200
|
+
job="Do a research on the internet and find articles of relevent to the topic asked by the user",
|
|
201
|
+
tools=[TavilySearchResults()]
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
blogger = FloAgent.create(
|
|
205
|
+
session,
|
|
206
|
+
name="BlogWriter",
|
|
207
|
+
role="Thought Leader", # optional
|
|
208
|
+
job="Able to write a blog using information provided",
|
|
209
|
+
tools=[TavilySearchResults()]
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
marketing_team = FloTeam.create(session, "Marketing", [researcher, blogger])
|
|
213
|
+
head_of_marketing = FloSupervisor.create(session, "Head-of-Marketing", marketing_team)
|
|
214
|
+
marketing_flo = Flo.create(session, routed_team=head_of_marketing)
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Tools
|
|
219
|
+
|
|
220
|
+
FloAI supports all the tools built and available in `langchain_community` package. To know more these tools, go [here](https://python.langchain.com/docs/integrations/tools/).
|
|
221
|
+
|
|
222
|
+
Along with that FloAI has a decorator `@flotool` which makes any function into a tool.
|
|
223
|
+
|
|
224
|
+
Creating a simple tool using `@flotool`:
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
from flo_ai.tools import flotool
|
|
228
|
+
from pydantic import BaseModel, Field
|
|
229
|
+
|
|
230
|
+
# define argument schema
|
|
231
|
+
class AdditionToolInput(BaseModel):
|
|
232
|
+
numbers: List[int] = Field(..., description='List of numbers to add')
|
|
233
|
+
|
|
234
|
+
@flotool(name='AdditionTool', description='Tool to add numbers')
|
|
235
|
+
async def addition_tool(numbers: List[int]) -> str:
|
|
236
|
+
result = sum(numbers)
|
|
237
|
+
await asyncio.sleep(1)
|
|
238
|
+
return f'The sum is {result}'
|
|
239
|
+
|
|
240
|
+
# async tools can also be defined
|
|
241
|
+
# when using async tool, while running the flo use async invoke
|
|
242
|
+
@flotool(
|
|
243
|
+
name='MultiplicationTool',
|
|
244
|
+
description='Tool to multiply numbers to get product of numbers',
|
|
245
|
+
)
|
|
246
|
+
async def mul_tool(numbers: List[int]) -> str:
|
|
247
|
+
result = sum(numbers)
|
|
248
|
+
await asyncio.sleep(1)
|
|
249
|
+
return f'The product is {result}'
|
|
250
|
+
|
|
251
|
+
# register your tool or use directly in code impl
|
|
252
|
+
session.register_tool(name='Adder', tool=addition_tool)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Note:** `@flotool` comes with inherent error handling capabilities to retry if an exception is thrown. Use `unsafe=True` to disable error handling
|
|
256
|
+
|
|
257
|
+
## Output Parsing and formatting
|
|
258
|
+
|
|
259
|
+
FloAI now supports output parsing using JSON or YAML formatter. You can now defined your output formatter using `pydantic` and use the same in code or directly make it part of the Agent Definition Yaml (ADY)
|
|
260
|
+
|
|
261
|
+
### Using Agent Defintion YAML
|
|
262
|
+
|
|
263
|
+
We have added parser key to your agent schema, which gives you the output. The following is the schema of the parser
|
|
264
|
+
|
|
265
|
+
```yaml
|
|
266
|
+
name: SchemaName
|
|
267
|
+
fields:
|
|
268
|
+
- name: field_name
|
|
269
|
+
type: data_type
|
|
270
|
+
description: field_description
|
|
271
|
+
values: <optional(for literals, all possible values that can be taken)>
|
|
272
|
+
- value: <the value>
|
|
273
|
+
description: value_description
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Supported Field Types
|
|
277
|
+
|
|
278
|
+
#### Primitive Types
|
|
279
|
+
|
|
280
|
+
- str: String values
|
|
281
|
+
- int: Integer values
|
|
282
|
+
- bool: Boolean values
|
|
283
|
+
- float: Floating-point values
|
|
284
|
+
|
|
285
|
+
##### Complex Types
|
|
286
|
+
|
|
287
|
+
- array: Lists of items
|
|
288
|
+
- object: Nested objects
|
|
289
|
+
- literal: Enumerated values
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
Here an example of a simple summarization agent yaml that produces output a structured manner.
|
|
293
|
+
|
|
294
|
+
```yaml
|
|
295
|
+
apiVersion: flo/alpha-v1
|
|
296
|
+
kind: FloAgent
|
|
297
|
+
name: SummarizationFlo
|
|
298
|
+
agent:
|
|
299
|
+
name: SummaryAgent
|
|
300
|
+
kind: llm
|
|
301
|
+
role: Book summarizer agent
|
|
302
|
+
job: >
|
|
303
|
+
You are an given a paragraph from a book
|
|
304
|
+
and your job is to understand the information in it and extract summary
|
|
305
|
+
parser:
|
|
306
|
+
name: BookSummary
|
|
307
|
+
fields:
|
|
308
|
+
- name: long_summary
|
|
309
|
+
type: str
|
|
310
|
+
description: A comprehensive summary of the book, with all the major topics discussed
|
|
311
|
+
- name: short_summary
|
|
312
|
+
type: str
|
|
313
|
+
description: A short summary of the book in less than 20 words
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
As you can see here, the `parser` key makes sure that output of this agent will be the given key value format.
|
|
317
|
+
|
|
318
|
+
### Using parser with code
|
|
319
|
+
|
|
320
|
+
You can define parser as json in code and use it easily, here is an example:
|
|
321
|
+
|
|
322
|
+
```python
|
|
323
|
+
format = {
|
|
324
|
+
'name': 'NameFormat',
|
|
325
|
+
'fields': [
|
|
326
|
+
{
|
|
327
|
+
'type': 'str',
|
|
328
|
+
'description': 'The first name of the person',
|
|
329
|
+
'name': 'first_name',
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
'type': 'str',
|
|
333
|
+
'description': 'The middle name of the person',
|
|
334
|
+
'name': 'middle_name',
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
'type': 'literal',
|
|
338
|
+
'description': 'The last name of the person, the value can be either of Vishnu or Satis',
|
|
339
|
+
'name': 'last_name',
|
|
340
|
+
'values': [
|
|
341
|
+
{'value': 'Vishnu', 'description': 'If the first_name starts with K'},
|
|
342
|
+
{'value': 'Satis', 'description': 'If the first_name starts with M'},
|
|
343
|
+
],
|
|
344
|
+
'default_value_prompt': 'If none of the above value is suited, please use value other than the above in snake-case',
|
|
345
|
+
},
|
|
346
|
+
],
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
researcher = FloAgent.create(
|
|
350
|
+
session,
|
|
351
|
+
name='Researcher',
|
|
352
|
+
role='Internet Researcher',
|
|
353
|
+
job='What is the first name, last name and middle name of the the person user asks about',
|
|
354
|
+
tools=[TavilySearchResults()],
|
|
355
|
+
parser=FloJsonParser.create(json_dict=format)
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
Flo.set_log_level('DEBUG')
|
|
360
|
+
flo: Flo = Flo.create(session, researcher)
|
|
361
|
+
result = flo.invoke('Mahatma Gandhi')
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Output Data Collector
|
|
366
|
+
|
|
367
|
+
Output collector is an infrastructure that helps you collect outputs across multiple agents into single data structure. The most useful collector is a JSON output collector which when combined with output parser gives combined JSON outputs.
|
|
368
|
+
|
|
369
|
+
Usage:
|
|
370
|
+
```python
|
|
371
|
+
from flo_ai.state import FloJsonOutputCollector
|
|
372
|
+
|
|
373
|
+
dc = FloJsonOutputCollector()
|
|
374
|
+
|
|
375
|
+
# register your collector to the session
|
|
376
|
+
session = FloSession(llm).register_tool(
|
|
377
|
+
name='InternetSearchTool', tool=TavilySearchResults()
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
simple_reseacher = """
|
|
381
|
+
apiVersion: flo/alpha-v1
|
|
382
|
+
kind: FloAgent
|
|
383
|
+
name: weather-assistant
|
|
384
|
+
agent:
|
|
385
|
+
name: WeatherAssistant
|
|
386
|
+
kind: agentic
|
|
387
|
+
job: >
|
|
388
|
+
Given the person name, guess the first and last name
|
|
389
|
+
tools:
|
|
390
|
+
- name: InternetSearchTool
|
|
391
|
+
parser:
|
|
392
|
+
name: NameFormatter
|
|
393
|
+
fields:
|
|
394
|
+
- type: str
|
|
395
|
+
description: The first name of the person
|
|
396
|
+
name: first_name
|
|
397
|
+
- type: str
|
|
398
|
+
description: The first name of the person
|
|
399
|
+
name: last_name
|
|
400
|
+
- name: location
|
|
401
|
+
type: object
|
|
402
|
+
description: The details about birth location
|
|
403
|
+
fields:
|
|
404
|
+
- name: state
|
|
405
|
+
type: str
|
|
406
|
+
description: The Indian State in whihc the person was born
|
|
407
|
+
data_collector: kv
|
|
408
|
+
"""
|
|
409
|
+
|
|
410
|
+
flo: Flo = Flo.build(session, simple_reseacher)
|
|
411
|
+
result = flo.invoke('Gandhi')
|
|
412
|
+
|
|
413
|
+
# This will output the output as JSON. The idea is that you can use the same collector across multiple agents and teams to still get a combined JSON output.
|
|
414
|
+
print(dc.fetch())
|
|
415
|
+
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
## 📊 Tool Logging and Data Collection
|
|
419
|
+
|
|
420
|
+
FloAI provides built-in capabilities for logging tool calls and collecting data through the `FloExecutionLogger` and `DataCollector` classes, facilitating the creation of valuable training data.
|
|
421
|
+
You can customize `DataCollector` implementation according to your database. A sample implementation where logs are stored locally as JSON files is implemented in `JSONLFileCollector`.
|
|
422
|
+
|
|
423
|
+
### Quick Setup
|
|
424
|
+
|
|
425
|
+
```python
|
|
426
|
+
from flo_ai.callbacks import FloExecutionLogger
|
|
427
|
+
from flo_ai.storage.data_collector import JSONLFileCollector
|
|
428
|
+
|
|
429
|
+
# Initialize the file collector with a path for the JSONL log file to be stored
|
|
430
|
+
file_collector = JSONLFileCollector("'.logs'")
|
|
431
|
+
|
|
432
|
+
# Create a tool logger with the collector
|
|
433
|
+
local_tracker = FloExecutionLogger(file_collector)
|
|
434
|
+
|
|
435
|
+
# Register the logger with your session
|
|
436
|
+
session.register_callback(local_tracker)
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Features
|
|
440
|
+
|
|
441
|
+
- 📝 Logs all tool calls, chain executions, and agent actions
|
|
442
|
+
- 🕒 Includes timestamps for start and end of operations
|
|
443
|
+
- 🔍 Tracks inputs, outputs, and errors
|
|
444
|
+
- 💾 Stores data in JSONL format for easy analysis
|
|
445
|
+
- 📚 Facilitates the creation of training data from logged interactions
|
|
446
|
+
|
|
447
|
+
### Log Data Structure
|
|
448
|
+
|
|
449
|
+
The logger captures detailed information including:
|
|
450
|
+
- Tool name and inputs
|
|
451
|
+
- Execution timestamps
|
|
452
|
+
- Operation status (completed/error)
|
|
453
|
+
- Chain and agent activities
|
|
454
|
+
- Parent-child relationship between operations
|
|
455
|
+
|
|
456
|
+
### Training Data Generation
|
|
457
|
+
|
|
458
|
+
The structured logs provide valuable training data that can be used to:
|
|
459
|
+
- **Fine-tune LLMs** on your specific use cases
|
|
460
|
+
- **Train new models** to replicate successful tool usage patterns
|
|
461
|
+
- **Create supervised datasets** for tool selection and chain optimization
|
|
462
|
+
|
|
463
|
+
We have created a script to convert your logs to training data:
|
|
464
|
+
|
|
465
|
+
```python
|
|
466
|
+
python generate_training_data.py --logger-path PATH --tool-path PATH [--output PATH]
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Arguments:
|
|
470
|
+
- *logger-path*: Path to the logger file containing tool and chain entries, eg: .logs/logs/log.jsonl
|
|
471
|
+
- *tool-path*: Path to the tool descriptions file eg: eg: .logs/tools/tools.jsonl
|
|
472
|
+
- *output*: path to save the output eg: training-data.jsonl
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
## 📖 Documentation
|
|
476
|
+
|
|
477
|
+
Visit our [comprehensive documentation](https://flo-ai.rootflo.ai) for:
|
|
478
|
+
- Detailed tutorials
|
|
479
|
+
- Architecture deep-dives
|
|
480
|
+
- API reference
|
|
481
|
+
- Logging
|
|
482
|
+
- Error handling
|
|
483
|
+
- Observers
|
|
484
|
+
- Dynamic model switching
|
|
485
|
+
- Best practices
|
|
486
|
+
- Advanced examples
|
|
487
|
+
|
|
488
|
+
## 🌟 Why Flo AI?
|
|
489
|
+
|
|
490
|
+
### For AI Engineers
|
|
491
|
+
- **Faster Development**: Build complex AI systems in minutes, not days
|
|
492
|
+
- **Production Focus**: Built-in optimizations and best practices
|
|
493
|
+
- **Flexibility**: Use our components or build your own
|
|
494
|
+
|
|
495
|
+
### For Teams
|
|
496
|
+
- **Maintainable**: YAML-first approach makes systems easy to understand and modify
|
|
497
|
+
- **Scalable**: From single agents to complex team hierarchies
|
|
498
|
+
- **Testable**: Each component can be tested independently
|
|
499
|
+
|
|
500
|
+
## 🎯 Use Cases
|
|
501
|
+
|
|
502
|
+
- 🤖 Customer Service Automation
|
|
503
|
+
- 📊 Data Analysis Pipelines
|
|
504
|
+
- 📝 Content Generation
|
|
505
|
+
- 🔍 Research Automation
|
|
506
|
+
- 🎯 Task-Specific AI Teams
|
|
507
|
+
|
|
508
|
+
## 🤝 Contributing
|
|
509
|
+
|
|
510
|
+
We love your input! Check out our [Contributing Guide](CONTRIBUTING.md) to get started. Ways to contribute:
|
|
511
|
+
|
|
512
|
+
- 🐛 Report bugs
|
|
513
|
+
- 💡 Propose new features
|
|
514
|
+
- 📝 Improve documentation
|
|
515
|
+
- 🔧 Submit PRs
|
|
516
|
+
|
|
517
|
+
## 📜 License
|
|
518
|
+
|
|
519
|
+
Flo AI is [MIT Licensed](LICENSE).
|
|
520
|
+
|
|
521
|
+
## 🙏 Acknowledgments
|
|
522
|
+
|
|
523
|
+
Built with ❤️ using:
|
|
524
|
+
- [LangChain](https://github.com/hwchase17/langchain)
|
|
525
|
+
- [LangGraph](https://github.com/langchain-ai/langgraph)
|
|
526
|
+
|
|
527
|
+
<h2>📚 Latest Blog Posts</h2>
|
|
528
|
+
|
|
529
|
+
<div style="display: flex; gap: 10px;">
|
|
530
|
+
<a href="https://medium.com/rootflo/flo-simple-way-to-create-composable-ai-agents-6946c2922a94" target="_blank" style="text-decoration: none;">
|
|
531
|
+
<img src="./images/blog-image.png" width="150" style="border-radius: 10px;" />
|
|
532
|
+
<p><b>Flo: 🔥🔥🔥 Simple way to create composable AI agents</b><br />Unlock the Power of Customizable AI Workflows with FloAI’s Intuitive and Flexible Agentic Framework</p>
|
|
533
|
+
</a>
|
|
534
|
+
<a href="https://medium.com/rootflo/build-an-agentic-ai-customer-support-bot-using-floai-533660fb9c9b" target="_blank" style="text-decoration: none;">
|
|
535
|
+
<img src="./images/customer-support.png" width="150" style="border-radius: 10px;" />
|
|
536
|
+
<p><b>Build an Agentic AI customer support bot using FloAI</b><br />We built an open-source agentic AI workflow builder named FloAI and used it to create an agentic customer support agent.</p>
|
|
537
|
+
</a>
|
|
538
|
+
<a href="https://medium.com/rootflo/build-an-agentic-rag-using-floai-in-minutes-0be260304c98" target="_blank" style="text-decoration: none;">
|
|
539
|
+
<img src="./examples/images/agentic-rag.png" width="150" style="border-radius: 10px;" />
|
|
540
|
+
<p><b>Build an Agentic RAG using FloAI in minutes</b><br />FloAI has just made implementing agentic RAG simple and easy to manage</p>
|
|
541
|
+
</a>
|
|
542
|
+
</div>
|
|
543
|
+
<a href="https://medium.com/rootflo/mastering-ai-interaction-logging-and-data-collection-with-floai-a490818bb2f1" target="_blank" style="text-decoration: none;">
|
|
544
|
+
<img src="./images/blog-image.png" width="150" style="border-radius: 10px;" />
|
|
545
|
+
<p><b>Mastering AI Interaction Logging and Data Collection with FloAI</b><br />Learn how to leverage FloAI's powerful logging system for debugging, training data generation, and system optimization</p>
|
|
546
|
+
</a>
|
|
547
|
+
</a>
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
<div align="center">
|
|
551
|
+
<strong>Built with ❤️ by the <a href="http://rootflo.ai">rootflo</a> team</strong>
|
|
552
|
+
<br><a href="https://github.com/rootflo/flo-ai/discussions">Community</a> •
|
|
553
|
+
<a href="https://flo-ai.rootflo.ai">Documentation</a>
|
|
554
|
+
</div>
|
|
555
|
+
|