# <img src="https://raw.githubusercontent.com/vectara/py-vectara-agentic/main/.github/assets/Vectara-logo.png" alt="Vectara Logo" width="30" height="30" style="vertical-align: middle;"> vectara-agentic
<p align="center">
<a href="https://vectara.github.io/py-vectara-agentic">Documentation</a> ·
<a href="#example-ai-assistants">Examples</a> ·
<a href="https://discord.gg/S9dwgCNEFs">Discord</a>
</p>
<p align="center">
<a href="https://opensource.org/licenses/Apache-2.0">
<img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License">
</a>
<a href="https://github.com/vectara/py-vectara-agentic/graphs/commit-activity">
<img src="https://img.shields.io/badge/Maintained%3F-yes-green.svg" alt="Maintained">
</a>
<a href="https://twitter.com/vectara">
<img src="https://img.shields.io/twitter/follow/vectara.svg?style=social&label=Follow%20%40Vectara" alt="Twitter">
</a>
<a href="https://pypi.org/project/vectara-agentic/">
<img src="https://img.shields.io/pypi/v/vectara-agentic.svg" alt="PyPI version">
</a>
<a href="https://pypi.org/project/vectara-agentic/">
<img src="https://img.shields.io/pypi/pyversions/vectara-agentic.svg" alt="Python versions">
</a>
</p>
## 📑 Table of Contents
- [Overview](#-overview)
- [Quick Start](#-quick-start)
- [Using Tools](#using-tools)
- [Advanced Usage: Workflows](#advanced-usage-workflows)
- [Configuration](#️-configuration)
- [Contributing](#-contributing)
- [License](#-license)
## ✨ Overview
`vectara-agentic` is a Python library for developing powerful AI assistants and agents using Vectara and Agentic-RAG. It leverages the LlamaIndex Agent framework and provides helper functions to quickly create tools that connect to Vectara corpora.
<p align="center">
<img src="https://raw.githubusercontent.com/vectara/py-vectara-agentic/main/.github/assets/diagram1.png" alt="Agentic RAG diagram" width="100%" style="vertical-align: middle;">
</p>
### Key Features
- **Rapid Tool Creation:**
Build Vectara RAG tools or search tools with a single line of code.
- **Agent Flexibility:**
Supports multiple agent types including `ReAct`, `OpenAIAgent`, `LATS`, and `LLMCompiler`.
- **Pre-Built Domain Tools:**
Tools tailored for finance, legal, and other verticals.
- **Multi-LLM Integration:**
Seamless integration with OpenAI, Anthropic, Gemini, GROQ, Together.AI, Cohere, Bedrock, and Fireworks.
- **Observability:**
Built-in support with Arize Phoenix for monitoring and feedback.
- **Workflow Support:**
Extend your agent's capabilities by defining custom workflows using the `run()` method.
### Example AI Assistants
Check out our example AI assistants:
- [Financial Assistant](https://huggingface.co/spaces/vectara/finance-chat)
- [Justice Harvard Teaching Assistant](https://huggingface.co/spaces/vectara/Justice-Harvard)
- [Legal Assistant](https://huggingface.co/spaces/vectara/legal-agent)
- [EV Assistant](https://huggingface.co/spaces/vectara/ev-assistant)
### Prerequisites
- [Vectara account](https://console.vectara.com/signup/?utm_source=github&utm_medium=code&utm_term=DevRel&utm_content=vectara-agentic&utm_campaign=github-code-DevRel-vectara-agentic)
- A Vectara corpus with an [API key](https://docs.vectara.com/docs/api-keys)
- [Python 3.10 or higher](https://www.python.org/downloads/)
- OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Cohere, GEMINI or GROQ, if you choose to use them).
To use AWS Bedrock, make sure that
* The Bedrock models you need are enabled on your account
* Your environment includes `AWS_PROFILE` with your AWS profile name.
* Your environment includes `AWS_REGION` set to the region where you want to consume the AWS Bedrock services (defaults to us-east-2)
### Installation
```bash
pip install vectara-agentic
```
## 🚀 Quick Start
Let's see how we create a simple AI assistant to answer questions about financial data ingested into Vectara, using `vectara-agentic`.
### 1. Initialize the Vectara tool factory
```python
import os
from vectara_agentic.tools import VectaraToolFactory
vec_factory = VectaraToolFactory(
vectara_api_key=os.environ['VECTARA_API_KEY'],
vectara_corpus_key=os.environ['VECTARA_CORPUS_KEY']
)
```
### 2. Create a Vectara RAG Tool
A RAG tool calls the full Vectara RAG pipeline to provide summarized responses to queries grounded in data. We define two additional arguments (`year` and `ticker` that map to filter attributes in the Vectara corpus):
```python
from pydantic import BaseModel, Field
years = list(range(2020, 2024))
tickers = {
"AAPL": "Apple Computer",
"GOOG": "Google",
"AMZN": "Amazon",
"SNOW": "Snowflake",
}
class QueryFinancialReportsArgs(BaseModel):
year: int | str = Field(..., description=f"The year this query relates to. An integer between {min(years)} and {max(years)} or a string specifying a condition on the year (example: '>2020').")
ticker: str = Field(..., description=f"The company ticker. Must be a valid ticket symbol from the list {tickers.keys()}.")
ask_finance = vec_factory.create_rag_tool(
tool_name="query_financial_reports",
tool_description="Query financial reports for a company and year",
tool_args_schema=QueryFinancialReportsArgs,
lambda_val=0.005,
summary_num_results=7,
# Additional Vectara query arguments...
)
```
> **Note:** We only defined the `year` and `ticker` arguments in the QueryFinancialReportsArgs model. The `query` argument is automatically added by `create_rag_tool`.
To learn about additional arguments `create_rag_tool`, please see the full [docs](https://vectara.github.io/py-vectara-agentic/latest/).
### 3. Create other tools (optional)
In addition to RAG tools or search tools, you can generate additional tools the agent can use. These could be mathematical tools, tools
that call other APIs to get more information, or any other type of tool.
See [Agent Tools](#️-agent-tools-at-a-glance) for more information.
### 4. Create your agent
Here is how we will instantiate our AI Finance Assistant. First define your custom instructions:
```python
financial_assistant_instructions = """
- You are a helpful financial assistant, with expertise in financial reporting, in conversation with a user.
- Never discuss politics, and always respond politely.
- Respond in a compact format by using appropriate units of measure (e.g., K for thousands, M for millions, B for billions).
- Do not report the same number twice (e.g. $100K and 100,000 USD).
- Always check the get_company_info and get_valid_years tools to validate company and year are valid.
- When querying a tool for a numeric value or KPI, use a concise and non-ambiguous description of what you are looking for.
- If you calculate a metric, make sure you have all the necessary information to complete the calculation. Don't guess.
"""
```
Then just instantiate the `Agent` class:
```python
from vectara_agentic import Agent
agent = Agent(
tools =
[ask_finance],
topic="10-K annual financial reports",
custom_instructions=financial_assistant_instructions,
agent_progress_callback=agent_progress_callback
)
```
The `topic` parameter helps identify the agent's area of expertise, while `custom_instructions` lets you customize how the agent behaves and presents information. The agent will combine these with its default general instructions to determine its complete behavior.
The `agent_progress_callback` argument is an optional function that will be called when various Agent events occur, and can be used to track agent steps.
### 5. Run a chat interaction
```python
res = agent.chat("What was the revenue for Apple in 2021?")
print(res.response)
```
> **Note:**
> 1. `vectara-agentic` also supports `achat()` as well as two streaming variants `stream_chat()` and `astream_chat()`.
> 2. The response types from `chat()` and `achat()` are of type `AgentResponse`. If you just need the actual string
> response it's available as the `response` variable, or just use `str()`. For advanced use-cases you can look
> at other `AgentResponse` variables [such as `sources`](https://github.com/run-llama/llama_index/blob/659f9faaafbecebb6e6c65f42143c0bf19274a37/llama-index-core/llama_index/core/chat_engine/types.py#L53).
## Agent Instructions
When creating an agent, it already comes with a set of general base instructions, designed carefully to enhance its operation and improve how the agent works.
In addition, you can add `custom_instructions` that are specific to your use case that customize how the agent behaves.
When writing custom instructions:
- Focus on behavior and presentation rather than tool usage (that's what tool descriptions are for)
- Be precise and clear without overcomplicating
- Consider edge cases and unusual scenarios
- Avoid over-specifying behavior based on primary use cases
- Keep instructions focused on how you want the agent to behave and present information
The agent will combine both the general instructions and your custom instructions to determine its behavior.
It is not recommended to change the general instructions, but it is possible as well to override them with the optional `general_instructions` parameter. If you do change them, your agent may not work as intended, so be careful if overriding these instructions.
## 🧰 Defining Tools
### Vectara tools
`vectara-agentic` provides two helper functions to connect with Vectara RAG:
* `create_rag_tool()` to create an agent tool that connects with a Vectara corpus for querying.
* `create_search_tool()` to create a tool to search a Vectara corpus and return a list of matching documents.
See the documentation for the full list of arguments for `create_rag_tool()` and `create_search_tool()`,
to understand how to configure Vectara query performed by those tools.
#### Creating a Vectara RAG tool
A Vectara RAG tool is often the main workhorse for any Agentic RAG application, and enables the agent to query
one or more Vectara RAG corpora.
The tool generated always includes the `query` argument, followed by 1 or more optional arguments used for
metadata filtering, defined by `tool_args_schema`.
For example, in the quickstart example the schema is:
```python
class QueryFinancialReportsArgs(BaseModel):
year: int | str = Field(..., description=f"The year this query relates to. An integer between {min(years)} and {max(years)} or a string specifying a condition on the year (example: '>2020').")
ticker: str = Field(..., description=f"The company ticker. Must be a valid ticket symbol from the list {tickers.keys()}.")
```
Remember, the `query` argument is part of the rag_tool that is generated, but `vectara-agentic` creates it and you do
not need to specify it explicitly.
For example, in the example above, the agent may call the `query_financial_reports_tool` tool with
query='what is the revenue?', year=2022 and ticker='AAPL'. Subsequently the RAG tool will issue
a Vectara RAG query with the same query, but with metadata filtering (doc.year=2022 and doc.ticker='AAPL').
There are also additional cool features supported here:
* An argument can be a condition, for example year='>2022' translates to the correct metadata
filtering condition doc.year>2022
* if `fixed_filter` is defined in the RAG tool, it provides a constant metadata filtering that is always applied.
For example, if fixed_filter=`doc.filing_type='10K'` then a query with query='what is the reveue', year=2022
and ticker='AAPL' would translate into query='what is the revenue' with metadata filtering condition of
"doc.year=2022 AND doc.ticker='AAPL' and doc.filing_type='10K'"
Note that `tool_args_type` is an optional dictionary that indicates:
* `type`: the level at which metadata filtering is applied for each argument (`doc` or `part`)
* `is_list`: whether the argument is a list type
* `filter_name`: a filter name (in cases where variable name can't be used, e.g. with spaces) to be used
instead of the variable name.
#### Creating a Vectara search tool
The Vectara search tool allows the agent to list documents that match a query.
This can be helpful to the agent to answer queries like "how many documents discuss the iPhone?" or other
similar queries that require a response in terms of a list of matching documents.
### 🛠️ Agent Tools at a Glance
`vectara-agentic` provides a few tools out of the box (see `ToolsCatalog` for details):
**1. Standard tools**
- `summarize_text`: a tool to summarize a long text into a shorter summary (uses LLM)
- `rephrase_text`: a tool to rephrase a given text, given a set of rephrase instructions (uses LLM)
These tools use an LLM and so would use the `Tools` LLM specified in your `AgentConfig`.
To instantiate them:
```python
from vectara_agentic.tools_catalog import ToolsCatalog
summarize_text = ToolsCatalog(agent_config).summarize_text
```
This ensures the summarize_text tool is configured with the proper LLM provider and model as
specified in the Agent configuration.
**2. Legal tools**
A set of tools for the legal vertical, such as:
- `summarize_legal_text`: summarize legal text with a certain point of view
- `critique_as_judge`: critique a legal text as a judge, providing their perspective
**3. Financial tools**
Based on tools from Yahoo! Finance:
- tools to understand the financials of a public company like: `balance_sheet`, `income_statement`, `cash_flow`
- `stock_news`: provides news about a company
- `stock_analyst_recommendations`: provides stock analyst recommendations for a company.
**4. Database tools**
Providing tools to inspect and query a database:
- `list_tables`: list all tables in the database
- `describe_tables`: describe the schema of tables in the database
- `load_data`: returns data based on a SQL query
- `load_sample_data`: returns the first 25 rows of a table
- `load_unique_values`: returns the top unique values for a given column
**5. Additional integrations**
vectara-agentic includes various other tools from LlamaIndex ToolSpecs:
* **Search Tools**
* Tavily Search: Real-time web search using [Tavily API](https://tavily.com/)
```python
from vectara_agentic.tools_catalog import ToolsCatalog
tools_factory = ToolsFactory()
tavily_tools = tools_factory.get_llama_index_tools(
tool_package_name="tavily_research",
tool_spec_name="TavilyToolSpec",
api_key=str(os.environ["TAVILY_API_KEY"]),
)
```
* EXA.AI: Advanced web search and data extraction
```python
exa_tools = tools_factory.get_llama_index_tools(
tool_package_name="exa.ai",
tool_spec_name="ExaToolSpec",
api_key=str(os.environ["EXA_API_KEY"]),
)
```
* Brave Search: Web search using Brave's search engine
```python
brave_tools = tools_factory.get_llama_index_tools(
tool_package_name="brave_search",
tool_spec_name="BraveSearchToolSpec",
api_key=str(os.environ["BRAVE_API_KEY"]),
)
```
* **Academic Tools**
* arXiv: Search and retrieve academic papers
```python
arxiv_tools = tools_factory.get_llama_index_tools(
tool_package_name="arxiv",
tool_spec_name="ArxivToolSpec",
)
```
* **Database Tools**
* Neo4j: Graph database integration
```python
neo4j_tools = tools_factory.get_llama_index_tools(
tool_package_name="neo4j",
tool_spec_name="Neo4jQueryToolSpec",
)
```
* Kuzu: Lightweight graph database
```python
kuzu_tools = tools_factory.get_llama_index_tools(
tool_package_name="kuzu",
tool_spec_name="KuzuGraphStore",
)
```
* Waii: tools for natural langauge query of a relational database
```python
waii_tools = tools_factory.get_llama_index_tools(
tool_package_name="waii",
tool_spec_name="WaiiToolSpec",
)
```
* **Google Tools**
* Gmail: Read and send emails
```python
gmail_tools = tools_factory.get_llama_index_tools(
tool_package_name="google",
tool_spec_name="GmailToolSpec",
)
```
* Calendar: Manage calendar events
```python
calendar_tools = tools_factory.get_llama_index_tools(
tool_package_name="google",
tool_spec_name="GoogleCalendarToolSpec",
)
```
* Search: Google search integration
```python
search_tools = tools_factory.get_llama_index_tools(
tool_package_name="google",
tool_spec_name="GoogleSearchToolSpec",
)
```
* **Communication Tools**
* Slack: Send messages and interact with Slack
```python
slack_tools = tools_factory.get_llama_index_tools(
tool_package_name="slack",
tool_spec_name="SlackToolSpec",
)
```
For detailed setup instructions and API key requirements, please refer the instructions on [LlamaIndex hub](https://llamahub.ai/?tab=tools) for the specific tool.
### Creating custom tools
You can create your own tool directly from a Python function using the `create_tool()` method of the `ToolsFactory` class:
```python
def mult_func(x, y):
return x * y
mult_tool = ToolsFactory().create_tool(mult_func)
```
#### Human-Readable Tool Output
Tools can provide both raw data and human-readable formatted output using the `create_human_readable_output` utility:
```python
from vectara_agentic.tool_utils import create_human_readable_output, format_as_table
def my_data_tool(query: str):
"""Tool that returns structured data with custom formatting."""
raw_data = [
{"name": "Alice", "age": 30, "city": "New York"},
{"name": "Bob", "age": 25, "city": "Boston"}
]
# Return human-readable output with built-in table formatter
return create_human_readable_output(raw_data, format_as_table)
```
Built-in formatters include `format_as_table`, `format_as_json`, and `format_as_markdown_list`. For detailed documentation and advanced usage, see [tools.md](docs/tools.md#human-readable-tool-output).
> **Important:** When you define your own Python functions as tools, implement them at the top module level,
> and not as nested functions. Nested functions are not supported if you use serialization
> (dumps/loads or from_dict/to_dict).
The human-readable format, if available, is used when computing the factual consistency score.
### Tool Validation
When creating an agent, you can enable tool validation by setting `validate_tools=True`. This will check that any tools mentioned in your custom instructions actually exist in the agent's tool set:
```python
agent = Agent(
tools=[...],
topic="financial reports",
custom_instructions="Always use the get_company_info tool first...",
validate_tools=True # Will raise an error if get_company_info tool doesn't exist
)
```
This helps catch errors where your instructions reference tools that aren't available to the agent.
## 🔄 Advanced Usage: Workflows
In addition to standard chat interactions, `vectara-agentic` supports custom workflows via the `run()` method.
Workflows allow you to structure multi-step interactions where inputs and outputs are validated using Pydantic models.
To learn more about workflows read [the documentation](https://docs.llamaindex.ai/en/stable/understanding/workflows/basic_flow/)
### What are Workflows?
Workflows provide a structured way to handle complex, multi-step interactions with your agent. They're particularly useful when:
- You need to break down complex queries into simpler sub-questions
- You want to implement a specific sequence of operations
- You need to maintain state between different steps of a process
- You want to parallelize certain operations for better performance
### Defining a Custom Workflow
Create a workflow by subclassing `llama_index.core.workflow.Workflow` and defining the input/output models:
```python
from pydantic import BaseModel
from llama_index.core.workflow import (
StartEvent, StopEvent, Workflow, step,
)
class MyWorkflow(Workflow):
class InputsModel(BaseModel):
query: str
class OutputsModel(BaseModel):
answer: str
class OutputModelOnFail(BaseModel):
partial_response: str = ""
@step
async def my_step(self, ev: StartEvent) -> StopEvent:
# do something here
return StopEvent(result="Hello, world!")
```
When the `run()` method in vectara-agentic is invoked, it calls the workflow with the following variables in the `StartEvent`:
* `agent`: the agent object used to call `run()` (self)
* `tools`: the tools provided to the agent. Those can be used as needed in the flow.
* `llm`: a pointer to a LlamaIndex llm, so it can be used in the workflow. For example, one of the steps may call `llm.acomplete(prompt)`
* `verbose`: controls whether extra debug information is displayed
* `inputs`: this is the actual inputs to the workflow provided by the call to `run()` and must be of type `InputsModel`
If you want to use `agent`, `tools`, `llm` or `verbose` in other events (that are not `StartEvent`), you can store them in
the `Context` of the Workflow as follows:
```python
await ctx.set("agent", ev.agent)
```
and then in any other event you can pull that agent object with
```python
agent = await ctx.get("agent")
```
Similarly you can reuse the `llm`, `tools` or `verbose` arguments within other nodes in the workflow.
### Using the Workflow with Your Agent
When initializing your agent, pass the workflow class using the `workflow_cls` parameter:
```python
agent = Agent(
tools=[query_financial_reports_tool],
topic="10-K financial reports",
custom_instructions="You are a helpful financial assistant.",
workflow_cls=MyWorkflow, # Provide your custom workflow here
workflow_timeout=120 # Optional: Set a timeout (default is 120 seconds)
)
```
### Running the Workflow
Prepare the inputs using your workflow's `InputsModel` and execute the workflow using `run()`:
```python
# Create an instance of the workflow's input model
inputs = MyWorkflow.InputsModel(query="What is Vectara?", extra_param=42)
# Run the workflow (ensure you're in an async context or use asyncio.run)
workflow_result = asyncio.run(agent.run(inputs))
# Access the output from the workflow's OutputsModel
print(workflow_result.answer)
```
When a workflow reaches its timeout, the timeout handler builds and returns an `OutputModelOnFail`
by reading each field named in that model from the workflow’s Context; for any field that isn’t set in the context,
it uses the default value you’ve defined on `OutputModelOnFail`. In other words, every property in `OutputModelOnFail`
must declare a default so that even if the corresponding context variable is missing, the model can be fully populated and returned without errors.
### Built-in Workflows
`vectara-agentic` includes two workflow implementations that you can use right away:
#### 1. `SubQuestionQueryWorkflow`
This workflow breaks down complex queries into simpler sub-questions, executes them in parallel, and then combines the answers:
```python
from vectara_agentic.sub_query_workflow import SubQuestionQueryWorkflow
agent = Agent(
tools=[query_financial_reports_tool],
topic="10-K financial reports",
custom_instructions="You are a helpful financial assistant.",
workflow_cls=SubQuestionQueryWorkflow
)
# Run the workflow with a complex query
inputs = SubQuestionQueryWorkflow.InputsModel(
query="Compare Apple's revenue growth to Google's between 2020 and 2023"
)
result = asyncio.run(agent.run(inputs))
print(result.response)
```
The workflow works in three steps:
1. **Query**: Breaks down the complex query into sub-questions
2. **Sub-question**: Executes each sub-question in parallel (using 4 workers by default)
3. **Combine answers**: Synthesizes all the answers into a coherent response
#### 2. `SequentialSubQuestionsWorkflow`
This workflow is similar to `SubQuestionQueryWorkflow` but executes sub-questions sequentially, where each question can depend on the answer to the previous question:
```python
from vectara_agentic.sub_query_workflow import SequentialSubQuestionsWorkflow
agent = Agent(
tools=[query_financial_reports_tool],
topic="10-K financial reports",
custom_instructions="You are a helpful financial assistant.",
workflow_cls=SequentialSubQuestionsWorkflow
)
# Run the workflow with a complex query that requires sequential reasoning
inputs = SequentialSubQuestionsWorkflow.InputsModel(
query="What was the revenue growth rate of the company with the highest market cap in 2022?"
)
result = asyncio.run(agent.run(inputs))
print(result.response)
```
The workflow works in two steps:
1. **Query**: Breaks down the complex query into sequential sub-questions
2. **Sub-question**: Executes each sub-question in sequence, passing the answer from one question to the next
### When to Use Each Workflow Type
- **Use SubQuestionQueryWorkflow** when:
- Your query can be broken down into independent sub-questions
- You want to parallelize the execution for better performance
- The sub-questions don't depend on each other's answers
- **Use SequentialSubQuestionsWorkflow** when:
- Your query requires sequential reasoning
- Each sub-question depends on the answer to the previous question
- You need to build up information step by step
- **Create a custom workflow** when:
- You have a specific sequence of operations that doesn't fit the built-in workflows
- You need to implement complex business logic
- You want to integrate with external systems or APIs in a specific way
## 🛠️ Configuration
### Configuring Vectara-agentic
The main way to control the behavior of `vectara-agentic` is by passing an `AgentConfig` object to your `Agent` when creating it.
For example:
```python
from vectara_agentic import AgentConfig, AgentType, ModelProvider
agent_config = AgentConfig(
agent_type = AgentType.REACT,
main_llm_provider = ModelProvider.ANTHROPIC,
main_llm_model_name = 'claude-3-5-sonnet-20241022',
tool_llm_provider = ModelProvider.TOGETHER,
tool_llm_model_name = 'meta-llama/Llama-3.3-70B-Instruct-Turbo'
)
agent = Agent(
tools=[query_financial_reports_tool],
topic="10-K financial reports",
custom_instructions="You are a helpful financial assistant in conversation with a user.",
agent_config=agent_config
)
```
The `AgentConfig` object may include the following items:
- `agent_type`: the agent type. Valid values are `REACT`, `LLMCOMPILER`, `LATS` or `OPENAI` (default: `OPENAI`).
- `main_llm_provider` and `tool_llm_provider`: the LLM provider for main agent and for the tools. Valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `BEDROCK`, `GEMINI` or `FIREWORKS` (default: `OPENAI`).
- `main_llm_model_name` and `tool_llm_model_name`: agent model name for agent and tools (default depends on provider).
- `observer`: the observer type; should be `ARIZE_PHOENIX` or if undefined no observation framework will be used.
- `endpoint_api_key`: a secret key if using the API endpoint option (defaults to `dev-api-key`)
- `max_reasoning_steps`: the maximum number of reasoning steps (iterations for React and function calls for OpenAI agent, respectively). Defaults to 50.
If any of these are not provided, `AgentConfig` first tries to read the values from the OS environment.
### Configuring Vectara tools: `rag_tool`, or `search_tool`
When creating a `VectaraToolFactory`, you can pass in a `vectara_api_key`, and `vectara_corpus_key` to the factory.
If not passed in, it will be taken from the environment variables (`VECTARA_API_KEY` and `VECTARA_CORPUS_KEY`). Note that `VECTARA_CORPUS_KEY` can be a single KEY or a comma-separated list of KEYs (if you want to query multiple corpora).
These values will be used as credentials when creating Vectara tools - in `create_rag_tool()` and `create_search_tool()`.
### Setting up a privately hosted LLM
If you want to setup `vectara-agentic` to use your own self-hosted LLM endpoint, follow the example below:
```python
from vectara_agentic import AgentConfig, AgentType, ModelProvider
config = AgentConfig(
agent_type=AgentType.REACT,
main_llm_provider=ModelProvider.PRIVATE,
main_llm_model_name="meta-llama/Meta-Llama-3.1-8B-Instruct",
private_llm_api_base="http://vllm-server.company.com/v1",
private_llm_api_key="TEST_API_KEY",
)
agent = Agent(
agent_config=config,
tools=tools,
topic=topic,
custom_instructions=custom_instructions
)
```
Raw data
{
"_id": null,
"home_page": "https://github.com/vectara/py-vectara-agentic",
"name": "vectara-agentic",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "LLM, NLP, RAG, Agentic-RAG, AI assistant, AI Agent, Vectara",
"author": "Ofer Mendelevitch",
"author_email": "ofer@vectara.com",
"download_url": "https://files.pythonhosted.org/packages/46/63/9b222164a65350ef8a768bb2db525b6253d5c55957b91b1d557aab42d4ab/vectara_agentic-0.3.3.tar.gz",
"platform": null,
"description": "# <img src=\"https://raw.githubusercontent.com/vectara/py-vectara-agentic/main/.github/assets/Vectara-logo.png\" alt=\"Vectara Logo\" width=\"30\" height=\"30\" style=\"vertical-align: middle;\"> vectara-agentic\n\n<p align=\"center\">\n <a href=\"https://vectara.github.io/py-vectara-agentic\">Documentation</a> \u00b7\n <a href=\"#example-ai-assistants\">Examples</a> \u00b7\n <a href=\"https://discord.gg/S9dwgCNEFs\">Discord</a>\n</p>\n\n<p align=\"center\">\n <a href=\"https://opensource.org/licenses/Apache-2.0\">\n <img src=\"https://img.shields.io/badge/License-Apache%202.0-blue.svg\" alt=\"License\">\n </a>\n <a href=\"https://github.com/vectara/py-vectara-agentic/graphs/commit-activity\">\n <img src=\"https://img.shields.io/badge/Maintained%3F-yes-green.svg\" alt=\"Maintained\">\n </a>\n <a href=\"https://twitter.com/vectara\">\n <img src=\"https://img.shields.io/twitter/follow/vectara.svg?style=social&label=Follow%20%40Vectara\" alt=\"Twitter\">\n </a>\n <a href=\"https://pypi.org/project/vectara-agentic/\">\n <img src=\"https://img.shields.io/pypi/v/vectara-agentic.svg\" alt=\"PyPI version\">\n </a>\n <a href=\"https://pypi.org/project/vectara-agentic/\">\n <img src=\"https://img.shields.io/pypi/pyversions/vectara-agentic.svg\" alt=\"Python versions\">\n </a>\n</p>\n\n## \ud83d\udcd1 Table of Contents\n\n- [Overview](#-overview)\n- [Quick Start](#-quick-start)\n- [Using Tools](#using-tools)\n- [Advanced Usage: Workflows](#advanced-usage-workflows)\n- [Configuration](#\ufe0f-configuration)\n- [Contributing](#-contributing)\n- [License](#-license)\n\n## \u2728 Overview\n\n`vectara-agentic` is a Python library for developing powerful AI assistants and agents using Vectara and Agentic-RAG. It leverages the LlamaIndex Agent framework and provides helper functions to quickly create tools that connect to Vectara corpora.\n\n<p align=\"center\">\n<img src=\"https://raw.githubusercontent.com/vectara/py-vectara-agentic/main/.github/assets/diagram1.png\" alt=\"Agentic RAG diagram\" width=\"100%\" style=\"vertical-align: middle;\">\n</p>\n\n### Key Features\n\n- **Rapid Tool Creation:** \n Build Vectara RAG tools or search tools with a single line of code.\n- **Agent Flexibility:** \n Supports multiple agent types including `ReAct`, `OpenAIAgent`, `LATS`, and `LLMCompiler`.\n- **Pre-Built Domain Tools:** \n Tools tailored for finance, legal, and other verticals.\n- **Multi-LLM Integration:** \n Seamless integration with OpenAI, Anthropic, Gemini, GROQ, Together.AI, Cohere, Bedrock, and Fireworks.\n- **Observability:** \n Built-in support with Arize Phoenix for monitoring and feedback.\n- **Workflow Support:** \n Extend your agent's capabilities by defining custom workflows using the `run()` method.\n\n### Example AI Assistants\n\nCheck out our example AI assistants:\n\n- [Financial Assistant](https://huggingface.co/spaces/vectara/finance-chat)\n- [Justice Harvard Teaching Assistant](https://huggingface.co/spaces/vectara/Justice-Harvard)\n- [Legal Assistant](https://huggingface.co/spaces/vectara/legal-agent)\n- [EV Assistant](https://huggingface.co/spaces/vectara/ev-assistant)\n\n### Prerequisites\n\n- [Vectara account](https://console.vectara.com/signup/?utm_source=github&utm_medium=code&utm_term=DevRel&utm_content=vectara-agentic&utm_campaign=github-code-DevRel-vectara-agentic)\n- A Vectara corpus with an [API key](https://docs.vectara.com/docs/api-keys)\n- [Python 3.10 or higher](https://www.python.org/downloads/)\n- OpenAI API key (or API keys for Anthropic, TOGETHER.AI, Fireworks AI, Cohere, GEMINI or GROQ, if you choose to use them).\n To use AWS Bedrock, make sure that\n * The Bedrock models you need are enabled on your account\n * Your environment includes `AWS_PROFILE` with your AWS profile name.\n * Your environment includes `AWS_REGION` set to the region where you want to consume the AWS Bedrock services (defaults to us-east-2)\n\n### Installation\n\n```bash\npip install vectara-agentic\n```\n\n## \ud83d\ude80 Quick Start\n\nLet's see how we create a simple AI assistant to answer questions about financial data ingested into Vectara, using `vectara-agentic`. \n\n### 1. Initialize the Vectara tool factory\n\n```python\nimport os\nfrom vectara_agentic.tools import VectaraToolFactory\n\nvec_factory = VectaraToolFactory(\n vectara_api_key=os.environ['VECTARA_API_KEY'],\n vectara_corpus_key=os.environ['VECTARA_CORPUS_KEY']\n)\n```\n\n### 2. Create a Vectara RAG Tool\n\nA RAG tool calls the full Vectara RAG pipeline to provide summarized responses to queries grounded in data. We define two additional arguments (`year` and `ticker` that map to filter attributes in the Vectara corpus):\n\n```python\nfrom pydantic import BaseModel, Field\n\nyears = list(range(2020, 2024))\ntickers = {\n \"AAPL\": \"Apple Computer\",\n \"GOOG\": \"Google\",\n \"AMZN\": \"Amazon\",\n \"SNOW\": \"Snowflake\",\n}\n\nclass QueryFinancialReportsArgs(BaseModel):\n year: int | str = Field(..., description=f\"The year this query relates to. An integer between {min(years)} and {max(years)} or a string specifying a condition on the year (example: '>2020').\")\n ticker: str = Field(..., description=f\"The company ticker. Must be a valid ticket symbol from the list {tickers.keys()}.\")\n\nask_finance = vec_factory.create_rag_tool(\n tool_name=\"query_financial_reports\",\n tool_description=\"Query financial reports for a company and year\",\n tool_args_schema=QueryFinancialReportsArgs,\n lambda_val=0.005,\n summary_num_results=7, \n # Additional Vectara query arguments...\n)\n```\n\n> **Note:** We only defined the `year` and `ticker` arguments in the QueryFinancialReportsArgs model. The `query` argument is automatically added by `create_rag_tool`.\n\nTo learn about additional arguments `create_rag_tool`, please see the full [docs](https://vectara.github.io/py-vectara-agentic/latest/).\n\n### 3. Create other tools (optional)\n\nIn addition to RAG tools or search tools, you can generate additional tools the agent can use. These could be mathematical tools, tools \nthat call other APIs to get more information, or any other type of tool.\n\nSee [Agent Tools](#\ufe0f-agent-tools-at-a-glance) for more information.\n\n### 4. Create your agent\n\nHere is how we will instantiate our AI Finance Assistant. First define your custom instructions:\n\n```python\nfinancial_assistant_instructions = \"\"\"\n - You are a helpful financial assistant, with expertise in financial reporting, in conversation with a user.\n - Never discuss politics, and always respond politely.\n - Respond in a compact format by using appropriate units of measure (e.g., K for thousands, M for millions, B for billions).\n - Do not report the same number twice (e.g. $100K and 100,000 USD).\n - Always check the get_company_info and get_valid_years tools to validate company and year are valid.\n - When querying a tool for a numeric value or KPI, use a concise and non-ambiguous description of what you are looking for.\n - If you calculate a metric, make sure you have all the necessary information to complete the calculation. Don't guess.\n\"\"\"\n```\n\nThen just instantiate the `Agent` class:\n\n```python\nfrom vectara_agentic import Agent\n\nagent = Agent(\n tools = \n [ask_finance],\n topic=\"10-K annual financial reports\",\n custom_instructions=financial_assistant_instructions,\n agent_progress_callback=agent_progress_callback\n)\n```\n\nThe `topic` parameter helps identify the agent's area of expertise, while `custom_instructions` lets you customize how the agent behaves and presents information. The agent will combine these with its default general instructions to determine its complete behavior.\n\nThe `agent_progress_callback` argument is an optional function that will be called when various Agent events occur, and can be used to track agent steps.\n\n### 5. Run a chat interaction\n\n```python\nres = agent.chat(\"What was the revenue for Apple in 2021?\")\nprint(res.response)\n```\n\n> **Note:** \n> 1. `vectara-agentic` also supports `achat()` as well as two streaming variants `stream_chat()` and `astream_chat()`.\n> 2. The response types from `chat()` and `achat()` are of type `AgentResponse`. If you just need the actual string\n> response it's available as the `response` variable, or just use `str()`. For advanced use-cases you can look \n> at other `AgentResponse` variables [such as `sources`](https://github.com/run-llama/llama_index/blob/659f9faaafbecebb6e6c65f42143c0bf19274a37/llama-index-core/llama_index/core/chat_engine/types.py#L53).\n\n## Agent Instructions\n\nWhen creating an agent, it already comes with a set of general base instructions, designed carefully to enhance its operation and improve how the agent works.\n\nIn addition, you can add `custom_instructions` that are specific to your use case that customize how the agent behaves.\n\nWhen writing custom instructions:\n- Focus on behavior and presentation rather than tool usage (that's what tool descriptions are for)\n- Be precise and clear without overcomplicating\n- Consider edge cases and unusual scenarios\n- Avoid over-specifying behavior based on primary use cases\n- Keep instructions focused on how you want the agent to behave and present information\n\nThe agent will combine both the general instructions and your custom instructions to determine its behavior.\n\nIt is not recommended to change the general instructions, but it is possible as well to override them with the optional `general_instructions` parameter. If you do change them, your agent may not work as intended, so be careful if overriding these instructions.\n\n## \ud83e\uddf0 Defining Tools\n\n### Vectara tools\n\n`vectara-agentic` provides two helper functions to connect with Vectara RAG:\n* `create_rag_tool()` to create an agent tool that connects with a Vectara corpus for querying. \n* `create_search_tool()` to create a tool to search a Vectara corpus and return a list of matching documents.\n\nSee the documentation for the full list of arguments for `create_rag_tool()` and `create_search_tool()`, \nto understand how to configure Vectara query performed by those tools.\n\n#### Creating a Vectara RAG tool\n\nA Vectara RAG tool is often the main workhorse for any Agentic RAG application, and enables the agent to query \none or more Vectara RAG corpora. \n\nThe tool generated always includes the `query` argument, followed by 1 or more optional arguments used for \nmetadata filtering, defined by `tool_args_schema`.\n\nFor example, in the quickstart example the schema is:\n\n```python\nclass QueryFinancialReportsArgs(BaseModel):\n year: int | str = Field(..., description=f\"The year this query relates to. An integer between {min(years)} and {max(years)} or a string specifying a condition on the year (example: '>2020').\")\n ticker: str = Field(..., description=f\"The company ticker. Must be a valid ticket symbol from the list {tickers.keys()}.\")\n```\n\nRemember, the `query` argument is part of the rag_tool that is generated, but `vectara-agentic` creates it and you do \nnot need to specify it explicitly. \n\nFor example, in the example above, the agent may call the `query_financial_reports_tool` tool with \nquery='what is the revenue?', year=2022 and ticker='AAPL'. Subsequently the RAG tool will issue\na Vectara RAG query with the same query, but with metadata filtering (doc.year=2022 and doc.ticker='AAPL').\n\nThere are also additional cool features supported here:\n* An argument can be a condition, for example year='>2022' translates to the correct metadata \n filtering condition doc.year>2022\n* if `fixed_filter` is defined in the RAG tool, it provides a constant metadata filtering that is always applied.\n For example, if fixed_filter=`doc.filing_type='10K'` then a query with query='what is the reveue', year=2022\n and ticker='AAPL' would translate into query='what is the revenue' with metadata filtering condition of\n \"doc.year=2022 AND doc.ticker='AAPL' and doc.filing_type='10K'\"\n\nNote that `tool_args_type` is an optional dictionary that indicates:\n* `type`: the level at which metadata filtering is applied for each argument (`doc` or `part`)\n* `is_list`: whether the argument is a list type\n* `filter_name`: a filter name (in cases where variable name can't be used, e.g. with spaces) to be used \n instead of the variable name.\n\n#### Creating a Vectara search tool\n\nThe Vectara search tool allows the agent to list documents that match a query.\nThis can be helpful to the agent to answer queries like \"how many documents discuss the iPhone?\" or other\nsimilar queries that require a response in terms of a list of matching documents.\n\n### \ud83d\udee0\ufe0f Agent Tools at a Glance\n\n`vectara-agentic` provides a few tools out of the box (see `ToolsCatalog` for details):\n\n**1. Standard tools**\n- `summarize_text`: a tool to summarize a long text into a shorter summary (uses LLM)\n- `rephrase_text`: a tool to rephrase a given text, given a set of rephrase instructions (uses LLM)\n\nThese tools use an LLM and so would use the `Tools` LLM specified in your `AgentConfig`.\nTo instantiate them:\n\n```python\nfrom vectara_agentic.tools_catalog import ToolsCatalog\nsummarize_text = ToolsCatalog(agent_config).summarize_text\n```\n\nThis ensures the summarize_text tool is configured with the proper LLM provider and model as \nspecified in the Agent configuration.\n\n**2. Legal tools**\nA set of tools for the legal vertical, such as:\n- `summarize_legal_text`: summarize legal text with a certain point of view\n- `critique_as_judge`: critique a legal text as a judge, providing their perspective\n\n**3. Financial tools**\nBased on tools from Yahoo! Finance:\n- tools to understand the financials of a public company like: `balance_sheet`, `income_statement`, `cash_flow`\n- `stock_news`: provides news about a company\n- `stock_analyst_recommendations`: provides stock analyst recommendations for a company.\n\n**4. Database tools**\nProviding tools to inspect and query a database:\n- `list_tables`: list all tables in the database\n- `describe_tables`: describe the schema of tables in the database\n- `load_data`: returns data based on a SQL query\n- `load_sample_data`: returns the first 25 rows of a table\n- `load_unique_values`: returns the top unique values for a given column\n\n**5. Additional integrations**\nvectara-agentic includes various other tools from LlamaIndex ToolSpecs:\n\n* **Search Tools**\n * Tavily Search: Real-time web search using [Tavily API](https://tavily.com/)\n ```python\n from vectara_agentic.tools_catalog import ToolsCatalog\n tools_factory = ToolsFactory()\n tavily_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"tavily_research\",\n tool_spec_name=\"TavilyToolSpec\",\n api_key=str(os.environ[\"TAVILY_API_KEY\"]),\n )\n ```\n * EXA.AI: Advanced web search and data extraction\n ```python\n exa_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"exa.ai\",\n tool_spec_name=\"ExaToolSpec\",\n api_key=str(os.environ[\"EXA_API_KEY\"]),\n )\n ```\n * Brave Search: Web search using Brave's search engine\n ```python\n brave_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"brave_search\",\n tool_spec_name=\"BraveSearchToolSpec\",\n api_key=str(os.environ[\"BRAVE_API_KEY\"]),\n )\n ```\n\n* **Academic Tools**\n * arXiv: Search and retrieve academic papers\n ```python\n arxiv_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"arxiv\",\n tool_spec_name=\"ArxivToolSpec\",\n )\n ```\n\n* **Database Tools**\n * Neo4j: Graph database integration\n ```python\n neo4j_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"neo4j\",\n tool_spec_name=\"Neo4jQueryToolSpec\",\n )\n ```\n * Kuzu: Lightweight graph database\n ```python\n kuzu_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"kuzu\",\n tool_spec_name=\"KuzuGraphStore\",\n )\n ```\n * Waii: tools for natural langauge query of a relational database\n ```python\n waii_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"waii\",\n tool_spec_name=\"WaiiToolSpec\",\n )\n ```\n\n* **Google Tools**\n * Gmail: Read and send emails\n ```python\n gmail_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"google\",\n tool_spec_name=\"GmailToolSpec\",\n )\n ```\n * Calendar: Manage calendar events\n ```python\n calendar_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"google\",\n tool_spec_name=\"GoogleCalendarToolSpec\",\n )\n ```\n * Search: Google search integration\n ```python\n search_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"google\",\n tool_spec_name=\"GoogleSearchToolSpec\",\n )\n ```\n\n* **Communication Tools**\n * Slack: Send messages and interact with Slack\n ```python\n slack_tools = tools_factory.get_llama_index_tools(\n tool_package_name=\"slack\",\n tool_spec_name=\"SlackToolSpec\",\n )\n ```\n\nFor detailed setup instructions and API key requirements, please refer the instructions on [LlamaIndex hub](https://llamahub.ai/?tab=tools) for the specific tool.\n\n### Creating custom tools\n\nYou can create your own tool directly from a Python function using the `create_tool()` method of the `ToolsFactory` class:\n\n```python\ndef mult_func(x, y):\n return x * y\n\nmult_tool = ToolsFactory().create_tool(mult_func)\n```\n\n#### Human-Readable Tool Output\n\nTools can provide both raw data and human-readable formatted output using the `create_human_readable_output` utility:\n\n```python\nfrom vectara_agentic.tool_utils import create_human_readable_output, format_as_table\n\ndef my_data_tool(query: str):\n \"\"\"Tool that returns structured data with custom formatting.\"\"\"\n raw_data = [\n {\"name\": \"Alice\", \"age\": 30, \"city\": \"New York\"},\n {\"name\": \"Bob\", \"age\": 25, \"city\": \"Boston\"}\n ]\n \n # Return human-readable output with built-in table formatter\n return create_human_readable_output(raw_data, format_as_table)\n```\n\nBuilt-in formatters include `format_as_table`, `format_as_json`, and `format_as_markdown_list`. For detailed documentation and advanced usage, see [tools.md](docs/tools.md#human-readable-tool-output).\n\n> **Important:** When you define your own Python functions as tools, implement them at the top module level,\n> and not as nested functions. Nested functions are not supported if you use serialization \n> (dumps/loads or from_dict/to_dict).\n\nThe human-readable format, if available, is used when computing the factual consistency score.\n\n### Tool Validation\n\nWhen creating an agent, you can enable tool validation by setting `validate_tools=True`. This will check that any tools mentioned in your custom instructions actually exist in the agent's tool set:\n\n```python\nagent = Agent(\n tools=[...],\n topic=\"financial reports\",\n custom_instructions=\"Always use the get_company_info tool first...\",\n validate_tools=True # Will raise an error if get_company_info tool doesn't exist\n)\n```\n\nThis helps catch errors where your instructions reference tools that aren't available to the agent.\n\n## \ud83d\udd04 Advanced Usage: Workflows\n\nIn addition to standard chat interactions, `vectara-agentic` supports custom workflows via the `run()` method. \nWorkflows allow you to structure multi-step interactions where inputs and outputs are validated using Pydantic models.\nTo learn more about workflows read [the documentation](https://docs.llamaindex.ai/en/stable/understanding/workflows/basic_flow/)\n\n### What are Workflows?\n\nWorkflows provide a structured way to handle complex, multi-step interactions with your agent. They're particularly useful when:\n\n- You need to break down complex queries into simpler sub-questions\n- You want to implement a specific sequence of operations\n- You need to maintain state between different steps of a process\n- You want to parallelize certain operations for better performance\n\n### Defining a Custom Workflow\n\nCreate a workflow by subclassing `llama_index.core.workflow.Workflow` and defining the input/output models:\n\n```python\nfrom pydantic import BaseModel\nfrom llama_index.core.workflow import (\n StartEvent, StopEvent, Workflow, step,\n)\n\nclass MyWorkflow(Workflow):\n class InputsModel(BaseModel):\n query: str\n\n class OutputsModel(BaseModel):\n answer: str\n\n class OutputModelOnFail(BaseModel):\n partial_response: str = \"\"\n\n @step\n async def my_step(self, ev: StartEvent) -> StopEvent:\n # do something here\n return StopEvent(result=\"Hello, world!\")\n```\n\nWhen the `run()` method in vectara-agentic is invoked, it calls the workflow with the following variables in the `StartEvent`:\n* `agent`: the agent object used to call `run()` (self)\n* `tools`: the tools provided to the agent. Those can be used as needed in the flow.\n* `llm`: a pointer to a LlamaIndex llm, so it can be used in the workflow. For example, one of the steps may call `llm.acomplete(prompt)`\n* `verbose`: controls whether extra debug information is displayed\n* `inputs`: this is the actual inputs to the workflow provided by the call to `run()` and must be of type `InputsModel`\n\nIf you want to use `agent`, `tools`, `llm` or `verbose` in other events (that are not `StartEvent`), you can store them in\nthe `Context` of the Workflow as follows:\n\n```python\nawait ctx.set(\"agent\", ev.agent)\n```\n\nand then in any other event you can pull that agent object with\n\n```python\nagent = await ctx.get(\"agent\")\n```\n\nSimilarly you can reuse the `llm`, `tools` or `verbose` arguments within other nodes in the workflow.\n\n### Using the Workflow with Your Agent\n\nWhen initializing your agent, pass the workflow class using the `workflow_cls` parameter:\n\n```python\nagent = Agent(\n tools=[query_financial_reports_tool],\n topic=\"10-K financial reports\",\n custom_instructions=\"You are a helpful financial assistant.\",\n workflow_cls=MyWorkflow, # Provide your custom workflow here\n workflow_timeout=120 # Optional: Set a timeout (default is 120 seconds)\n)\n```\n\n### Running the Workflow\n\nPrepare the inputs using your workflow's `InputsModel` and execute the workflow using `run()`:\n\n```python\n# Create an instance of the workflow's input model\ninputs = MyWorkflow.InputsModel(query=\"What is Vectara?\", extra_param=42)\n\n# Run the workflow (ensure you're in an async context or use asyncio.run)\nworkflow_result = asyncio.run(agent.run(inputs))\n\n# Access the output from the workflow's OutputsModel\nprint(workflow_result.answer)\n```\n\nWhen a workflow reaches its timeout, the timeout handler builds and returns an `OutputModelOnFail` \nby reading each field named in that model from the workflow\u2019s Context; for any field that isn\u2019t set in the context, \nit uses the default value you\u2019ve defined on `OutputModelOnFail`. In other words, every property in `OutputModelOnFail` \nmust declare a default so that even if the corresponding context variable is missing, the model can be fully populated and returned without errors.\n\n### Built-in Workflows\n\n`vectara-agentic` includes two workflow implementations that you can use right away:\n\n#### 1. `SubQuestionQueryWorkflow`\n\nThis workflow breaks down complex queries into simpler sub-questions, executes them in parallel, and then combines the answers:\n\n```python\nfrom vectara_agentic.sub_query_workflow import SubQuestionQueryWorkflow\n\nagent = Agent(\n tools=[query_financial_reports_tool],\n topic=\"10-K financial reports\",\n custom_instructions=\"You are a helpful financial assistant.\",\n workflow_cls=SubQuestionQueryWorkflow\n)\n\n# Run the workflow with a complex query\ninputs = SubQuestionQueryWorkflow.InputsModel(\n query=\"Compare Apple's revenue growth to Google's between 2020 and 2023\"\n)\nresult = asyncio.run(agent.run(inputs))\nprint(result.response)\n```\n\nThe workflow works in three steps:\n1. **Query**: Breaks down the complex query into sub-questions\n2. **Sub-question**: Executes each sub-question in parallel (using 4 workers by default)\n3. **Combine answers**: Synthesizes all the answers into a coherent response\n\n#### 2. `SequentialSubQuestionsWorkflow`\n\nThis workflow is similar to `SubQuestionQueryWorkflow` but executes sub-questions sequentially, where each question can depend on the answer to the previous question:\n\n```python\nfrom vectara_agentic.sub_query_workflow import SequentialSubQuestionsWorkflow\n\nagent = Agent(\n tools=[query_financial_reports_tool],\n topic=\"10-K financial reports\",\n custom_instructions=\"You are a helpful financial assistant.\",\n workflow_cls=SequentialSubQuestionsWorkflow\n)\n\n# Run the workflow with a complex query that requires sequential reasoning\ninputs = SequentialSubQuestionsWorkflow.InputsModel(\n query=\"What was the revenue growth rate of the company with the highest market cap in 2022?\"\n)\nresult = asyncio.run(agent.run(inputs))\nprint(result.response)\n```\n\nThe workflow works in two steps:\n1. **Query**: Breaks down the complex query into sequential sub-questions\n2. **Sub-question**: Executes each sub-question in sequence, passing the answer from one question to the next\n\n### When to Use Each Workflow Type\n\n- **Use SubQuestionQueryWorkflow** when:\n - Your query can be broken down into independent sub-questions\n - You want to parallelize the execution for better performance\n - The sub-questions don't depend on each other's answers\n\n- **Use SequentialSubQuestionsWorkflow** when:\n - Your query requires sequential reasoning\n - Each sub-question depends on the answer to the previous question\n - You need to build up information step by step\n\n- **Create a custom workflow** when:\n - You have a specific sequence of operations that doesn't fit the built-in workflows\n - You need to implement complex business logic\n - You want to integrate with external systems or APIs in a specific way\n\n## \ud83d\udee0\ufe0f Configuration\n\n### Configuring Vectara-agentic\n\nThe main way to control the behavior of `vectara-agentic` is by passing an `AgentConfig` object to your `Agent` when creating it.\nFor example:\n\n```python\nfrom vectara_agentic import AgentConfig, AgentType, ModelProvider\n\nagent_config = AgentConfig(\n agent_type = AgentType.REACT,\n main_llm_provider = ModelProvider.ANTHROPIC,\n main_llm_model_name = 'claude-3-5-sonnet-20241022',\n tool_llm_provider = ModelProvider.TOGETHER,\n tool_llm_model_name = 'meta-llama/Llama-3.3-70B-Instruct-Turbo'\n)\n\nagent = Agent(\n tools=[query_financial_reports_tool],\n topic=\"10-K financial reports\",\n custom_instructions=\"You are a helpful financial assistant in conversation with a user.\",\n agent_config=agent_config\n)\n```\n\nThe `AgentConfig` object may include the following items:\n- `agent_type`: the agent type. Valid values are `REACT`, `LLMCOMPILER`, `LATS` or `OPENAI` (default: `OPENAI`).\n- `main_llm_provider` and `tool_llm_provider`: the LLM provider for main agent and for the tools. Valid values are `OPENAI`, `ANTHROPIC`, `TOGETHER`, `GROQ`, `COHERE`, `BEDROCK`, `GEMINI` or `FIREWORKS` (default: `OPENAI`).\n- `main_llm_model_name` and `tool_llm_model_name`: agent model name for agent and tools (default depends on provider).\n- `observer`: the observer type; should be `ARIZE_PHOENIX` or if undefined no observation framework will be used.\n- `endpoint_api_key`: a secret key if using the API endpoint option (defaults to `dev-api-key`)\n- `max_reasoning_steps`: the maximum number of reasoning steps (iterations for React and function calls for OpenAI agent, respectively). Defaults to 50.\n\nIf any of these are not provided, `AgentConfig` first tries to read the values from the OS environment.\n\n### Configuring Vectara tools: `rag_tool`, or `search_tool`\n\nWhen creating a `VectaraToolFactory`, you can pass in a `vectara_api_key`, and `vectara_corpus_key` to the factory. \n\nIf not passed in, it will be taken from the environment variables (`VECTARA_API_KEY` and `VECTARA_CORPUS_KEY`). Note that `VECTARA_CORPUS_KEY` can be a single KEY or a comma-separated list of KEYs (if you want to query multiple corpora).\n\nThese values will be used as credentials when creating Vectara tools - in `create_rag_tool()` and `create_search_tool()`.\n\n### Setting up a privately hosted LLM\n\nIf you want to setup `vectara-agentic` to use your own self-hosted LLM endpoint, follow the example below:\n\n```python\nfrom vectara_agentic import AgentConfig, AgentType, ModelProvider\n\nconfig = AgentConfig(\n agent_type=AgentType.REACT,\n main_llm_provider=ModelProvider.PRIVATE,\n main_llm_model_name=\"meta-llama/Meta-Llama-3.1-8B-Instruct\",\n private_llm_api_base=\"http://vllm-server.company.com/v1\",\n private_llm_api_key=\"TEST_API_KEY\",\n)\n\nagent = Agent(\n agent_config=config, \n tools=tools, \n topic=topic,\n custom_instructions=custom_instructions\n)\n```\n\n",
"bugtrack_url": null,
"license": null,
"summary": "A Python package for creating AI Assistants and AI Agents with Vectara",
"version": "0.3.3",
"project_urls": {
"Documentation": "https://vectara.github.io/py-vectara-agentic/",
"Homepage": "https://github.com/vectara/py-vectara-agentic"
},
"split_keywords": [
"llm",
" nlp",
" rag",
" agentic-rag",
" ai assistant",
" ai agent",
" vectara"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "a3074ae30a6dafd0c12d4d9890c744d2a14b7b26c59b9216f27492c5bd307d10",
"md5": "b9f6f0a3e337572c549661fb615e04b4",
"sha256": "3529e1b245f86f758dbd22b0b478c1f721de4a28779ad9d2e0ec493e2cbc4194"
},
"downloads": -1,
"filename": "vectara_agentic-0.3.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b9f6f0a3e337572c549661fb615e04b4",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 88151,
"upload_time": "2025-07-23T21:12:19",
"upload_time_iso_8601": "2025-07-23T21:12:19.582956Z",
"url": "https://files.pythonhosted.org/packages/a3/07/4ae30a6dafd0c12d4d9890c744d2a14b7b26c59b9216f27492c5bd307d10/vectara_agentic-0.3.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "46639b222164a65350ef8a768bb2db525b6253d5c55957b91b1d557aab42d4ab",
"md5": "c4017338ad33a50ba832d55771800f31",
"sha256": "8bde21260ba1084fc28c8f5fed09e8f43d0dd89de94828cbb985f85b89ebc7f3"
},
"downloads": -1,
"filename": "vectara_agentic-0.3.3.tar.gz",
"has_sig": false,
"md5_digest": "c4017338ad33a50ba832d55771800f31",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 84824,
"upload_time": "2025-07-23T21:12:20",
"upload_time_iso_8601": "2025-07-23T21:12:20.914428Z",
"url": "https://files.pythonhosted.org/packages/46/63/9b222164a65350ef8a768bb2db525b6253d5c55957b91b1d557aab42d4ab/vectara_agentic-0.3.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-23 21:12:20",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "vectara",
"github_project": "py-vectara-agentic",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "llama-index",
"specs": [
[
"==",
"0.12.37"
]
]
},
{
"name": "llama-index-core",
"specs": [
[
"==",
"0.12.37"
]
]
},
{
"name": "llama-index-cli",
"specs": [
[
"==",
"0.4.1"
]
]
},
{
"name": "llama-index-indices-managed-vectara",
"specs": [
[
"==",
"0.4.5"
]
]
},
{
"name": "llama-index-agent-llm-compiler",
"specs": [
[
"==",
"0.3.1"
]
]
},
{
"name": "llama-index-agent-lats",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-agent-openai",
"specs": [
[
"==",
"0.4.8"
]
]
},
{
"name": "llama-index-llms-openai",
"specs": [
[
"==",
"0.3.44"
]
]
},
{
"name": "llama-index-llms-openai-like",
"specs": [
[
"==",
"0.3.5"
]
]
},
{
"name": "llama-index-llms-anthropic",
"specs": [
[
"==",
"0.6.19"
]
]
},
{
"name": "llama-index-llms-together",
"specs": [
[
"==",
"0.3.1"
]
]
},
{
"name": "llama-index-llms-groq",
"specs": [
[
"==",
"0.3.1"
]
]
},
{
"name": "llama-index-llms-fireworks",
"specs": [
[
"==",
"0.3.2"
]
]
},
{
"name": "llama-index-llms-cohere",
"specs": [
[
"==",
"0.5.0"
]
]
},
{
"name": "llama-index-llms-google-genai",
"specs": [
[
"==",
"0.2.1"
]
]
},
{
"name": "llama-index-llms-bedrock-converse",
"specs": [
[
"==",
"0.7.1"
]
]
},
{
"name": "llama-index-tools-yahoo-finance",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-tools-arxiv",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-tools-database",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-tools-google",
"specs": [
[
"==",
"0.3.1"
]
]
},
{
"name": "llama-index-tools-tavily_research",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama_index.tools.brave_search",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-tools-neo4j",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-tools-waii",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-graph-stores-kuzu",
"specs": [
[
"==",
"0.7.0"
]
]
},
{
"name": "llama-index-tools-salesforce",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-tools-slack",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-tools-exa",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-tools-wikipedia",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "llama-index-tools-bing-search",
"specs": [
[
"==",
"0.3.0"
]
]
},
{
"name": "openai",
"specs": [
[
">=",
"1.82.1"
]
]
},
{
"name": "tavily-python",
"specs": [
[
"==",
"0.7.3"
]
]
},
{
"name": "exa-py",
"specs": [
[
"==",
"1.13.1"
]
]
},
{
"name": "openinference-instrumentation-llama-index",
"specs": [
[
"==",
"4.3.1"
]
]
},
{
"name": "opentelemetry-proto",
"specs": [
[
">=",
"1.31.0"
]
]
},
{
"name": "arize-phoenix",
"specs": [
[
"==",
"10.9.1"
]
]
},
{
"name": "arize-phoenix-otel",
"specs": [
[
"==",
"0.10.3"
]
]
},
{
"name": "protobuf",
"specs": [
[
"==",
"5.29.3"
]
]
},
{
"name": "tokenizers",
"specs": [
[
">=",
"0.20"
]
]
},
{
"name": "pydantic",
"specs": [
[
"==",
"2.11.5"
]
]
},
{
"name": "retrying",
"specs": [
[
"==",
"1.3.4"
]
]
},
{
"name": "python-dotenv",
"specs": [
[
"==",
"1.0.1"
]
]
},
{
"name": "tiktoken",
"specs": [
[
"==",
"0.9.0"
]
]
},
{
"name": "cloudpickle",
"specs": [
[
">=",
"3.1.1"
]
]
},
{
"name": "httpx",
"specs": [
[
"==",
"0.28.1"
]
]
},
{
"name": "commonmark",
"specs": [
[
"==",
"0.9.1"
]
]
}
],
"lcname": "vectara-agentic"
}