I am excited to play around with Controlflow but h...
# marvin-ai
b
I am excited to play around with Controlflow but have a question based on my (very brief) quick scan of the docs. Over the summer, I had a project where I built out a flow that allowed users to upload files and ask questions, compare, whatever. For this, I used the Assistants API from OpenAI to handle threads, files, whatever. The project was setup to be very modular, in that conversation threads were created, conditionally files were handled, and then assistants invoked. It was clumsy but worked. I want to use that project to frame out my learning in Controlflow, but it's not obvious to me how it would to wire that in given some "tasks" are for API calls and not actually invoking an LLM. I am sure I am missing something obvious, but any references to docs or nudges would be greatly appreicated.
j
Hey @Brock! If I'm understanding correctly, one of the cool things here is you can mix normal Python calls and control flow tasks just like a regular script:
Copy code
import controlflow as cf


agent = cf.Agent(name='My Agent')

@cf.flow
def do_stuff(files: list[str]):
    
    file_contents = []
    for file in files:
        file_contents.append(open(file).read())
        
    return cf.run(
        "analyze the file contents",
        agent=agent,
        context=dict(file_contents=file_contents)
    )
However you just made me realize that we don't have clear docs on thread management with the
@cf.flow
decorator, only the flow context manager, which is an important oversight especially if you're thinking of threads the way the Assistants API works
Generally speaking, I think for your use case: • define a "flow" function. The
flow
indicates that all CF
tasks
in that function will be run in the same thread. You can provide a thread ID to a flow when you call it in order to load history from any previous flows run with that same thread ID • inside the flow function, run whatever Python you want, including creating and running controlflow tasks. Each controlflow task delegates to an LLM agent, and asks it to use tools and available context to complete the task. The LLM make take many steps to complete the task (e.g. it may use 3 tools in a row), similar to how the Assistants API may take many steps to complete a "run"
Happy to answer any more specific questions you have!
b
This is very thorough and thank you for the quick reply. Because I was using the Assistants API, I was actually using their files API to get ids and attach those ids to a thread run. My question: instead of separating the python logic as you did above, is it possible to have the concept of handling files act as a
@task
in the pipeline? Also, as I am typing this, a separate question would be if its fair to say that the task in controlflow is intended to invoke a "chat completion" like response from an LLM. As opposed to say, invoking the run of a thread on OpenAI which is directionally similar but have different pathways for managing the prompt and other info (tools, files, etc.). I fully admit my brain my be locked into my old approach and the steps of the Assistants API, and that may be hindering my review of controlflow, but that is the framing for my questions.
j
Ok I think I understand where to focus -- • ControlFlow doesn't have an analogue of the Assistant API's built-in file storage system or file search, but you can mimic it closely. • A controlflow
Task
is actually much closer to a "run" of an Assistants API thread than a chat completion in that when you call
cf.run()
or
Task.run()
your agent may take multiple actions, use multiple tools, etc. before it marks the task as complete. A task is sort of like a more structured version of kicking off an assistants API run. Unlike the assistants API, you can provide tools and context on a per-task basis instead of on a per-agent basis (though you can also give an agent tools!) • To supply tools to a task:
Copy code
cf.Task( # or cf.run to run immediatley
    ...,
    tools=[pythonfn_1, python_fn_2, ...]
)
• To supply information to a task:
Copy code
cf.Task( # or cf.run to run immediatley
    ...,
    context=dict(
        foo="foo",
        bar="bar",    
)
• So you can use
tools
to let the agent interface with a system by caling an arbitrary function; and you can use
context
to supply information directly to the agent. • So to mimic the file API for assistants, you have two approaches: ◦ in normal python, load the files, extract relevant parts by any means you prefer, then provide them to your agent as context. This has the advantage of being straightforward and simple, but it makes it more complicated to let your agent decide what to look for in the files ◦ write a python function that takes a query string and searches the files, returning any relevant data. provide that function to your agent or to the task. Now the agent can decide to use that function if relevant, which is very similar to the assistants API's behavior
So that's probably more text than you cared for, but the more tldr response to your question is: • create tools for reading/querying your files, and assign those tools to your task or agent. This will let your agent interact with files just like in the assistants API • HOWEVER controlflow doesn't have a builtin API for that, you can use any RAG library you prefer
hattip 1
b
Thank you! This is great context to have as I dive in. I appreciate it.