| name | agents |
| description | AgentExecutor, ChatAgent (ReAct), OpenAIToolsAgent, and the Agent trait. |
AgentExecutor runs the tool-use loop. Two agent types: OpenAIToolsAgent (function calling,
preferred) and ChatAgent (ReAct text parsing). Both implement Agent and are wrapped in
AgentExecutor::from_agent().
## Agent Trait
#[async_trait]
pub trait Agent: Send + Sync {
async fn plan(
&self,
intermediate_steps: &[(AgentAction, String)],
inputs: PromptArgs,
) -> Result<AgentEvent, AgentError>;
fn get_tools(&self) -> Vec<Arc<dyn Tool>>;
}
AgentEvent is either Action(Vec<AgentAction>) or Finish(AgentFinish). The executor
calls plan() in a loop until Finish or max_iterations.
## OpenAIToolsAgent (recommended)
Uses OpenAI function-calling API. More reliable than ReAct text parsing.
use std::sync::Arc;
use langchainx::{
agent::{AgentExecutor, OpenAIToolsAgentBuilder},
chain::Chain,
llm::openai::OpenAI,
memory::SimpleMemory,
prompt_args,
tools::Tool,
};
let tools: Vec<Arc<dyn Tool>> = vec![Arc::new(MyTool)];
let agent = OpenAIToolsAgentBuilder::new()
.tools(&tools)
.llm(OpenAI::default())
.build()?;
let executor = AgentExecutor::from_agent(agent)
.with_max_iterations(10)
.with_memory(SimpleMemory::new().into())
.with_break_if_error(false);
let result = executor.invoke(prompt_args! {
"input" => "How many words are in 'hello world'?",
}).await?;
println!("{result}");
## ChatAgent (ReAct)
Uses text-based ReAct reasoning. Works with any LLM but is less reliable than function calling.
use langchainx::agent::{AgentExecutor, ChatAgentBuilder};
let agent = ChatAgentBuilder::new()
.tools(&tools)
.llm(OpenAI::default())
.build()?;
let executor = AgentExecutor::from_agent(agent)
.with_max_iterations(10);
## AgentExecutor Options
AgentExecutor::from_agent(agent)
.with_max_iterations(10)
.with_memory(mem.into())
.with_break_if_error(true)
When max_iterations is reached, the executor returns Ok(GenerateResult) with
generation = "Max iterations reached" — not an error.
## Memory in AgentExecutor
When memory is set, the executor:
- Injects
chat_history into input_variables before each plan() call
- On
Finish, saves user input, tool call messages, and AI response to memory
The required input key is "input" (hardcoded in executor).
let executor = AgentExecutor::from_agent(agent)
.with_memory(SimpleMemory::new().into());
executor.invoke(prompt_args! { "input" => "My name is Alice" }).await?;
executor.invoke(prompt_args! { "input" => "What is my name?" }).await?;