An answer written from your own pages takes two calls: a search that finds the best results, and an answer written from them. The model reads only what the search found, so the answer comes from your content, not from what a model remembers.
01 · Step 1: find the content
Search your index with embed_and_search and keep the best 3 or 4 results. Send fresh=no, so results of every date count, and in=all when the index also holds files.
curl -s https://api.opensolr.com/solr_manager/api/embed_and_search \ --data-urlencode "email=YOUR_EMAIL" \ --data-urlencode "api_key=YOUR_API_KEY" \ --data-urlencode "index_name=YOUR_INDEX" \ --data-urlencode "q=How do I reset my password?" \ --data-urlencode "rows=4" \ --data-urlencode "fresh=no" \ --data-urlencode "in=all"
02 · Step 2: write the answer
Put the question, your rules and the title, description and text of those results into one instruction for ai_summary. Number the documents, so you can tell which one the answer came from.
03 · PHP
<?php $auth = ['email' => 'YOUR_EMAIL', 'api_key' => 'YOUR_API_KEY', 'index_name' => 'YOUR_INDEX']; $question = 'How do I reset my password?'; function opensolr_post($endpoint, array $fields) { $ch = curl_init('https://api.opensolr.com/solr_manager/api/' . $endpoint); curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 300, CURLOPT_POSTFIELDS => http_build_query($fields)]); $body = curl_exec($ch); curl_close($ch); return $body; } // Step 1: the best 4 results $found = json_decode(opensolr_post('embed_and_search', $auth + [ 'q' => $question, 'rows' => 4, 'fresh' => 'no', 'in' => 'all', ]), true); // Step 2: one instruction with the question, the rules and the numbered content $lines = [ 'Answer the question using only the content below: ' . $question, 'Begin with the answer itself. Use only what the content states.', '', 'CONTENT:', ]; foreach ($found['results']['docs'] ?? [] as $i => $doc) { $text = implode(' ', array_slice(preg_split('/\s+/', (string)($doc['text'] ?? '')), 0, 1500)); $lines[] = '[' . ($i + 1) . '] ' . ($doc['title'] ?? '') . ' - ' . ($doc['description'] ?? '') . ' - ' . $text; } echo opensolr_post('ai_summary', $auth + ['instruction' => implode(PHP_EOL, $lines)]), PHP_EOL;
04 · Python
import requests API = "https://api.opensolr.com/solr_manager/api/" AUTH = {"email": "YOUR_EMAIL", "api_key": "YOUR_API_KEY", "index_name": "YOUR_INDEX"} question = "How do I reset my password?" # Step 1: the best 4 results found = requests.post(API + "embed_and_search", data={ **AUTH, "q": question, "rows": 4, "fresh": "no", "in": "all", }, timeout=60).json() docs = found.get("results", {}).get("docs", []) # Step 2: one instruction with the question, the rules and the numbered content lines = [ "Answer the question using only the content below: " + question, "Begin with the answer itself. Use only what the content states.", "", "CONTENT:", ] for i, doc in enumerate(docs, start=1): text = " ".join(str(doc.get("text", "")).split()[:1500]) lines.append(f"[{i}] {doc.get('title', '')} - {doc.get('description', '')} - {text}") answer = requests.post(API + "ai_summary", data={**AUTH, "instruction": "\n".join(lines)}, timeout=300) print(answer.text)
05 · Good to know
Each call uses the monthly AI allowance of the account that owns the index: one request for a new search, one for a new answer. Both are free when they come from cache. Every plan includes a monthly AI allowance of 500 AI requests; see pricing and API Quota.
The search in step 1 uses the Search Tuning of your index; you can change it for that call only: Search Tuning for one call.
To ask for the answer as JSON with the documents it used, add answer_format=picks in step 2: ai_summary.