-
Notifications
You must be signed in to change notification settings - Fork 79
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
Agent support #727
base: dev
Are you sure you want to change the base?
Agent support #727
Conversation
Key Features: Base Agent Infrastructure Introduces a flexible BaseAgent class that all agents inherit from Implements tool management and conversation history tracking Provides abstract methods for custom agent implementations Built-in Agents: a) ReAct Agent Implements the Reasoning + Acting pattern Follows a structured process: Reason → Act → Observe → Respond Excels at complex tasks requiring tool use and step-by-step thinking Maximum 5 steps to prevent infinite loops b) Chain of Thought (CoT) Agent Specializes in breaking down complex problems into logical steps Shows explicit reasoning process for each step Focuses on transparent decision-making Ideal for math, logic, and analysis tasks c) Tool-Using Agent Optimized for scenarios requiring multiple tool interactions Analyzes available tools and plans usage sequence Executes tools and processes results Built-in error handling for missing tools Custom Agent Framework Allows creation of specialized agents with custom behaviors Configurable system prompts and extraction patterns Adjustable maximum steps and tool usage Flexible pattern matching for different response formats Shared Components: Tool class for defining and executing custom tools AgentOutput class for standardized response formatting Conversation history tracking Consistent error handling ``` from writer.agents import ReActAgent, Tool # Create a tool calculator = Tool( name="calculator", description="Performs basic math operations", func=lambda x, y, op: eval(f"{x}{op}{y}") ) # Initialize agent agent = ReActAgent(tools=[calculator]) # Run agent result = agent.run("What is 25 * 48?") # Access structured output print(result.response) # Final answer print(result.reasoning) # List of reasoning steps print(result.actions) # List of tools used ```
@mmikita95 Mikita, can you please take a look and see how this relates to AI module? I'm seeing clear duplication in things like |
from abc import ABC, abstractmethod | ||
import re | ||
from typing import Any, Dict, List, Optional, Union | ||
from enum import Enum |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Output of ruff check:
agents.py:3:47: F401 [*] `typing.Union` imported but unused
|
1 | from abc import ABC, abstractmethod
2 | import re
3 | from typing import Any, Dict, List, Optional, Union
| ^^^^^ F401
4 | from enum import Enum
5 | import json
|
= help: Remove unused import: `typing.Union`
agents.py:4:18: F401 [*] `enum.Enum` imported but unused
|
2 | import re
3 | from typing import Any, Dict, List, Optional, Union
4 | from enum import Enum
| ^^^^ F401
5 | import json
|
= help: Remove unused import: `enum.Enum`
]) | ||
|
||
response = None | ||
max_steps = 5 # Prevent infinite loops |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both system prompt
and max_steps
should not be hardcoded.
The prompt needs to be refined, I see next regex failing a lot:
match = re.search(r"Reason:(.+?)(?=Action:|Response:|$)", text, re.DOTALL)
I did not guess from the prompt what is the expected format, the model will struggle with this too.
|
||
for _ in range(max_steps): | ||
# Get next action from AI | ||
action_response = self._get_llm_response(messages) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No error handling.
# Execute tool if specified | ||
if action.get("tool"): | ||
tool_result = self._execute_tool(action["tool"], action.get("args", {})) | ||
messages.append({"role": "system", "content": f"Observation: {tool_result}"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot be a "system" message. Our models don't support multiple system messages shuffled in.
We can make it into an "assistant" message and merge all assistant messages at the end.
return f"Tool '{tool_name}' not found" | ||
return tool.run(**args) | ||
|
||
class ChainOfThoughtAgent(BaseAgent): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ChainOfThoughtAgent
does not use tools, but it extends BaseAgent class with has tools and tools executions. That is confusing.
self.reasoning = reasoning | ||
self.actions = actions | ||
|
||
class Tool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
class Tool
should have a serialisation method.
The standard format looks like this:
tools = [
{
"type": "function",
"function": {
"name": "calculate_mean",
"description": "Calculate the mean (average) of a list of numbers.",
"parameters": {
"type": "object",
"properties": {
"numbers": {
"type": "array",
"items": {"type": "number"},
"description": "List of numbers"
}
},
"required": ["numbers"]
}
}
}
]
def __init__(self, name: str, description: str, func: callable): | ||
self.name = name | ||
self.description = description | ||
self.func = func |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing properties: self.parameters
and self.type
"""Run the agent with the given prompt""" | ||
pass | ||
|
||
def add_tool(self, tool: Tool): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like BaseAgent
should not have tools. We have ToolUsingAgent
for this.
ChainIfThoughAgent
extends BaseAgents and it does not use tools.
3. Observation: Consider the results | ||
4. Response: Provide final answer based on observations | ||
|
||
{self._format_tool_descriptions()} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think tool description is already handled in Writer sdk tool calling:
response = client.chat.chat(
model="palmyra-x-004",
messages=messages,
tools=tools,
tool_choice="auto",
stream=False # Set to True if you want to use streaming
)
Key Features:
Base Agent Infrastructure
Introduces a flexible BaseAgent class that all agents inherit from Implements tool management and conversation history tracking Provides abstract methods for custom agent implementations
Built-in Agents:
a) ReAct Agent
Implements the Reasoning + Acting pattern
Follows a structured process: Reason → Act → Observe → Respond Excels at complex tasks requiring tool use and step-by-step thinking Maximum 5 steps to prevent infinite loops
b) Chain of Thought (CoT) Agent
Specializes in breaking down complex problems into logical steps Shows explicit reasoning process for each step
Focuses on transparent decision-making
Ideal for math, logic, and analysis tasks
c) Tool-Using Agent
Optimized for scenarios requiring multiple tool interactions Analyzes available tools and plans usage sequence
Executes tools and processes results
Built-in error handling for missing tools
Custom Agent Framework
Allows creation of specialized agents with custom behaviors Configurable system prompts and extraction patterns Adjustable maximum steps and tool usage
Flexible pattern matching for different response formats
Shared Components:
Tool class for defining and executing custom tools AgentOutput class for standardized response formatting Conversation history tracking
Consistent error handling