mirror of
https://github.com/crewAIInc/crewAI.git
synced 2025-12-16 04:18:35 +00:00
Compare commits
3 Commits
1.2.1
...
devin/1761
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02f9a36acb | ||
|
|
70b083945f | ||
|
|
410db1ff39 |
@@ -93,11 +93,15 @@ After running the application, you can view the traces in [Datadog LLM Observabi
|
||||
|
||||
Clicking on a trace will show you the details of the trace, including total tokens used, number of LLM calls, models used, and estimated cost. Clicking into a specific span will narrow down these details, and show related input, output, and metadata.
|
||||
|
||||

|
||||
<Frame>
|
||||
<img src="/images/datadog-llm-observability-1.png" alt="Datadog LLM Observability Trace View" />
|
||||
</Frame>
|
||||
|
||||
Additionally, you can view the execution graph view of the trace, which shows the control and data flow of the trace, which will scale with larger agents to show handoffs and relationships between LLM calls, tool calls, and agent interactions.
|
||||
|
||||

|
||||
<Frame>
|
||||
<img src="/images/datadog-llm-observability-2.png" alt="Datadog LLM Observability Agent Execution Flow View" />
|
||||
</Frame>
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@@ -23,13 +23,15 @@ Here's a minimal example of how to use the tool:
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai_tools import QdrantVectorSearchTool
|
||||
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
|
||||
|
||||
# Initialize the tool
|
||||
# Initialize the tool with QdrantConfig
|
||||
qdrant_tool = QdrantVectorSearchTool(
|
||||
qdrant_url="your_qdrant_url",
|
||||
qdrant_api_key="your_qdrant_api_key",
|
||||
collection_name="your_collection"
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url="your_qdrant_url",
|
||||
qdrant_api_key="your_qdrant_api_key",
|
||||
collection_name="your_collection"
|
||||
)
|
||||
)
|
||||
|
||||
# Create an agent that uses the tool
|
||||
@@ -82,7 +84,7 @@ def extract_text_from_pdf(pdf_path):
|
||||
def get_openai_embedding(text):
|
||||
response = client.embeddings.create(
|
||||
input=text,
|
||||
model="text-embedding-3-small"
|
||||
model="text-embedding-3-large"
|
||||
)
|
||||
return response.data[0].embedding
|
||||
|
||||
@@ -90,13 +92,13 @@ def get_openai_embedding(text):
|
||||
def load_pdf_to_qdrant(pdf_path, qdrant, collection_name):
|
||||
# Extract text from PDF
|
||||
text_chunks = extract_text_from_pdf(pdf_path)
|
||||
|
||||
|
||||
# Create Qdrant collection
|
||||
if qdrant.collection_exists(collection_name):
|
||||
qdrant.delete_collection(collection_name)
|
||||
qdrant.create_collection(
|
||||
collection_name=collection_name,
|
||||
vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
|
||||
vectors_config=VectorParams(size=3072, distance=Distance.COSINE)
|
||||
)
|
||||
|
||||
# Store embeddings
|
||||
@@ -120,19 +122,23 @@ pdf_path = "path/to/your/document.pdf"
|
||||
load_pdf_to_qdrant(pdf_path, qdrant, collection_name)
|
||||
|
||||
# Initialize Qdrant search tool
|
||||
from crewai_tools import QdrantConfig
|
||||
|
||||
qdrant_tool = QdrantVectorSearchTool(
|
||||
qdrant_url=os.getenv("QDRANT_URL"),
|
||||
qdrant_api_key=os.getenv("QDRANT_API_KEY"),
|
||||
collection_name=collection_name,
|
||||
limit=3,
|
||||
score_threshold=0.35
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url=os.getenv("QDRANT_URL"),
|
||||
qdrant_api_key=os.getenv("QDRANT_API_KEY"),
|
||||
collection_name=collection_name,
|
||||
limit=3,
|
||||
score_threshold=0.35
|
||||
)
|
||||
)
|
||||
|
||||
# Create CrewAI agents
|
||||
search_agent = Agent(
|
||||
role="Senior Semantic Search Agent",
|
||||
goal="Find and analyze documents based on semantic search",
|
||||
backstory="""You are an expert research assistant who can find relevant
|
||||
backstory="""You are an expert research assistant who can find relevant
|
||||
information using semantic search in a Qdrant database.""",
|
||||
tools=[qdrant_tool],
|
||||
verbose=True
|
||||
@@ -141,7 +147,7 @@ search_agent = Agent(
|
||||
answer_agent = Agent(
|
||||
role="Senior Answer Assistant",
|
||||
goal="Generate answers to questions based on the context provided",
|
||||
backstory="""You are an expert answer assistant who can generate
|
||||
backstory="""You are an expert answer assistant who can generate
|
||||
answers to questions based on the context provided.""",
|
||||
tools=[qdrant_tool],
|
||||
verbose=True
|
||||
@@ -180,21 +186,82 @@ print(result)
|
||||
## Tool Parameters
|
||||
|
||||
### Required Parameters
|
||||
- `qdrant_url` (str): The URL of your Qdrant server
|
||||
- `qdrant_api_key` (str): API key for authentication with Qdrant
|
||||
- `collection_name` (str): Name of the Qdrant collection to search
|
||||
- `qdrant_config` (QdrantConfig): Configuration object containing all Qdrant settings
|
||||
|
||||
### Optional Parameters
|
||||
### QdrantConfig Parameters
|
||||
- `qdrant_url` (str): The URL of your Qdrant server
|
||||
- `qdrant_api_key` (str, optional): API key for authentication with Qdrant
|
||||
- `collection_name` (str): Name of the Qdrant collection to search
|
||||
- `limit` (int): Maximum number of results to return (default: 3)
|
||||
- `score_threshold` (float): Minimum similarity score threshold (default: 0.35)
|
||||
- `filter` (Any, optional): Qdrant Filter instance for advanced filtering (default: None)
|
||||
|
||||
### Optional Tool Parameters
|
||||
- `custom_embedding_fn` (Callable[[str], list[float]]): Custom function for text vectorization
|
||||
- `qdrant_package` (str): Base package path for Qdrant (default: "qdrant_client")
|
||||
- `client` (Any): Pre-initialized Qdrant client (optional)
|
||||
|
||||
## Advanced Filtering
|
||||
|
||||
The QdrantVectorSearchTool supports powerful filtering capabilities to refine your search results:
|
||||
|
||||
### Dynamic Filtering
|
||||
Use `filter_by` and `filter_value` parameters in your search to filter results on-the-fly:
|
||||
|
||||
```python
|
||||
# Agent will use these parameters when calling the tool
|
||||
# The tool schema accepts filter_by and filter_value
|
||||
# Example: search with category filter
|
||||
# Results will be filtered where category == "technology"
|
||||
```
|
||||
|
||||
### Preset Filters with QdrantConfig
|
||||
For complex filtering, use Qdrant Filter instances in your configuration:
|
||||
|
||||
```python
|
||||
from qdrant_client.http import models as qmodels
|
||||
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
|
||||
|
||||
# Create a filter for specific conditions
|
||||
preset_filter = qmodels.Filter(
|
||||
must=[
|
||||
qmodels.FieldCondition(
|
||||
key="category",
|
||||
match=qmodels.MatchValue(value="research")
|
||||
),
|
||||
qmodels.FieldCondition(
|
||||
key="year",
|
||||
match=qmodels.MatchValue(value=2024)
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
# Initialize tool with preset filter
|
||||
qdrant_tool = QdrantVectorSearchTool(
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url="your_url",
|
||||
qdrant_api_key="your_key",
|
||||
collection_name="your_collection",
|
||||
filter=preset_filter # Preset filter applied to all searches
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Combining Filters
|
||||
The tool automatically combines preset filters from `QdrantConfig` with dynamic filters from `filter_by` and `filter_value`:
|
||||
|
||||
```python
|
||||
# If QdrantConfig has a preset filter for category="research"
|
||||
# And the search uses filter_by="year", filter_value=2024
|
||||
# Both filters will be combined (AND logic)
|
||||
```
|
||||
|
||||
## Search Parameters
|
||||
|
||||
The tool accepts these parameters in its schema:
|
||||
- `query` (str): The search query to find similar documents
|
||||
- `filter_by` (str, optional): Metadata field to filter on
|
||||
- `filter_value` (str, optional): Value to filter by
|
||||
- `filter_value` (Any, optional): Value to filter by
|
||||
|
||||
## Return Format
|
||||
|
||||
@@ -214,7 +281,7 @@ The tool returns results in JSON format:
|
||||
|
||||
## Default Embedding
|
||||
|
||||
By default, the tool uses OpenAI's `text-embedding-3-small` model for vectorization. This requires:
|
||||
By default, the tool uses OpenAI's `text-embedding-3-large` model for vectorization. This requires:
|
||||
- OpenAI API key set in environment: `OPENAI_API_KEY`
|
||||
|
||||
## Custom Embeddings
|
||||
@@ -240,18 +307,22 @@ def custom_embeddings(text: str) -> list[float]:
|
||||
# Tokenize and get model outputs
|
||||
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
|
||||
outputs = model(**inputs)
|
||||
|
||||
|
||||
# Use mean pooling to get text embedding
|
||||
embeddings = outputs.last_hidden_state.mean(dim=1)
|
||||
|
||||
|
||||
# Convert to list of floats and return
|
||||
return embeddings[0].tolist()
|
||||
|
||||
# Use custom embeddings with the tool
|
||||
from crewai_tools import QdrantConfig
|
||||
|
||||
tool = QdrantVectorSearchTool(
|
||||
qdrant_url="your_url",
|
||||
qdrant_api_key="your_key",
|
||||
collection_name="your_collection",
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url="your_url",
|
||||
qdrant_api_key="your_key",
|
||||
collection_name="your_collection"
|
||||
),
|
||||
custom_embedding_fn=custom_embeddings # Pass your custom function
|
||||
)
|
||||
```
|
||||
@@ -269,4 +340,4 @@ Required environment variables:
|
||||
```bash
|
||||
export QDRANT_URL="your_qdrant_url" # If not provided in constructor
|
||||
export QDRANT_API_KEY="your_api_key" # If not provided in constructor
|
||||
export OPENAI_API_KEY="your_openai_key" # If using default embeddings
|
||||
export OPENAI_API_KEY="your_openai_key" # If using default embeddings
|
||||
|
||||
@@ -54,25 +54,25 @@ The following parameters can be used to customize the `CSVSearchTool`'s behavior
|
||||
By default, the tool uses OpenAI for both embeddings and summarization. To customize the model, you can use a config dictionary as follows:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = CSVSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # or "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -46,23 +46,25 @@ tool = DirectorySearchTool(directory='/path/to/directory')
|
||||
The DirectorySearchTool uses OpenAI for embeddings and summarization by default. Customization options for these settings include changing the model provider and configuration, enhancing flexibility for advanced users.
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = DirectorySearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # Options include ollama, google, anthropic, llama2, and more
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# Additional configurations here
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # or "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -56,25 +56,25 @@ The following parameters can be used to customize the `DOCXSearchTool`'s behavio
|
||||
By default, the tool uses OpenAI for both embeddings and summarization. To customize the model, you can use a config dictionary as follows:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = DOCXSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # or "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -48,27 +48,25 @@ tool = MDXSearchTool(mdx='path/to/your/document.mdx')
|
||||
The tool defaults to using OpenAI for embeddings and summarization. For customization, utilize a configuration dictionary as shown below:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = MDXSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # Options include google, openai, anthropic, llama2, etc.
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# Optional parameters can be included here.
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# Optional title for the embeddings can be added here.
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # or "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -45,28 +45,64 @@ tool = PDFSearchTool(pdf='path/to/your/document.pdf')
|
||||
|
||||
## Custom model and embeddings
|
||||
|
||||
By default, the tool uses OpenAI for both embeddings and summarization. To customize the model, you can use a config dictionary as follows:
|
||||
By default, the tool uses OpenAI for both embeddings and summarization. To customize the model, you can use a config dictionary as follows. Note: a vector database is required because generated embeddings must be stored and queried from a vectordb.
|
||||
|
||||
```python Code
|
||||
from crewai_tools import PDFSearchTool
|
||||
|
||||
# - embedding_model (required): choose provider + provider-specific config
|
||||
# - vectordb (required): choose vector DB and pass its config
|
||||
|
||||
tool = PDFSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
# Supported providers: "openai", "azure", "google-generativeai", "google-vertex",
|
||||
# "voyageai", "cohere", "huggingface", "jina", "sentence-transformer",
|
||||
# "text2vec", "ollama", "openclip", "instructor", "onnx", "roboflow", "watsonx", "custom"
|
||||
"provider": "openai", # or: "google-generativeai", "cohere", "ollama", ...
|
||||
"config": {
|
||||
# Model identifier for the chosen provider. "model" will be auto-mapped to "model_name" internally.
|
||||
"model": "text-embedding-3-small",
|
||||
# Optional: API key. If omitted, the tool will use provider-specific env vars when available
|
||||
# (e.g., OPENAI_API_KEY for provider="openai").
|
||||
# "api_key": "sk-...",
|
||||
|
||||
# Provider-specific examples:
|
||||
# --- Google Generative AI ---
|
||||
# (Set provider="google-generativeai" above)
|
||||
# "model": "models/embedding-001",
|
||||
# "task_type": "retrieval_document",
|
||||
# "title": "Embeddings",
|
||||
|
||||
# --- Cohere ---
|
||||
# (Set provider="cohere" above)
|
||||
# "model": "embed-english-v3.0",
|
||||
|
||||
# --- Ollama (local) ---
|
||||
# (Set provider="ollama" above)
|
||||
# "model": "nomic-embed-text",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # or "qdrant"
|
||||
"config": {
|
||||
# For ChromaDB: pass "settings" (chromadb.config.Settings) or rely on defaults.
|
||||
# Example (uncomment and import):
|
||||
# from chromadb.config import Settings
|
||||
# "settings": Settings(
|
||||
# persist_directory="/content/chroma",
|
||||
# allow_reset=True,
|
||||
# is_persistent=True,
|
||||
# ),
|
||||
|
||||
# For Qdrant: pass "vectors_config" (qdrant_client.models.VectorParams).
|
||||
# Example (uncomment and import):
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
|
||||
# Note: collection name is controlled by the tool (default: "rag_tool_collection"), not set here.
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -57,25 +57,41 @@ By default, the tool uses OpenAI for both embeddings and summarization.
|
||||
To customize the model, you can use a config dictionary as follows:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = TXTSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
# Required: embeddings provider + config
|
||||
"embedding_model": {
|
||||
"provider": "openai", # or google-generativeai, cohere, ollama, ...
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...", # optional if env var is set
|
||||
# Provider examples:
|
||||
# Google → model: "models/embedding-001", task_type: "retrieval_document"
|
||||
# Cohere → model: "embed-english-v3.0"
|
||||
# Ollama → model: "nomic-embed-text"
|
||||
},
|
||||
},
|
||||
|
||||
# Required: vector database config
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # or "qdrant"
|
||||
"config": {
|
||||
# Chroma settings (optional persistence)
|
||||
# "settings": Settings(
|
||||
# persist_directory="/content/chroma",
|
||||
# allow_reset=True,
|
||||
# is_persistent=True,
|
||||
# ),
|
||||
|
||||
# Qdrant vector params example:
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
|
||||
# Note: collection name is controlled by the tool (default: "rag_tool_collection").
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -54,25 +54,25 @@ It is an optional parameter during the tool's initialization but must be provide
|
||||
By default, the tool uses OpenAI for both embeddings and summarization. To customize the model, you can use a config dictionary as follows:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = XMLSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # or "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -93,11 +93,15 @@ ddtrace-run python crewai_agent.py
|
||||
|
||||
트레이스를 클릭하면 사용된 총 토큰, LLM 호출 수, 사용된 모델, 예상 비용 등 트레이스에 대한 세부 정보가 표시됩니다. 특정 스팬(span)을 클릭하면 이러한 세부 정보의 범위가 좁혀지고 관련 입력, 출력 및 메타데이터가 표시됩니다.
|
||||
|
||||

|
||||
<Frame>
|
||||
<img src="/images/datadog-llm-observability-1.png" alt="Datadog LLM 옵저버빌리티 추적 보기" />
|
||||
</Frame>
|
||||
|
||||
또한, 트레이스의 제어 및 데이터 흐름을 보여주는 트레이스의 실행 그래프 보기를 볼 수 있으며, 이는 더 큰 에이전트로 확장하여 LLM 호출, 도구 호출 및 에이전트 상호 작용 간의 핸드오프와 관계를 보여줍니다.
|
||||
|
||||

|
||||
<Frame>
|
||||
<img src="/images/datadog-llm-observability-2.png" alt="Datadog LLM Observability 에이전트 실행 흐름 보기" />
|
||||
</Frame>
|
||||
|
||||
## 참조
|
||||
|
||||
|
||||
@@ -23,13 +23,15 @@ uv add qdrant-client
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai_tools import QdrantVectorSearchTool
|
||||
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
|
||||
|
||||
# Initialize the tool
|
||||
# QdrantConfig로 도구 초기화
|
||||
qdrant_tool = QdrantVectorSearchTool(
|
||||
qdrant_url="your_qdrant_url",
|
||||
qdrant_api_key="your_qdrant_api_key",
|
||||
collection_name="your_collection"
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url="your_qdrant_url",
|
||||
qdrant_api_key="your_qdrant_api_key",
|
||||
collection_name="your_collection"
|
||||
)
|
||||
)
|
||||
|
||||
# Create an agent that uses the tool
|
||||
@@ -82,7 +84,7 @@ def extract_text_from_pdf(pdf_path):
|
||||
def get_openai_embedding(text):
|
||||
response = client.embeddings.create(
|
||||
input=text,
|
||||
model="text-embedding-3-small"
|
||||
model="text-embedding-3-large"
|
||||
)
|
||||
return response.data[0].embedding
|
||||
|
||||
@@ -90,13 +92,13 @@ def get_openai_embedding(text):
|
||||
def load_pdf_to_qdrant(pdf_path, qdrant, collection_name):
|
||||
# Extract text from PDF
|
||||
text_chunks = extract_text_from_pdf(pdf_path)
|
||||
|
||||
|
||||
# Create Qdrant collection
|
||||
if qdrant.collection_exists(collection_name):
|
||||
qdrant.delete_collection(collection_name)
|
||||
qdrant.create_collection(
|
||||
collection_name=collection_name,
|
||||
vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
|
||||
vectors_config=VectorParams(size=3072, distance=Distance.COSINE)
|
||||
)
|
||||
|
||||
# Store embeddings
|
||||
@@ -120,19 +122,23 @@ pdf_path = "path/to/your/document.pdf"
|
||||
load_pdf_to_qdrant(pdf_path, qdrant, collection_name)
|
||||
|
||||
# Initialize Qdrant search tool
|
||||
from crewai_tools import QdrantConfig
|
||||
|
||||
qdrant_tool = QdrantVectorSearchTool(
|
||||
qdrant_url=os.getenv("QDRANT_URL"),
|
||||
qdrant_api_key=os.getenv("QDRANT_API_KEY"),
|
||||
collection_name=collection_name,
|
||||
limit=3,
|
||||
score_threshold=0.35
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url=os.getenv("QDRANT_URL"),
|
||||
qdrant_api_key=os.getenv("QDRANT_API_KEY"),
|
||||
collection_name=collection_name,
|
||||
limit=3,
|
||||
score_threshold=0.35
|
||||
)
|
||||
)
|
||||
|
||||
# Create CrewAI agents
|
||||
search_agent = Agent(
|
||||
role="Senior Semantic Search Agent",
|
||||
goal="Find and analyze documents based on semantic search",
|
||||
backstory="""You are an expert research assistant who can find relevant
|
||||
backstory="""You are an expert research assistant who can find relevant
|
||||
information using semantic search in a Qdrant database.""",
|
||||
tools=[qdrant_tool],
|
||||
verbose=True
|
||||
@@ -141,7 +147,7 @@ search_agent = Agent(
|
||||
answer_agent = Agent(
|
||||
role="Senior Answer Assistant",
|
||||
goal="Generate answers to questions based on the context provided",
|
||||
backstory="""You are an expert answer assistant who can generate
|
||||
backstory="""You are an expert answer assistant who can generate
|
||||
answers to questions based on the context provided.""",
|
||||
tools=[qdrant_tool],
|
||||
verbose=True
|
||||
@@ -180,21 +186,82 @@ print(result)
|
||||
## 도구 매개변수
|
||||
|
||||
### 필수 파라미터
|
||||
- `qdrant_url` (str): Qdrant 서버의 URL
|
||||
- `qdrant_api_key` (str): Qdrant 인증을 위한 API 키
|
||||
- `collection_name` (str): 검색할 Qdrant 컬렉션의 이름
|
||||
- `qdrant_config` (QdrantConfig): 모든 Qdrant 설정을 포함하는 구성 객체
|
||||
|
||||
### 선택적 매개변수
|
||||
### QdrantConfig 매개변수
|
||||
- `qdrant_url` (str): Qdrant 서버의 URL
|
||||
- `qdrant_api_key` (str, 선택 사항): Qdrant 인증을 위한 API 키
|
||||
- `collection_name` (str): 검색할 Qdrant 컬렉션의 이름
|
||||
- `limit` (int): 반환할 최대 결과 수 (기본값: 3)
|
||||
- `score_threshold` (float): 최소 유사도 점수 임계값 (기본값: 0.35)
|
||||
- `filter` (Any, 선택 사항): 고급 필터링을 위한 Qdrant Filter 인스턴스 (기본값: None)
|
||||
|
||||
### 선택적 도구 매개변수
|
||||
- `custom_embedding_fn` (Callable[[str], list[float]]): 텍스트 벡터화를 위한 사용자 지정 함수
|
||||
- `qdrant_package` (str): Qdrant의 기본 패키지 경로 (기본값: "qdrant_client")
|
||||
- `client` (Any): 사전 초기화된 Qdrant 클라이언트 (선택 사항)
|
||||
|
||||
## 고급 필터링
|
||||
|
||||
QdrantVectorSearchTool은 검색 결과를 세밀하게 조정할 수 있는 강력한 필터링 기능을 지원합니다:
|
||||
|
||||
### 동적 필터링
|
||||
검색 시 `filter_by` 및 `filter_value` 매개변수를 사용하여 즉석에서 결과를 필터링할 수 있습니다:
|
||||
|
||||
```python
|
||||
# 에이전트는 도구를 호출할 때 이러한 매개변수를 사용합니다
|
||||
# 도구 스키마는 filter_by 및 filter_value를 허용합니다
|
||||
# 예시: 카테고리 필터를 사용한 검색
|
||||
# 결과는 category == "기술"인 항목으로 필터링됩니다
|
||||
```
|
||||
|
||||
### QdrantConfig를 사용한 사전 설정 필터
|
||||
복잡한 필터링의 경우 구성에서 Qdrant Filter 인스턴스를 사용하세요:
|
||||
|
||||
```python
|
||||
from qdrant_client.http import models as qmodels
|
||||
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
|
||||
|
||||
# 특정 조건에 대한 필터 생성
|
||||
preset_filter = qmodels.Filter(
|
||||
must=[
|
||||
qmodels.FieldCondition(
|
||||
key="category",
|
||||
match=qmodels.MatchValue(value="research")
|
||||
),
|
||||
qmodels.FieldCondition(
|
||||
key="year",
|
||||
match=qmodels.MatchValue(value=2024)
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
# 사전 설정 필터로 도구 초기화
|
||||
qdrant_tool = QdrantVectorSearchTool(
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url="your_url",
|
||||
qdrant_api_key="your_key",
|
||||
collection_name="your_collection",
|
||||
filter=preset_filter # 모든 검색에 적용되는 사전 설정 필터
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### 필터 결합
|
||||
도구는 `QdrantConfig`의 사전 설정 필터와 `filter_by` 및 `filter_value`의 동적 필터를 자동으로 결합합니다:
|
||||
|
||||
```python
|
||||
# QdrantConfig에 category="research"에 대한 사전 설정 필터가 있고
|
||||
# 검색에서 filter_by="year", filter_value=2024를 사용하는 경우
|
||||
# 두 필터가 모두 결합됩니다 (AND 논리)
|
||||
```
|
||||
|
||||
## 검색 매개변수
|
||||
|
||||
이 도구는 스키마에서 다음과 같은 매개변수를 허용합니다:
|
||||
- `query` (str): 유사한 문서를 찾기 위한 검색 쿼리
|
||||
- `filter_by` (str, 선택 사항): 필터링할 메타데이터 필드
|
||||
- `filter_value` (str, 선택 사항): 필터 기준 값
|
||||
- `filter_value` (Any, 선택 사항): 필터 기준 값
|
||||
|
||||
## 반환 형식
|
||||
|
||||
@@ -214,7 +281,7 @@ print(result)
|
||||
|
||||
## 기본 임베딩
|
||||
|
||||
기본적으로, 이 도구는 벡터화를 위해 OpenAI의 `text-embedding-3-small` 모델을 사용합니다. 이를 위해서는 다음이 필요합니다:
|
||||
기본적으로, 이 도구는 벡터화를 위해 OpenAI의 `text-embedding-3-large` 모델을 사용합니다. 이를 위해서는 다음이 필요합니다:
|
||||
- 환경변수에 설정된 OpenAI API 키: `OPENAI_API_KEY`
|
||||
|
||||
## 커스텀 임베딩
|
||||
@@ -240,18 +307,22 @@ def custom_embeddings(text: str) -> list[float]:
|
||||
# Tokenize and get model outputs
|
||||
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
|
||||
outputs = model(**inputs)
|
||||
|
||||
|
||||
# Use mean pooling to get text embedding
|
||||
embeddings = outputs.last_hidden_state.mean(dim=1)
|
||||
|
||||
|
||||
# Convert to list of floats and return
|
||||
return embeddings[0].tolist()
|
||||
|
||||
# Use custom embeddings with the tool
|
||||
from crewai_tools import QdrantConfig
|
||||
|
||||
tool = QdrantVectorSearchTool(
|
||||
qdrant_url="your_url",
|
||||
qdrant_api_key="your_key",
|
||||
collection_name="your_collection",
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url="your_url",
|
||||
qdrant_api_key="your_key",
|
||||
collection_name="your_collection"
|
||||
),
|
||||
custom_embedding_fn=custom_embeddings # Pass your custom function
|
||||
)
|
||||
```
|
||||
@@ -270,4 +341,4 @@ tool = QdrantVectorSearchTool(
|
||||
export QDRANT_URL="your_qdrant_url" # If not provided in constructor
|
||||
export QDRANT_API_KEY="your_api_key" # If not provided in constructor
|
||||
export OPENAI_API_KEY="your_openai_key" # If using default embeddings
|
||||
```
|
||||
```
|
||||
|
||||
@@ -54,25 +54,25 @@ tool = CSVSearchTool()
|
||||
기본적으로 이 도구는 임베딩과 요약 모두에 OpenAI를 사용합니다. 모델을 사용자 지정하려면 다음과 같이 config 딕셔너리를 사용할 수 있습니다:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = CSVSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # 또는 "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -46,23 +46,25 @@ tool = DirectorySearchTool(directory='/path/to/directory')
|
||||
DirectorySearchTool은 기본적으로 OpenAI를 사용하여 임베딩 및 요약을 수행합니다. 이 설정의 커스터마이즈 옵션에는 모델 공급자 및 구성을 변경하는 것이 포함되어 있어, 고급 사용자를 위한 유연성을 향상시킵니다.
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = DirectorySearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # Options include ollama, google, anthropic, llama2, and more
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# Additional configurations here
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # 또는 "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -56,25 +56,25 @@ tool = DOCXSearchTool(docx='path/to/your/document.docx')
|
||||
기본적으로 이 도구는 임베딩과 요약 모두에 OpenAI를 사용합니다. 모델을 커스터마이즈하려면 다음과 같이 config 딕셔너리를 사용할 수 있습니다:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = DOCXSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # 또는 "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -48,27 +48,25 @@ tool = MDXSearchTool(mdx='path/to/your/document.mdx')
|
||||
이 도구는 기본적으로 임베딩과 요약을 위해 OpenAI를 사용합니다. 커스터마이징을 위해 아래와 같이 설정 딕셔너리를 사용할 수 있습니다.
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = MDXSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # 옵션에는 google, openai, anthropic, llama2 등이 있습니다.
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# 선택적 파라미터를 여기에 포함할 수 있습니다.
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # 또는 openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# 임베딩에 대한 선택적 제목을 여기에 추가할 수 있습니다.
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # 또는 "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -45,28 +45,60 @@ tool = PDFSearchTool(pdf='path/to/your/document.pdf')
|
||||
|
||||
## 커스텀 모델 및 임베딩
|
||||
|
||||
기본적으로 이 도구는 임베딩과 요약 모두에 OpenAI를 사용합니다. 모델을 커스터마이즈하려면 다음과 같이 config 딕셔너리를 사용할 수 있습니다:
|
||||
기본적으로 이 도구는 임베딩과 요약 모두에 OpenAI를 사용합니다. 모델을 커스터마이즈하려면 다음과 같이 config 딕셔너리를 사용할 수 있습니다. 참고: 임베딩은 벡터DB에 저장되어야 하므로 vectordb 설정이 필요합니다.
|
||||
|
||||
```python Code
|
||||
from crewai_tools import PDFSearchTool
|
||||
from chromadb.config import Settings # Chroma 영속성 설정
|
||||
|
||||
tool = PDFSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
# 필수: 임베딩 제공자와 설정
|
||||
"embedding_model": {
|
||||
# 사용 가능 공급자: "openai", "azure", "google-generativeai", "google-vertex",
|
||||
# "voyageai", "cohere", "huggingface", "jina", "sentence-transformer",
|
||||
# "text2vec", "ollama", "openclip", "instructor", "onnx", "roboflow", "watsonx", "custom"
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
# "model" 키는 내부적으로 "model_name"으로 매핑됩니다.
|
||||
"model": "text-embedding-3-small",
|
||||
# 선택: API 키 (미설정 시 환경변수 사용)
|
||||
# "api_key": "sk-...",
|
||||
|
||||
# 공급자별 예시
|
||||
# --- Google ---
|
||||
# (provider를 "google-generativeai"로 설정)
|
||||
# "model": "models/embedding-001",
|
||||
# "task_type": "retrieval_document",
|
||||
|
||||
# --- Cohere ---
|
||||
# (provider를 "cohere"로 설정)
|
||||
# "model": "embed-english-v3.0",
|
||||
|
||||
# --- Ollama(로컬) ---
|
||||
# (provider를 "ollama"로 설정)
|
||||
# "model": "nomic-embed-text",
|
||||
},
|
||||
},
|
||||
|
||||
# 필수: 벡터DB 설정
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # 또는 "qdrant"
|
||||
"config": {
|
||||
# Chroma 설정 예시
|
||||
# "settings": Settings(
|
||||
# persist_directory="/content/chroma",
|
||||
# allow_reset=True,
|
||||
# is_persistent=True,
|
||||
# ),
|
||||
|
||||
# Qdrant 설정 예시
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
|
||||
# 참고: 컬렉션 이름은 도구에서 관리합니다(기본값: "rag_tool_collection").
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -57,25 +57,34 @@ tool = TXTSearchTool(txt='path/to/text/file.txt')
|
||||
모델을 커스터마이징하려면 다음과 같이 config 딕셔너리를 사용할 수 있습니다:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = TXTSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
# 필수: 임베딩 제공자 + 설정
|
||||
"embedding_model": {
|
||||
"provider": "openai", # 또는 google-generativeai, cohere, ollama 등
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...", # 환경변수 사용 시 생략 가능
|
||||
# 공급자별 예시: Google → model: "models/embedding-001", task_type: "retrieval_document"
|
||||
},
|
||||
},
|
||||
|
||||
# 필수: 벡터DB 설정
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # 또는 "qdrant"
|
||||
"config": {
|
||||
# Chroma 설정(영속성 예시)
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
|
||||
# Qdrant 벡터 파라미터 예시:
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
|
||||
# 참고: 컬렉션 이름은 도구에서 관리합니다(기본값: "rag_tool_collection").
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -54,25 +54,25 @@ tool = XMLSearchTool(xml='path/to/your/xmlfile.xml')
|
||||
기본적으로 이 도구는 임베딩과 요약 모두에 OpenAI를 사용합니다. 모델을 커스터마이징하려면 다음과 같이 config 딕셔너리를 사용할 수 있습니다.
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = XMLSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # or google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # or openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # 또는 "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
@@ -93,11 +93,14 @@ Depois de executar o aplicativo, você pode visualizar os traços na [Datadog LL
|
||||
|
||||
Ao clicar em um rastreamento, você verá os detalhes do rastreamento, incluindo o total de tokens usados, o número de chamadas LLM, os modelos usados e o custo estimado. Clicar em um intervalo específico reduzirá esses detalhes e mostrará a entrada, a saída e os metadados relacionados.
|
||||
|
||||

|
||||
|
||||
<Frame>
|
||||
<img src="/images/datadog-llm-observability-1.png" alt="Visualização do rastreamento de observabilidade do Datadog LLM" />
|
||||
</Frame>
|
||||
Além disso, você pode visualizar a visualização do gráfico de execução do rastreamento, que mostra o controle e o fluxo de dados do rastreamento, que será dimensionado com agentes maiores para mostrar transferências e relacionamentos entre chamadas LLM, chamadas de ferramentas e interações de agentes.
|
||||
|
||||

|
||||
<Frame>
|
||||
<img src="/images/datadog-llm-observability-2.png" alt="Visualização do fluxo de execução do agente de observabilidade do Datadog LLM" />
|
||||
</Frame>
|
||||
|
||||
## Referências
|
||||
|
||||
|
||||
@@ -23,13 +23,15 @@ Veja um exemplo mínimo de como utilizar a ferramenta:
|
||||
|
||||
```python
|
||||
from crewai import Agent
|
||||
from crewai_tools import QdrantVectorSearchTool
|
||||
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
|
||||
|
||||
# Inicialize a ferramenta
|
||||
# Inicialize a ferramenta com QdrantConfig
|
||||
qdrant_tool = QdrantVectorSearchTool(
|
||||
qdrant_url="your_qdrant_url",
|
||||
qdrant_api_key="your_qdrant_api_key",
|
||||
collection_name="your_collection"
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url="your_qdrant_url",
|
||||
qdrant_api_key="your_qdrant_api_key",
|
||||
collection_name="your_collection"
|
||||
)
|
||||
)
|
||||
|
||||
# Crie um agente que utiliza a ferramenta
|
||||
@@ -82,7 +84,7 @@ def extract_text_from_pdf(pdf_path):
|
||||
def get_openai_embedding(text):
|
||||
response = client.embeddings.create(
|
||||
input=text,
|
||||
model="text-embedding-3-small"
|
||||
model="text-embedding-3-large"
|
||||
)
|
||||
return response.data[0].embedding
|
||||
|
||||
@@ -90,13 +92,13 @@ def get_openai_embedding(text):
|
||||
def load_pdf_to_qdrant(pdf_path, qdrant, collection_name):
|
||||
# Extrair texto do PDF
|
||||
text_chunks = extract_text_from_pdf(pdf_path)
|
||||
|
||||
|
||||
# Criar coleção no Qdrant
|
||||
if qdrant.collection_exists(collection_name):
|
||||
qdrant.delete_collection(collection_name)
|
||||
qdrant.create_collection(
|
||||
collection_name=collection_name,
|
||||
vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
|
||||
vectors_config=VectorParams(size=3072, distance=Distance.COSINE)
|
||||
)
|
||||
|
||||
# Armazenar embeddings
|
||||
@@ -120,19 +122,23 @@ pdf_path = "path/to/your/document.pdf"
|
||||
load_pdf_to_qdrant(pdf_path, qdrant, collection_name)
|
||||
|
||||
# Inicializar ferramenta de busca Qdrant
|
||||
from crewai_tools import QdrantConfig
|
||||
|
||||
qdrant_tool = QdrantVectorSearchTool(
|
||||
qdrant_url=os.getenv("QDRANT_URL"),
|
||||
qdrant_api_key=os.getenv("QDRANT_API_KEY"),
|
||||
collection_name=collection_name,
|
||||
limit=3,
|
||||
score_threshold=0.35
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url=os.getenv("QDRANT_URL"),
|
||||
qdrant_api_key=os.getenv("QDRANT_API_KEY"),
|
||||
collection_name=collection_name,
|
||||
limit=3,
|
||||
score_threshold=0.35
|
||||
)
|
||||
)
|
||||
|
||||
# Criar agentes CrewAI
|
||||
search_agent = Agent(
|
||||
role="Senior Semantic Search Agent",
|
||||
goal="Find and analyze documents based on semantic search",
|
||||
backstory="""You are an expert research assistant who can find relevant
|
||||
backstory="""You are an expert research assistant who can find relevant
|
||||
information using semantic search in a Qdrant database.""",
|
||||
tools=[qdrant_tool],
|
||||
verbose=True
|
||||
@@ -141,7 +147,7 @@ search_agent = Agent(
|
||||
answer_agent = Agent(
|
||||
role="Senior Answer Assistant",
|
||||
goal="Generate answers to questions based on the context provided",
|
||||
backstory="""You are an expert answer assistant who can generate
|
||||
backstory="""You are an expert answer assistant who can generate
|
||||
answers to questions based on the context provided.""",
|
||||
tools=[qdrant_tool],
|
||||
verbose=True
|
||||
@@ -180,21 +186,82 @@ print(result)
|
||||
## Parâmetros da Ferramenta
|
||||
|
||||
### Parâmetros Obrigatórios
|
||||
- `qdrant_url` (str): URL do seu servidor Qdrant
|
||||
- `qdrant_api_key` (str): Chave de API para autenticação com o Qdrant
|
||||
- `collection_name` (str): Nome da coleção Qdrant a ser pesquisada
|
||||
- `qdrant_config` (QdrantConfig): Objeto de configuração contendo todas as configurações do Qdrant
|
||||
|
||||
### Parâmetros Opcionais
|
||||
### Parâmetros do QdrantConfig
|
||||
- `qdrant_url` (str): URL do seu servidor Qdrant
|
||||
- `qdrant_api_key` (str, opcional): Chave de API para autenticação com o Qdrant
|
||||
- `collection_name` (str): Nome da coleção Qdrant a ser pesquisada
|
||||
- `limit` (int): Número máximo de resultados a serem retornados (padrão: 3)
|
||||
- `score_threshold` (float): Limite mínimo de similaridade (padrão: 0.35)
|
||||
- `filter` (Any, opcional): Instância de Filter do Qdrant para filtragem avançada (padrão: None)
|
||||
|
||||
### Parâmetros Opcionais da Ferramenta
|
||||
- `custom_embedding_fn` (Callable[[str], list[float]]): Função personalizada para vetorização de textos
|
||||
- `qdrant_package` (str): Caminho base do pacote Qdrant (padrão: "qdrant_client")
|
||||
- `client` (Any): Cliente Qdrant pré-inicializado (opcional)
|
||||
|
||||
## Filtragem Avançada
|
||||
|
||||
A ferramenta QdrantVectorSearchTool oferece recursos poderosos de filtragem para refinar os resultados da busca:
|
||||
|
||||
### Filtragem Dinâmica
|
||||
Use os parâmetros `filter_by` e `filter_value` na sua busca para filtrar resultados dinamicamente:
|
||||
|
||||
```python
|
||||
# O agente usará esses parâmetros ao chamar a ferramenta
|
||||
# O schema da ferramenta aceita filter_by e filter_value
|
||||
# Exemplo: busca com filtro de categoria
|
||||
# Os resultados serão filtrados onde categoria == "tecnologia"
|
||||
```
|
||||
|
||||
### Filtros Pré-definidos com QdrantConfig
|
||||
Para filtragens complexas, use instâncias de Filter do Qdrant na sua configuração:
|
||||
|
||||
```python
|
||||
from qdrant_client.http import models as qmodels
|
||||
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
|
||||
|
||||
# Criar um filtro para condições específicas
|
||||
preset_filter = qmodels.Filter(
|
||||
must=[
|
||||
qmodels.FieldCondition(
|
||||
key="categoria",
|
||||
match=qmodels.MatchValue(value="pesquisa")
|
||||
),
|
||||
qmodels.FieldCondition(
|
||||
key="ano",
|
||||
match=qmodels.MatchValue(value=2024)
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
# Inicializar ferramenta com filtro pré-definido
|
||||
qdrant_tool = QdrantVectorSearchTool(
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url="your_url",
|
||||
qdrant_api_key="your_key",
|
||||
collection_name="your_collection",
|
||||
filter=preset_filter # Filtro pré-definido aplicado a todas as buscas
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Combinando Filtros
|
||||
A ferramenta combina automaticamente os filtros pré-definidos do `QdrantConfig` com os filtros dinâmicos de `filter_by` e `filter_value`:
|
||||
|
||||
```python
|
||||
# Se QdrantConfig tem um filtro pré-definido para categoria="pesquisa"
|
||||
# E a busca usa filter_by="ano", filter_value=2024
|
||||
# Ambos os filtros serão combinados (lógica AND)
|
||||
```
|
||||
|
||||
## Parâmetros de Busca
|
||||
|
||||
A ferramenta aceita estes parâmetros em seu schema:
|
||||
- `query` (str): Consulta de busca para encontrar documentos similares
|
||||
- `filter_by` (str, opcional): Campo de metadado para filtrar
|
||||
- `filter_value` (str, opcional): Valor para filtrar
|
||||
- `filter_value` (Any, opcional): Valor para filtrar
|
||||
|
||||
## Formato de Retorno
|
||||
|
||||
@@ -214,7 +281,7 @@ A ferramenta retorna resultados no formato JSON:
|
||||
|
||||
## Embedding Padrão
|
||||
|
||||
Por padrão, a ferramenta utiliza o modelo `text-embedding-3-small` da OpenAI para vetorização. Isso requer:
|
||||
Por padrão, a ferramenta utiliza o modelo `text-embedding-3-large` da OpenAI para vetorização. Isso requer:
|
||||
- Chave de API da OpenAI definida na variável de ambiente: `OPENAI_API_KEY`
|
||||
|
||||
## Embeddings Personalizados
|
||||
@@ -240,18 +307,22 @@ def custom_embeddings(text: str) -> list[float]:
|
||||
# Tokenizar e obter saídas do modelo
|
||||
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
|
||||
outputs = model(**inputs)
|
||||
|
||||
|
||||
# Usar mean pooling para obter o embedding do texto
|
||||
embeddings = outputs.last_hidden_state.mean(dim=1)
|
||||
|
||||
|
||||
# Converter para lista de floats e retornar
|
||||
return embeddings[0].tolist()
|
||||
|
||||
# Usar embeddings personalizados com a ferramenta
|
||||
from crewai_tools import QdrantConfig
|
||||
|
||||
tool = QdrantVectorSearchTool(
|
||||
qdrant_url="your_url",
|
||||
qdrant_api_key="your_key",
|
||||
collection_name="your_collection",
|
||||
qdrant_config=QdrantConfig(
|
||||
qdrant_url="your_url",
|
||||
qdrant_api_key="your_key",
|
||||
collection_name="your_collection"
|
||||
),
|
||||
custom_embedding_fn=custom_embeddings # Passe sua função personalizada
|
||||
)
|
||||
```
|
||||
@@ -270,4 +341,4 @@ Variáveis de ambiente obrigatórias:
|
||||
export QDRANT_URL="your_qdrant_url" # Se não for informado no construtor
|
||||
export QDRANT_API_KEY="your_api_key" # Se não for informado no construtor
|
||||
export OPENAI_API_KEY="your_openai_key" # Se estiver usando embeddings padrão
|
||||
```
|
||||
```
|
||||
|
||||
@@ -46,23 +46,25 @@ tool = DirectorySearchTool(directory='/path/to/directory')
|
||||
O DirectorySearchTool utiliza OpenAI para embeddings e sumarização por padrão. As opções de personalização dessas configurações incluem a alteração do provedor de modelo e configurações, ampliando a flexibilidade para usuários avançados.
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = DirectorySearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # As opções incluem ollama, google, anthropic, llama2 e mais
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# Configurações adicionais aqui
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # ou openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # ou "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -56,25 +56,25 @@ Os seguintes parâmetros podem ser usados para customizar o comportamento da `DO
|
||||
Por padrão, a ferramenta utiliza o OpenAI tanto para embeddings quanto para sumarização. Para customizar o modelo, você pode usar um dicionário de configuração como no exemplo:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = DOCXSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # ou google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # ou openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # ou "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -48,27 +48,25 @@ tool = MDXSearchTool(mdx='path/to/your/document.mdx')
|
||||
A ferramenta utiliza, por padrão, o OpenAI para embeddings e sumarização. Para personalizar, utilize um dicionário de configuração conforme exemplo abaixo:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = MDXSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # As opções incluem google, openai, anthropic, llama2, etc.
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# Parâmetros opcionais podem ser incluídos aqui.
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # ou openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# Um título opcional para os embeddings pode ser adicionado aqui.
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # ou "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -45,28 +45,60 @@ tool = PDFSearchTool(pdf='path/to/your/document.pdf')
|
||||
|
||||
## Modelo e embeddings personalizados
|
||||
|
||||
Por padrão, a ferramenta utiliza OpenAI tanto para embeddings quanto para sumarização. Para personalizar o modelo, você pode usar um dicionário de configuração como no exemplo abaixo:
|
||||
Por padrão, a ferramenta utiliza OpenAI para embeddings e sumarização. Para personalizar, use um dicionário de configuração conforme abaixo. Observação: um banco vetorial (vectordb) é necessário, pois os embeddings gerados precisam ser armazenados e consultados.
|
||||
|
||||
```python Code
|
||||
from crewai_tools import PDFSearchTool
|
||||
from chromadb.config import Settings # Persistência no Chroma
|
||||
|
||||
tool = PDFSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # ou google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # ou openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
# Obrigatório: provedor de embeddings + configuração
|
||||
"embedding_model": {
|
||||
# Provedores suportados: "openai", "azure", "google-generativeai", "google-vertex",
|
||||
# "voyageai", "cohere", "huggingface", "jina", "sentence-transformer",
|
||||
# "text2vec", "ollama", "openclip", "instructor", "onnx", "roboflow", "watsonx", "custom"
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
# "model" é mapeado internamente para "model_name".
|
||||
"model": "text-embedding-3-small",
|
||||
# Opcional: chave da API (se ausente, usa variáveis de ambiente do provedor)
|
||||
# "api_key": "sk-...",
|
||||
|
||||
# Exemplos específicos por provedor
|
||||
# --- Google ---
|
||||
# (defina provider="google-generativeai")
|
||||
# "model": "models/embedding-001",
|
||||
# "task_type": "retrieval_document",
|
||||
|
||||
# --- Cohere ---
|
||||
# (defina provider="cohere")
|
||||
# "model": "embed-english-v3.0",
|
||||
|
||||
# --- Ollama (local) ---
|
||||
# (defina provider="ollama")
|
||||
# "model": "nomic-embed-text",
|
||||
},
|
||||
},
|
||||
|
||||
# Obrigatório: configuração do banco vetorial
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # ou "qdrant"
|
||||
"config": {
|
||||
# Exemplo Chroma:
|
||||
# "settings": Settings(
|
||||
# persist_directory="/content/chroma",
|
||||
# allow_reset=True,
|
||||
# is_persistent=True,
|
||||
# ),
|
||||
|
||||
# Exemplo Qdrant:
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
|
||||
# Observação: o nome da coleção é controlado pela ferramenta (padrão: "rag_tool_collection").
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -57,25 +57,39 @@ Por padrão, a ferramenta utiliza o OpenAI tanto para embeddings quanto para sum
|
||||
Para personalizar o modelo, você pode usar um dicionário de configuração como o exemplo a seguir:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = TXTSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # ou google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # ou openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
# Obrigatório: provedor de embeddings + configuração
|
||||
"embedding_model": {
|
||||
"provider": "openai", # ou google-generativeai, cohere, ollama, ...
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...", # opcional se variável de ambiente estiver definida
|
||||
# Exemplos por provedor:
|
||||
# Google → model: "models/embedding-001", task_type: "retrieval_document"
|
||||
},
|
||||
},
|
||||
|
||||
# Obrigatório: configuração do banco vetorial
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # ou "qdrant"
|
||||
"config": {
|
||||
# Configurações do Chroma (persistência opcional)
|
||||
# "settings": Settings(
|
||||
# persist_directory="/content/chroma",
|
||||
# allow_reset=True,
|
||||
# is_persistent=True,
|
||||
# ),
|
||||
|
||||
# Exemplo de parâmetros de vetor do Qdrant:
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
|
||||
# Observação: o nome da coleção é controlado pela ferramenta (padrão: "rag_tool_collection").
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -54,25 +54,25 @@ Este parâmetro é opcional durante a inicialização da ferramenta, mas deve se
|
||||
Por padrão, a ferramenta utiliza a OpenAI tanto para embeddings quanto para sumarização. Para personalizar o modelo, você pode usar um dicionário de configuração conforme o exemplo a seguir:
|
||||
|
||||
```python Code
|
||||
from chromadb.config import Settings
|
||||
|
||||
tool = XMLSearchTool(
|
||||
config=dict(
|
||||
llm=dict(
|
||||
provider="ollama", # ou google, openai, anthropic, llama2, ...
|
||||
config=dict(
|
||||
model="llama2",
|
||||
# temperature=0.5,
|
||||
# top_p=1,
|
||||
# stream=true,
|
||||
),
|
||||
),
|
||||
embedder=dict(
|
||||
provider="google", # ou openai, ollama, ...
|
||||
config=dict(
|
||||
model="models/embedding-001",
|
||||
task_type="retrieval_document",
|
||||
# title="Embeddings",
|
||||
),
|
||||
),
|
||||
)
|
||||
config={
|
||||
"embedding_model": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
# "api_key": "sk-...",
|
||||
},
|
||||
},
|
||||
"vectordb": {
|
||||
"provider": "chromadb", # ou "qdrant"
|
||||
"config": {
|
||||
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
|
||||
# from qdrant_client.models import VectorParams, Distance
|
||||
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
@@ -1,9 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
from crewai.tools import BaseTool, EnvVar
|
||||
@@ -12,9 +12,13 @@ from pydantic.types import ImportString
|
||||
|
||||
|
||||
class QdrantToolSchema(BaseModel):
|
||||
query: str = Field(..., description="Query to search in Qdrant DB.")
|
||||
filter_by: str | None = None
|
||||
filter_value: str | None = None
|
||||
query: str = Field(..., description="Query to search in Qdrant DB")
|
||||
filter_by: str | None = Field(
|
||||
default=None, description="Parameter to filter the search by."
|
||||
)
|
||||
filter_value: Any | None = Field(
|
||||
default=None, description="Value to filter the search by."
|
||||
)
|
||||
|
||||
|
||||
class QdrantConfig(BaseModel):
|
||||
@@ -25,7 +29,9 @@ class QdrantConfig(BaseModel):
|
||||
collection_name: str
|
||||
limit: int = 3
|
||||
score_threshold: float = 0.35
|
||||
filter_conditions: list[tuple[str, Any]] = Field(default_factory=list)
|
||||
filter: Any | None = Field(
|
||||
default=None, description="Qdrant Filter instance for advanced filtering."
|
||||
)
|
||||
|
||||
|
||||
class QdrantVectorSearchTool(BaseTool):
|
||||
@@ -76,23 +82,26 @@ class QdrantVectorSearchTool(BaseTool):
|
||||
filter_value: Any | None = None,
|
||||
) -> str:
|
||||
"""Perform vector similarity search."""
|
||||
filter_ = self.qdrant_package.http.models.Filter
|
||||
field_condition = self.qdrant_package.http.models.FieldCondition
|
||||
match_value = self.qdrant_package.http.models.MatchValue
|
||||
conditions = self.qdrant_config.filter_conditions.copy()
|
||||
if filter_by and filter_value is not None:
|
||||
conditions.append((filter_by, filter_value))
|
||||
|
||||
search_filter = (
|
||||
filter_(
|
||||
must=[
|
||||
field_condition(key=k, match=match_value(value=v))
|
||||
for k, v in conditions
|
||||
]
|
||||
)
|
||||
if conditions
|
||||
else None
|
||||
self.qdrant_config.filter.model_copy()
|
||||
if self.qdrant_config.filter is not None
|
||||
else self.qdrant_package.http.models.Filter(must=[])
|
||||
)
|
||||
if filter_by and filter_value is not None:
|
||||
if not hasattr(search_filter, "must") or not isinstance(
|
||||
search_filter.must, list
|
||||
):
|
||||
search_filter.must = []
|
||||
search_filter.must.append(
|
||||
self.qdrant_package.http.models.FieldCondition(
|
||||
key=filter_by,
|
||||
match=self.qdrant_package.http.models.MatchValue(
|
||||
value=filter_value
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
query_vector = (
|
||||
self.custom_embedding_fn(query)
|
||||
if self.custom_embedding_fn
|
||||
|
||||
@@ -36,7 +36,7 @@ class AnthropicCompletion(BaseLLM):
|
||||
timeout: float | None = None,
|
||||
max_retries: int = 2,
|
||||
temperature: float | None = None,
|
||||
max_tokens: int = 4096, # Required for Anthropic
|
||||
max_tokens: int | None = None, # Optional, computed dynamically if not set
|
||||
top_p: float | None = None,
|
||||
stop_sequences: list[str] | None = None,
|
||||
stream: bool = False,
|
||||
@@ -52,7 +52,8 @@ class AnthropicCompletion(BaseLLM):
|
||||
timeout: Request timeout in seconds
|
||||
max_retries: Maximum number of retries
|
||||
temperature: Sampling temperature (0-1)
|
||||
max_tokens: Maximum tokens in response (required for Anthropic)
|
||||
max_tokens: Maximum tokens in response. If not set, will be computed
|
||||
dynamically based on context window size (recommended for most use cases)
|
||||
top_p: Nucleus sampling parameter
|
||||
stop_sequences: Stop sequences (Anthropic uses stop_sequences, not stop)
|
||||
stream: Enable streaming responses
|
||||
@@ -72,7 +73,7 @@ class AnthropicCompletion(BaseLLM):
|
||||
self.client = Anthropic(**self._get_client_params())
|
||||
|
||||
# Store completion parameters
|
||||
self.max_tokens = max_tokens
|
||||
self.max_tokens = max_tokens # Can be None, will be computed dynamically
|
||||
self.top_p = top_p
|
||||
self.stream = stream
|
||||
self.stop_sequences = stop_sequences or []
|
||||
@@ -178,10 +179,19 @@ class AnthropicCompletion(BaseLLM):
|
||||
Returns:
|
||||
Parameters dictionary for Anthropic API
|
||||
"""
|
||||
max_tokens = self.max_tokens
|
||||
if max_tokens is None:
|
||||
# while still allowing enough tokens for most responses
|
||||
max_tokens = 1024
|
||||
|
||||
context_window = self.get_context_window_size()
|
||||
if context_window > 100000: # For Claude models with 200k+ context
|
||||
max_tokens = 2048
|
||||
|
||||
params = {
|
||||
"model": self.model,
|
||||
"messages": messages,
|
||||
"max_tokens": self.max_tokens,
|
||||
"max_tokens": max_tokens,
|
||||
"stream": self.stream,
|
||||
}
|
||||
|
||||
|
||||
@@ -664,3 +664,105 @@ def test_anthropic_token_usage_tracking():
|
||||
assert usage["input_tokens"] == 50
|
||||
assert usage["output_tokens"] == 25
|
||||
assert usage["total_tokens"] == 75
|
||||
|
||||
|
||||
def test_anthropic_max_tokens_explicit():
|
||||
"""
|
||||
Test that explicit max_tokens is passed through to the API
|
||||
"""
|
||||
llm = LLM(model="anthropic/claude-3-5-sonnet-20241022", max_tokens=4096)
|
||||
|
||||
with patch.object(llm.client.messages, 'create') as mock_create:
|
||||
mock_response = MagicMock()
|
||||
mock_response.content = [MagicMock(text="test response")]
|
||||
mock_response.usage = MagicMock(input_tokens=10, output_tokens=20)
|
||||
mock_create.return_value = mock_response
|
||||
|
||||
llm.call("Hello")
|
||||
|
||||
call_kwargs = mock_create.call_args[1]
|
||||
assert call_kwargs["max_tokens"] == 4096
|
||||
|
||||
|
||||
def test_anthropic_max_tokens_default_computed():
|
||||
"""
|
||||
Test that max_tokens is computed dynamically when not explicitly set
|
||||
"""
|
||||
llm = LLM(model="anthropic/claude-3-5-sonnet-20241022")
|
||||
|
||||
with patch.object(llm.client.messages, 'create') as mock_create:
|
||||
mock_response = MagicMock()
|
||||
mock_response.content = [MagicMock(text="test response")]
|
||||
mock_response.usage = MagicMock(input_tokens=10, output_tokens=20)
|
||||
mock_create.return_value = mock_response
|
||||
|
||||
llm.call("Hello")
|
||||
|
||||
call_kwargs = mock_create.call_args[1]
|
||||
assert "max_tokens" in call_kwargs
|
||||
assert call_kwargs["max_tokens"] is not None
|
||||
assert call_kwargs["max_tokens"] < 4096
|
||||
|
||||
|
||||
def test_anthropic_max_tokens_none_uses_dynamic_default():
|
||||
"""
|
||||
Test that max_tokens=None results in dynamic computation
|
||||
"""
|
||||
llm = LLM(model="anthropic/claude-3-5-sonnet-20241022", max_tokens=None)
|
||||
|
||||
assert llm.max_tokens is None
|
||||
|
||||
with patch.object(llm.client.messages, 'create') as mock_create:
|
||||
mock_response = MagicMock()
|
||||
mock_response.content = [MagicMock(text="test response")]
|
||||
mock_response.usage = MagicMock(input_tokens=10, output_tokens=20)
|
||||
mock_create.return_value = mock_response
|
||||
|
||||
llm.call("Hello")
|
||||
|
||||
call_kwargs = mock_create.call_args[1]
|
||||
assert "max_tokens" in call_kwargs
|
||||
assert call_kwargs["max_tokens"] is not None
|
||||
assert call_kwargs["max_tokens"] < 4096
|
||||
|
||||
|
||||
def test_anthropic_max_tokens_dynamic_for_large_context():
|
||||
"""
|
||||
Test that dynamic max_tokens is larger for models with large context windows
|
||||
"""
|
||||
llm = LLM(model="anthropic/claude-3-5-sonnet-20241022")
|
||||
|
||||
with patch.object(llm.client.messages, 'create') as mock_create:
|
||||
mock_response = MagicMock()
|
||||
mock_response.content = [MagicMock(text="test response")]
|
||||
mock_response.usage = MagicMock(input_tokens=10, output_tokens=20)
|
||||
mock_create.return_value = mock_response
|
||||
|
||||
llm.call("Hello")
|
||||
|
||||
call_kwargs = mock_create.call_args[1]
|
||||
computed_max_tokens = call_kwargs["max_tokens"]
|
||||
|
||||
assert computed_max_tokens >= 1024
|
||||
assert computed_max_tokens <= 2048
|
||||
|
||||
|
||||
def test_anthropic_max_tokens_respects_user_value():
|
||||
"""
|
||||
Test that user-provided max_tokens is always respected
|
||||
"""
|
||||
test_values = [512, 1024, 2048, 4096, 8192]
|
||||
|
||||
for max_tokens_value in test_values:
|
||||
llm = LLM(model="anthropic/claude-3-5-sonnet-20241022", max_tokens=max_tokens_value)
|
||||
|
||||
with patch.object(llm.client.messages, 'create') as mock_create:
|
||||
mock_response = MagicMock()
|
||||
mock_response.content = [MagicMock(text="test response")]
|
||||
mock_response.usage = MagicMock(input_tokens=10, output_tokens=20)
|
||||
mock_create.return_value = mock_response
|
||||
|
||||
llm.call("Hello")
|
||||
|
||||
call_kwargs = mock_create.call_args[1]
|
||||
assert call_kwargs["max_tokens"] == max_tokens_value
|
||||
|
||||
Reference in New Issue
Block a user