Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decorator for more easily implementing common agent flows (e.g. ReAct) #731

Open
willbakst opened this issue Dec 4, 2024 · 3 comments
Open
Labels
enhancement New feature or request mirascope

Comments

@willbakst
Copy link
Contributor

Description

partially sparked from the discussion in #709

The original goal for Mirascope was to provide a single-order abstraction on top of LLM APIs to provide a more consistent interface across providers. We're continuing to improve this with new features, and we're actively working towards making the interface even more provider-agnostic (see #729).

I firmly believe Mirascope should remain a lightweight toolkit (rather than trying to do everything), but I also see value in implementing second-order abstractions on top of our call decorators to make it easier to implement common flows. Since we already have mirascope.core, this won't remove the lower-level control we often want when implementing more complex flows. Instead, we'll implement separate functionality that (optionally) operates on top of the existing functionality.

Here is my rough thought:

from mirascope.core import Messages
from mirascope.agents import agent


@agent.react("openai:gpt-4o-mini", tools=[...])
def customer_support_bot(query: str) -> Messages.Type:
    return [
        Messages.System("You are a customer support bot"),
        Messages.User(query),
    ]


response = customer_support_bot("I need help with my recent bill")
print(response.content)  # agent's final string response
print(response.messages)  # the full history of messages that went into producing the response

The idea here would be that the @agent.react decorator operates just like the llm.call decorator would except that under-the-hood it will run through the ReAct tool calling flow and call the tools on behalf of the user. Everything else should work the same (including things like response_model, structured streaming, dynamic configuration, etc.).

Alternatively, we could create an Agent class and have the @agent.react decorator return an Agent instance (thus operating as shorthand). For example:

from mirascope.agents import Agent

agent = Agent(...)

@agent.tool()
def tool(...) -> ...: ...

@agent.system_prompt()
def system_prompt(...) -> str: ...

Then, the above customer_support_bot definition would instead be an Agent class (rather than a function), and we could call it moreso like customer_support_bot.run(...).

Biggest thing to think through will be how to best write the prompt such that you can make multiple sequential calls to the agent while injecting history. My thinking here is that is that we'll do something like always inject history into the array of messages right before the final user message and always ahead of the system message, and the resulting decorated method (i.e. customer_support_bot) would accept a keyword argument (e.g. history or messages) for the running history.

One benefit of the Agent class is that it enables more internal state management of the message history. The downside of this approach if not done correctly would be removing too much user control. We'll have to strike the right balance between what Mirascope handles and what the user handles (or some version of overriding so that the user can optionally take back control when desired/necessary).

This feature request is very early and definitely requires additional thought, so any and all feedback is welcome here.

@willbakst willbakst added the enhancement New feature or request label Dec 4, 2024
@minhquan23102000
Copy link

Could we use MCP to standardize context handling for agents? If so, Mirascope could be the first framework to implement it. By providing a set of community-supported context protocols, MCP would accelerate agent development by eliminating the need to re-implement common functionalities like:

  • Environment interaction (database access, tool usage)
  • Short-term and long-term memory management

This would allow developers to focus on building the agent's core logic instead of repeatedly building the same context management infrastructure. What do you think?

@willbakst
Copy link
Contributor Author

We're currently working on adding support for MCP. We have the server side implemented but still need to iron out the details on the client side. Once we figure that out, we should be able to hook the MCP client up to Mirascope calls, so hooking it up to an agent as described here should be possible.

I really like the idea of standardization on context, and MCP seems like the perfect fit for that.

@willbakst
Copy link
Contributor Author

@minhquan23102000 we just released MCP support in v1.12, would love to know your thoughts. I think the way we've implemented it should make it easy to hook the client up to an llm call (or new agent decorator as described in this issue) to easily provide tools/resources etc. through a common interface for all providers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request mirascope
Projects
None yet
Development

No branches or pull requests

2 participants