opencode-skills-collection 3.1.10 → 3.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +8 -1
  2. package/bundled-skills/browser-testing-with-devtools/SKILL.md +334 -0
  3. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  4. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  5. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  6. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  7. package/bundled-skills/docs/sources/sources.md +4 -0
  8. package/bundled-skills/docs/users/bundles.md +1 -1
  9. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  10. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  11. package/bundled-skills/docs/users/getting-started.md +1 -1
  12. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  13. package/bundled-skills/docs/users/usage.md +4 -4
  14. package/bundled-skills/docs/users/visual-guide.md +4 -4
  15. package/bundled-skills/drizzle-migration-conflict/SKILL.md +179 -0
  16. package/bundled-skills/drizzle-migration-conflict/references/ci-policy.md +87 -0
  17. package/bundled-skills/drizzle-migration-conflict/references/conflict-resolution.md +163 -0
  18. package/bundled-skills/drizzle-migration-conflict/references/report-template.md +69 -0
  19. package/bundled-skills/drizzle-migration-conflict/references/sources.md +51 -0
  20. package/bundled-skills/drizzle-migration-conflict/scripts/check_drizzle_migrations.py +721 -0
  21. package/bundled-skills/frontend-lighthouse/SKILL.md +348 -0
  22. package/bundled-skills/pre-release-review/SKILL.md +198 -0
  23. package/bundled-skills/pre-release-review/references/checklist.md +104 -0
  24. package/bundled-skills/pre-release-review/references/report-template.md +91 -0
  25. package/bundled-skills/re-create/SKILL.md +251 -0
  26. package/bundled-skills/weaviate/SKILL.md +132 -0
  27. package/bundled-skills/weaviate/references/ask.md +36 -0
  28. package/bundled-skills/weaviate/references/create_collection.md +152 -0
  29. package/bundled-skills/weaviate/references/environment_requirements.md +34 -0
  30. package/bundled-skills/weaviate/references/example_data.md +24 -0
  31. package/bundled-skills/weaviate/references/explore_collection.md +50 -0
  32. package/bundled-skills/weaviate/references/fetch_filter.md +88 -0
  33. package/bundled-skills/weaviate/references/get_collection.md +32 -0
  34. package/bundled-skills/weaviate/references/hybrid_search.md +47 -0
  35. package/bundled-skills/weaviate/references/import_data.md +160 -0
  36. package/bundled-skills/weaviate/references/keyword_search.md +38 -0
  37. package/bundled-skills/weaviate/references/list_collections.md +31 -0
  38. package/bundled-skills/weaviate/references/query_search.md +38 -0
  39. package/bundled-skills/weaviate/references/semantic_search.md +46 -0
  40. package/bundled-skills/weaviate/scripts/ask.py +106 -0
  41. package/bundled-skills/weaviate/scripts/create_collection.py +359 -0
  42. package/bundled-skills/weaviate/scripts/example_data.py +945 -0
  43. package/bundled-skills/weaviate/scripts/explore_collection.py +295 -0
  44. package/bundled-skills/weaviate/scripts/fetch_filter.py +261 -0
  45. package/bundled-skills/weaviate/scripts/get_collection.py +122 -0
  46. package/bundled-skills/weaviate/scripts/hybrid_search.py +157 -0
  47. package/bundled-skills/weaviate/scripts/import.py +701 -0
  48. package/bundled-skills/weaviate/scripts/keyword_search.py +142 -0
  49. package/bundled-skills/weaviate/scripts/list_collections.py +77 -0
  50. package/bundled-skills/weaviate/scripts/query_search.py +135 -0
  51. package/bundled-skills/weaviate/scripts/semantic_search.py +139 -0
  52. package/bundled-skills/weaviate/scripts/weaviate_conn.py +231 -0
  53. package/bundled-skills/weaviate-cookbooks/SKILL.md +67 -0
  54. package/bundled-skills/weaviate-cookbooks/references/advanced_rag.md +274 -0
  55. package/bundled-skills/weaviate-cookbooks/references/agentic_rag.md +360 -0
  56. package/bundled-skills/weaviate-cookbooks/references/async_client.md +428 -0
  57. package/bundled-skills/weaviate-cookbooks/references/basic_agent.md +270 -0
  58. package/bundled-skills/weaviate-cookbooks/references/basic_rag.md +219 -0
  59. package/bundled-skills/weaviate-cookbooks/references/data_explorer.md +336 -0
  60. package/bundled-skills/weaviate-cookbooks/references/environment_requirements.md +78 -0
  61. package/bundled-skills/weaviate-cookbooks/references/frontend_interface.md +104 -0
  62. package/bundled-skills/weaviate-cookbooks/references/pdf_multimodal_rag.md +635 -0
  63. package/bundled-skills/weaviate-cookbooks/references/project_setup.md +75 -0
  64. package/bundled-skills/weaviate-cookbooks/references/query_agent_chatbot.md +163 -0
  65. package/package.json +1 -1
  66. package/skills_index.json +156 -0
@@ -0,0 +1,231 @@
1
+ """
2
+ Shared Weaviate connection utilities.
3
+
4
+ This module handles:
5
+ - Environment variable validation
6
+ - API key to header mapping for all supported providers
7
+ - Client connection with automatic header configuration
8
+
9
+ Usage in scripts:
10
+ import sys
11
+ from pathlib import Path
12
+ sys.path.insert(0, str(Path(__file__).parent.parent.parent / "lib"))
13
+ from weaviate_conn import get_client, get_headers, validate_env
14
+ """
15
+
16
+ import os
17
+ import sys
18
+ from contextlib import contextmanager
19
+ from typing import Generator
20
+
21
+ import weaviate
22
+ from weaviate.classes.init import Auth
23
+ from weaviate.client import WeaviateClient
24
+ from weaviate.classes.init import AdditionalConfig, Timeout
25
+
26
+ # Canonical environment variable to Weaviate header mapping
27
+ API_KEY_MAP = {
28
+ "ANTHROPIC_API_KEY": "X-Anthropic-Api-Key",
29
+ "ANYSCALE_API_KEY": "X-Anyscale-Api-Key",
30
+ "AWS_ACCESS_KEY": "X-Aws-Access-Key",
31
+ "AWS_SECRET_KEY": "X-Aws-Secret-Key",
32
+ "COHERE_API_KEY": "X-Cohere-Api-Key",
33
+ "DATABRICKS_TOKEN": "X-Databricks-Token",
34
+ "FRIENDLI_TOKEN": "X-Friendli-Api-Key",
35
+ "VERTEX_API_KEY": "X-Goog-Vertex-Api-Key",
36
+ "STUDIO_API_KEY": "X-Goog-Studio-Api-Key",
37
+ "HUGGINGFACE_API_KEY": "X-HuggingFace-Api-Key",
38
+ "JINAAI_API_KEY": "X-JinaAI-Api-Key",
39
+ "MISTRAL_API_KEY": "X-Mistral-Api-Key",
40
+ "NVIDIA_API_KEY": "X-Nvidia-Api-Key",
41
+ "OPENAI_API_KEY": "X-OpenAI-Api-Key",
42
+ "AZURE_API_KEY": "X-Azure-Api-Key",
43
+ "VOYAGE_API_KEY": "X-Voyage-Api-Key",
44
+ "XAI_API_KEY": "X-Xai-Api-Key",
45
+ }
46
+
47
+
48
+ def _collect_headers_and_providers() -> tuple[dict[str, str], list[str]]:
49
+ """
50
+ Scan env once to build Weaviate headers and detected key names.
51
+
52
+ Returns:
53
+ Tuple of (headers, detected_env_var_names)
54
+ """
55
+ headers: dict[str, str] = {}
56
+ detected_providers: list[str] = []
57
+
58
+ for env_var, header_name in API_KEY_MAP.items():
59
+ value = os.environ.get(env_var, "").strip()
60
+ if not value:
61
+ continue
62
+
63
+ detected_providers.append(env_var)
64
+ headers[header_name] = value
65
+
66
+ return headers, detected_providers
67
+
68
+
69
+ def validate_env(require_weaviate: bool = True) -> tuple[str, str]:
70
+ """
71
+ Validate required Weaviate environment variables.
72
+
73
+ Args:
74
+ require_weaviate: If True, exit with error if WEAVIATE_URL/API_KEY not set
75
+
76
+ Returns:
77
+ Tuple of (weaviate_url, weaviate_api_key)
78
+
79
+ Raises:
80
+ SystemExit: If required variables are missing
81
+ """
82
+ url = os.environ.get("WEAVIATE_URL", "").strip()
83
+ api_key = os.environ.get("WEAVIATE_API_KEY", "").strip()
84
+
85
+ if require_weaviate:
86
+ if not url:
87
+ print("Error: WEAVIATE_URL environment variable not set", file=sys.stderr)
88
+ sys.exit(1)
89
+ if not api_key:
90
+ print(
91
+ "Error: WEAVIATE_API_KEY environment variable not set", file=sys.stderr
92
+ )
93
+ sys.exit(1)
94
+
95
+ return url, api_key
96
+
97
+
98
+ def get_headers() -> dict[str, str] | None:
99
+ """
100
+ Build headers dict from all available API keys in environment.
101
+
102
+ Scans environment for all known API key variables and builds
103
+ the appropriate headers dict for Weaviate client connection.
104
+
105
+ Returns:
106
+ Dict of headers if any API keys found, None otherwise
107
+ """
108
+ headers, _ = _collect_headers_and_providers()
109
+ return headers if headers else None
110
+
111
+
112
+ def get_detected_providers() -> list[str]:
113
+ """
114
+ Get list of detected API key environment variable names.
115
+
116
+ Returns:
117
+ List of env var names (e.g., ["OPENAI_API_KEY", "COHERE_API_KEY"])
118
+ """
119
+ _, detected_providers = _collect_headers_and_providers()
120
+ return sorted(detected_providers)
121
+
122
+
123
+ @contextmanager
124
+ def get_client(
125
+ url: str | None = None,
126
+ api_key: str | None = None,
127
+ headers: dict[str, str] | None = None,
128
+ verbose: bool = True,
129
+ ) -> Generator[WeaviateClient, None, None]:
130
+ """
131
+ Context manager for Weaviate client connection.
132
+
133
+ Auto-detects credentials from environment if not provided.
134
+ Auto-builds headers from all available API keys if not provided.
135
+
136
+ Args:
137
+ url: Weaviate cluster URL (default: from WEAVIATE_URL env var)
138
+ api_key: Weaviate API key (default: from WEAVIATE_API_KEY env var)
139
+ headers: Custom headers dict (default: auto-detected from env vars)
140
+ verbose: Print connection status to stderr
141
+
142
+ Yields:
143
+ Connected WeaviateClient instance
144
+
145
+ Example:
146
+ with get_client() as client:
147
+ collections = client.collections.list_all()
148
+ """
149
+ # Get credentials from env if not provided
150
+ if url is None or api_key is None:
151
+ env_url, env_api_key = validate_env()
152
+ url = url or env_url
153
+ api_key = api_key or env_api_key
154
+
155
+ # Auto-detect headers if not provided
156
+ if headers is None:
157
+ headers, detected_providers = _collect_headers_and_providers()
158
+ headers = headers or None
159
+ else:
160
+ detected_providers = None
161
+
162
+ if verbose:
163
+ detected = sorted(detected_providers) if detected_providers is not None else []
164
+ if detected:
165
+ print(f"Detected providers: {', '.join(detected)}", file=sys.stderr)
166
+ print("Connecting to Weaviate...", file=sys.stderr)
167
+
168
+ client = weaviate.connect_to_weaviate_cloud(
169
+ cluster_url=url,
170
+ auth_credentials=Auth.api_key(api_key),
171
+ headers=headers,
172
+ additional_config=AdditionalConfig(
173
+ timeout=Timeout(init=30, query=60, insert=120)
174
+ ),
175
+ )
176
+
177
+ try:
178
+ if verbose:
179
+ print("Connected.", file=sys.stderr)
180
+ yield client
181
+ finally:
182
+ client.close()
183
+
184
+
185
+ def connect_client(
186
+ url: str | None = None,
187
+ api_key: str | None = None,
188
+ headers: dict[str, str] | None = None,
189
+ verbose: bool = True,
190
+ ) -> WeaviateClient:
191
+ """
192
+ Get a Weaviate client connection (non-context manager version).
193
+
194
+ IMPORTANT: Caller is responsible for calling client.close()
195
+
196
+ Args:
197
+ url: Weaviate cluster URL (default: from WEAVIATE_URL env var)
198
+ api_key: Weaviate API key (default: from WEAVIATE_API_KEY env var)
199
+ headers: Custom headers dict (default: auto-detected from env vars)
200
+ verbose: Print connection status to stderr
201
+
202
+ Returns:
203
+ Connected WeaviateClient instance
204
+ """
205
+ if url is None or api_key is None:
206
+ env_url, env_api_key = validate_env()
207
+ url = url or env_url
208
+ api_key = api_key or env_api_key
209
+
210
+ if headers is None:
211
+ headers, detected_providers = _collect_headers_and_providers()
212
+ headers = headers or None
213
+ else:
214
+ detected_providers = None
215
+
216
+ if verbose:
217
+ detected = sorted(detected_providers) if detected_providers is not None else []
218
+ if detected:
219
+ print(f"Detected providers: {', '.join(detected)}", file=sys.stderr)
220
+ print("Connecting to Weaviate...", file=sys.stderr)
221
+
222
+ client = weaviate.connect_to_weaviate_cloud(
223
+ cluster_url=url,
224
+ auth_credentials=Auth.api_key(api_key),
225
+ headers=headers,
226
+ )
227
+
228
+ if verbose:
229
+ print("Connected.", file=sys.stderr)
230
+
231
+ return client
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: weaviate-cookbooks
3
+ description: "Build Weaviate AI apps from official cookbook blueprints for RAG, agentic RAG, data exploration, multimodal PDF search, async clients, and frontends."
4
+ category: ai
5
+ risk: safe
6
+ source: community
7
+ source_repo: weaviate/agent-skills
8
+ source_type: official
9
+ date_added: "2026-06-29"
10
+ author: Weaviate
11
+ tags: [weaviate, rag, agents, vector-database, ai-apps]
12
+ tools: [python, weaviate, nextjs]
13
+ license: "BSD-3-Clause"
14
+ license_source: "https://github.com/weaviate/agent-skills/blob/main/LICENSE"
15
+ ---
16
+
17
+ # Weaviate Cookbooks
18
+
19
+ ## Overview
20
+
21
+ This skill provides an index of implementation guides and foundational requirements for building Weaviate-powered AI applications. Use the references to quickly scaffold full-stack applications with best practices for connection management, environment setup, and application architecture.
22
+
23
+ ## When to Use This Skill
24
+
25
+ - Use when the user wants a Weaviate-backed RAG, agentic RAG, chatbot, data explorer, or multimodal document-search application.
26
+ - Use when selecting between cookbook patterns before writing a full-stack Weaviate app.
27
+ - Use when the project needs Weaviate environment, setup, async-client, or frontend guidance.
28
+ - Use when the user asks for an official Weaviate blueprint rather than a generic vector database recipe.
29
+
30
+ ### Weaviate Cloud Instance
31
+
32
+ If the user does not have an instance yet, direct them to the cloud console to register and create a free sandbox. Create a Weaviate instance via [Weaviate Cloud](https://console.weaviate.cloud/signin?utm_source=github&utm_campaign=agent_skills).
33
+
34
+ ## Before Building Any Cookbook
35
+
36
+ Follow these shared guidelines before generating any cookbook app:
37
+
38
+ - [Project Setup Contract](references/project_setup.md)
39
+ - [Environment Requirements](references/environment_requirements.md)
40
+
41
+ Then proceed to the specific cookbook reference below.
42
+
43
+ ## Cookbook Index
44
+
45
+ - [Query Agent Chatbot](references/query_agent_chatbot.md): Build a full-stack chatbot using Weaviate Query Agent with streaming and chat history support.
46
+ - [Data Explorer](references/data_explorer.md): Build a full-stack data explorer app including sorting, keyword search and tabular view of weaviate data.
47
+ - [Multimodal RAG: Building Document Search](references/pdf_multimodal_rag.md): Build a multimodal Retrieval-Augmented Generation (RAG) system using Weaviate Embeddings (ModernVBERT/colmodernvbert) and Ollama with Qwen3-VL for generation.
48
+ - [Basic RAG](references/basic_rag.md): Implement basic retrieval and generation with Weaviate. Useful for most forms of data retrieval from a Weaviate collection.
49
+ - [Advanced RAG](references/advanced_rag.md): Improve on basic RAG by adding extra features such as re-ranking, query decomposition, query re-writing, LLM filter selection.
50
+ - [Basic Agent](references/basic_agent.md): Build a tool-calling AI agent with structured outputs using DSPy. Covers AgentResponse signatures, RouterAgent, tool design, and sequential multi-step loops.
51
+ - [Agentic RAG](references/agentic_rag.md): Build RAG-powered AI agents with Weaviate. Covers naive RAG tools, hierarchical RAG with LLM-created filters, vector DB memory, Weaviate Query Agent, and Elysia integration.
52
+
53
+ ## Interface (Optional)
54
+
55
+ Use this when the user explicitly asks for a frontend for their Weaviate backend.
56
+
57
+ - [Frontend Interface](references/frontend_interface.md): Build a Next.js frontend to interact with the Weaviate backend.
58
+
59
+ ## Client Usage
60
+
61
+ - [Async Client](references/async_client.md): Guide for using the Weaviate Python async client in production applications (FastAPI, async frameworks). Covers connection patterns, lifecycle management, common pitfalls, and multi-cluster setups.
62
+
63
+ ## Limitations
64
+
65
+ - Cookbook blueprints still need adaptation to the user's data model, embedding provider, auth model, deployment platform, and latency/cost targets.
66
+ - This skill does not validate live Weaviate credentials, cloud quotas, or model availability unless the user provides and approves the relevant environment.
67
+ - Generated apps should be reviewed for security, data privacy, prompt injection exposure, and production observability before launch.
@@ -0,0 +1,274 @@
1
+ # Advanced RAG Cookbook
2
+
3
+ Build advanced RAG functionality with Weaviate.
4
+
5
+ Read first:
6
+ - Basic RAG cookbook, important to start from this base. MUST READ: [Basic RAG Cookbook](./basic_rag.md)
7
+
8
+ Docs to reference if needed:
9
+ - Search patterns and basics in Weaviate: https://docs.weaviate.io/weaviate/search/basics
10
+ - Filters in Weaviate: https://docs.weaviate.io/weaviate/search/filters
11
+ - Vector search: https://docs.weaviate.io/weaviate/search/similarity
12
+ - Keyword search: https://docs.weaviate.io/weaviate/search/bm25
13
+ - Hybrid search: https://docs.weaviate.io/weaviate/search/hybrid
14
+ - Image search: https://docs.weaviate.io/weaviate/search/image
15
+
16
+
17
+ ## Core Rules
18
+
19
+ First implement the basic strategy from [here](./basic_rag.md). Then modify according to this guide.
20
+
21
+ - Use a virtual environment via `venv`
22
+ - Use `uv` for Python project/dependency management.
23
+ - Do not manually author `pyproject.toml` or `uv.lock`; let `uv` generate/update them.
24
+ - Use this install set: `uv add weaviate-client python-dotenv dspy weaviate-agents`
25
+ - Customise this cookbook to the users specification, ask them for details if not given.
26
+
27
+ Assume the user has data already to be used, do not create data unless asked to.
28
+
29
+ Instead of following this cookbook, you first must ask the user if they would prefer to use the Weaviate Query Agent. If so, all steps in this guide can be implemented with the query agent which does advanced RAG out of the box.
30
+
31
+ Query agent docs: https://docs.weaviate.io/agents/query/usage
32
+
33
+ ## Env Rules
34
+
35
+ Mandatory:
36
+ - `WEAVIATE_URL`
37
+ - `WEAVIATE_API_KEY`
38
+
39
+ External provider keys:
40
+ - Fill only keys actually used by the target Weaviate collection setup.
41
+
42
+ ## Advanced RAG overview
43
+
44
+ * Query re-writer: *Change user input text into a query text using an LLM*
45
+ * Query decomposition: *Change query into multiple sub-queries each re-written with an LLM*
46
+ * Filtering: *Use an LLM to define filters on the collection*
47
+ * Re-ranking: *Score the final results by a more advanced model*
48
+ * Prompt engineering: *Add chain of thought, Tree of thoughts, ReAct*
49
+
50
+ ## Query Re-writer
51
+
52
+ ```python
53
+ class QueryRewriter(dspy.Signature):
54
+ """
55
+ Rewrite the user's query into a more relevant search term that is a more relevant search term for searching a database.
56
+ """
57
+ input_query: str = dspy.InputField(description="The original user query")
58
+ rewritten_query: str = dspy.OutputField(
59
+ description=(
60
+ "A single search term that is more relevant to the user's query. "
61
+ "Include only relevant information, it does not need to be a full sentence or question "
62
+ )
63
+ )
64
+ ```
65
+
66
+ Modify the `query_transformation` function:
67
+
68
+ ```python
69
+ def query_transformation(query: str) -> list[str]:
70
+ lm = dspy.LM(subtask_model_name)
71
+ answer = dspy.Predict(QueryRewriter)
72
+ pred = answer(input_query=query, lm=lm)
73
+ return [pred.rewritten_query]
74
+ ```
75
+
76
+ ## Query Decomposition
77
+
78
+ ```python
79
+ class QueryRewriter(dspy.Signature):
80
+ """
81
+ Rewrite the user's query into a more relevant search terms that are more relevant search term for searching a database.
82
+ """
83
+ input_query: str = dspy.InputField(description="The original user query")
84
+ rewritten_queries: list[str] = dspy.OutputField(
85
+ description=(
86
+ "A list of search terms that are more relevant to the user's query. "
87
+ "Each entry should include only relevant information, it does not need to be a full sentence or question "
88
+ "Split independent searches into different entries "
89
+ "Each entry should be relevant independently that capture a different required search aspect "
90
+ "Do not repeat similar search terms, each one should have a unique meaning "
91
+ "Be sparse, do not duplicate search terms "
92
+ )
93
+ )
94
+
95
+ def query_transformation(query: str) -> list[str]:
96
+ lm = dspy.LM(subtask_model_name)
97
+ answer = dspy.Predict(QueryRewriter)
98
+ pred = answer(input_query=query, lm=lm)
99
+ return pred.rewritten_queries
100
+ ```
101
+
102
+ ## LLM-created Filters
103
+
104
+ Filters can be specified by the user (for specific use-cases, perhaps), or you can get an LLM to write the filters also. Writing filters requires knowledge of the collection schema. This can be retrieved by advanced methods or a simple version can be used.
105
+
106
+ Simple version:
107
+
108
+ 1. First create structured responses to format filters
109
+
110
+ ```python
111
+ from pydantic import BaseModel, Field
112
+ from typing import Literal, Any
113
+
114
+ class SearchFilter(BaseModel):
115
+ field: str = Field(description="The field to be filtered on.")
116
+ operator: Literal["=", "!=", ">", "<"] = Field(description="The operator to be used in conjunction with the value. These are strict operators.")
117
+ value: Any = Field(description="The value to be used in conjunction with the operator.")
118
+
119
+ class Search(BaseModel):
120
+ filters: list[SearchFilter] = Field(description="The filters to be used in the vector database. This is an AND operation.")
121
+
122
+ class SearchCreation(dspy.Signature):
123
+ """
124
+ Create filters and search parameters for a search query in a database.
125
+ """
126
+ query: str = dspy.InputField()
127
+ schema: list[dict] = dspy.InputField(desc="Schema of the collection to be searched.")
128
+ data_sample: list[dict] = dspy.InputField(desc="A sample of the data in the collection to be searched.")
129
+ search: Search = dspy.OutputField(
130
+ desc=(
131
+ "Your filters and search parameters, this should be a valid JSON object. "
132
+ "This should be constructed so that it matches the goal of the user prompt."
133
+ )
134
+ )
135
+ ```
136
+ This requires `schema` and `data_sample` as an input field to the LLM call `SearchCreation`.
137
+
138
+ 2. Helper function to turn structured response into weaviate filter
139
+
140
+ ```python
141
+ def _format_filters(search_filters: list[SearchFilter]):
142
+ filters = []
143
+ for search_filter in search_filters:
144
+ base_filter = Filter.by_property(search_filter.field)
145
+ if search_filter.operator == "=":
146
+ filter = base_filter.equal(search_filter.value)
147
+ elif search_filter.operator == "!=":
148
+ filter = base_filter.not_equal(search_filter.value)
149
+ elif search_filter.operator == ">":
150
+ filter = base_filter.greater_than(search_filter.value)
151
+ elif search_filter.operator == "<":
152
+ filter = base_filter.less_than(search_filter.value)
153
+ filters.append(filter)
154
+ return Filter.all_of(filters) if filters else None
155
+ ```
156
+
157
+ 3. Combine
158
+
159
+ ```python
160
+ def create_filters(query: str):
161
+
162
+ # import client here
163
+
164
+ collection = client.collections.use("<collection_name>")
165
+
166
+ # Get collection schema (for field names etc.). can replace this with more advanced configuration (like aggregating for unique groups)
167
+ config = collection.config.get()
168
+ schema = [{"name": p.name, "type": p.data_type[:]} for p in config.properties]
169
+
170
+ # Get a sample of the data in the collection to be searched
171
+ data_sample = collection.query.fetch_objects(limit=5)
172
+
173
+ # Create search parameters
174
+ search_parameters = dspy.ChainOfThought(SearchCreation)
175
+ search_parameters_output = search_parameters(query=query, schema=schema, data_sample=data_sample, lm=dspy.LM(subtask_model_name))
176
+
177
+ return _format_filters(search_parameters_output.search.filters)
178
+ ```
179
+
180
+ These filters can be passed into the `collection.query.near_text` (or equivalent search function).
181
+
182
+ ## Re-ranking
183
+
184
+ Do not modify the user's collection unless requested to do so. Re-ranking requires configuring the collection with a re-ranker, for example:
185
+
186
+ ```python
187
+ collection = client.collections.use("<collection_name>")
188
+ collection.config.update(
189
+ reranker_config=Reconfigure.Reranker.cohere()
190
+ )
191
+ ```
192
+ (this would require a Cohere API key).
193
+
194
+ Modify the `retrieve` function
195
+
196
+ ```python
197
+ from weaviate.classes.query import Rerank
198
+
199
+ def retrieve(query: str, limit: int | None = None, filters = []) -> list[dict]:
200
+
201
+ # ...existing code
202
+
203
+ response = collection.query.hybrid(
204
+ query=query,
205
+ limit=limit,
206
+ rerank=Rerank(
207
+ prop="content", # what field to re-rank on
208
+ query=query # what the search term for the re-ranker should be (same as original in this case)
209
+ ),
210
+ filters=filters if filters else None
211
+ )
212
+
213
+ # ...existing code
214
+ ```
215
+
216
+ ## Prompt Engineering
217
+
218
+ This step depends on the LLM framework used. You can manually ask the LLM to include reasoning before giving its final answer, adding a reasoning sub-field to be completed before giving the final answer in structured response, or specify in DSPy to use chain-of-thought.
219
+
220
+ ```python
221
+ class Generator(dspy.Signature):
222
+ """
223
+ Answer the question based on the context.
224
+ Do not include any information from external sources, only use the information provided in the context.
225
+ If you cannot answer the question based on the information provided, say "I don't know".
226
+ """
227
+ context: str | list[dict] = dspy.InputField(desc="The context to answer the question.")
228
+ query: str = dspy.InputField(desc="The question to answer.")
229
+ answer: str = dspy.OutputField(desc="The single answer to the question with no additional communication")
230
+ ```
231
+
232
+ Modify the `generate` function:
233
+
234
+ ```python
235
+ def generate(query: str, context: list[dict]) -> str:
236
+ lm = dspy.LM(generation_model_name)
237
+ answer = dspy.Predict(Generator)
238
+ pred = answer(context=context, query=query, lm=lm)
239
+ return pred.answer
240
+ ```
241
+
242
+ Consider other prompt engineering techniques like ReAct (if necessary but likely overkill), few-shot learning (requires advanced specification), or otherwise.
243
+
244
+ ## Query Agent
245
+
246
+ Skip this guide altogether and use the Weaviate Query Agent.
247
+
248
+ ```python
249
+ from weaviate.agents.query import QueryAgent
250
+
251
+ # import client here
252
+
253
+ qa = QueryAgent(
254
+ client=client, collections=["Example_Communications_Raw"]
255
+ )
256
+ response = qa.search("<user query here>") # just search with no text response
257
+ response = qa.ask("<user query here>") # search with text response accessible via response.final_answer
258
+ ```
259
+
260
+ ## Customisation Points
261
+
262
+ **LLM framework**
263
+
264
+ This guide used DSPy. Follow the guidelines in [here](./basic_rag.md), but most likely you will need an LLM framework involving structured responses.
265
+
266
+ ## Troubleshooting
267
+
268
+ - Weaviate startup host errors: ensure `WEAVIATE_URL` is full `https://...` URL.
269
+ - For any other issues, refer to the official library/package documentation and use web search extensively for troubleshooting.
270
+
271
+ ## Done Criteria
272
+
273
+ - Create test scripts to check each function works independently with test data. Tear down tests after completion, or create a proper test suite with pytest (requires install)
274
+ - User has completed specification of the app.