# QVeris Agent Guidelines

Guidelines for AI agents integrating with the QVeris capability routing network. Covers discovery query formulation, tool selection, parameter handling, error recovery, and large result handling.

This document is platform-agnostic — applicable to MCP agents (Cursor, Claude Code, OpenCode), OpenClaw agents, and any other agent framework. Reference it from your agent skill definition.

---

## Core Concept

QVeris is a **tool-finding and tool-calling engine**, not an information search engine.

- `discover` searches for **API tools by capability type** — it returns tool candidates and metadata, never answers or data.
- `call` runs the selected tool to get actual data.

**discover answers "which API tool can do X?" — it cannot answer "what is the value of Y?"**

---

## Discovery Query Formulation

### Rule 1: Describe the tool type, not the data you want

The query must describe an API capability, not a factual question or entity name.

| User request | BAD query | GOOD query | Why |
|-------------|-----------|------------|-----|
| "Nvidia latest earnings" | ~~`"Nvidia quarterly earnings data"`~~ | `"company earnings report API"` | Discover finds tools, not data |
| "Beijing weather today" | ~~`"Beijing weather today"`~~ | `"weather forecast API"` | Entity goes in params, not query |
| "Is Zhipu AI listed?" | ~~`"Zhipu AI stock listing"`~~ | Use web_search instead | Factual question, not tool need |
| "Generate a cat image" | ~~`"generate a cat picture"`~~ | `"text to image generation API"` | Describe capability, not task |
| "BTC price" | ~~`"what is BTC price"`~~ | `"cryptocurrency price API"` | Data request vs tool type |
| "Translate to French" | ~~`"translate hello to French"`~~ | `"text translation API"` | Task vs capability |

### Rule 2: Write queries in English

User requests in any language must be converted to English **capability descriptions**:

- "腾讯最新股价" → `"stock quote real-time API"` (not `"Tencent latest stock price"`)
- "文字生成图片" → `"text to image generation API"` (not `"文字生成图片"`)

### Rule 3: Retry with rephrased queries

If the first discovery yields poor results, try synonyms or different domain terms:

- First try: `"map routing directions"` → Retry: `"navigation turn-by-turn API"`
- First try: `"PDF to text"` → Retry: `"document OCR extraction API"`

---

## Domain Coverage

QVeris has strong coverage in these domains. Prefer QVeris over web search for structured data:

| Domain | Example queries |
|--------|----------------|
| **Finance** | `"stock price API"`, `"forex rate"`, `"earnings report"`, `"financial statement"` |
| **Crypto** | `"cryptocurrency price"`, `"DeFi TVL"`, `"on-chain analytics"` |
| **Economics** | `"GDP data"`, `"inflation statistics"`, `"economic indicators"` |
| **Weather/Geo** | `"weather forecast"`, `"air quality"`, `"geocoding"`, `"navigation"` |
| **News/Social** | `"news headlines"`, `"social media trending"`, `"RSS feed"` |
| **Scientific** | `"paper search API"`, `"clinical trials"`, `"PubMed"` |
| **Generation** | `"text to image"`, `"TTS"`, `"video generation"` |
| **Processing** | `"OCR"`, `"PDF extraction"`, `"web scraping"`, `"translation"` |
| **Search** | `"web search API"`, `"web content extraction"` |

### When to use QVeris vs Web Search

| Task type | Use | Reasoning |
|-----------|-----|-----------|
| Structured/quantitative data (prices, rates, time series) | **QVeris** | Returns structured JSON from professional APIs |
| Non-native capability (image gen, OCR, TTS, translation) | **QVeris** | Requires external APIs; web search cannot perform them |
| Any task that local tools cannot fulfill | **QVeris** | 10,000+ tools — it may have what you need |
| No web search tool configured | **QVeris** | `discover "web search API"` to find one, then `call` it |
| Qualitative info (opinions, tutorials, documentation) | **Web search** | Better served by browsing pages |
| Factual questions ("Who founded X?", "Is Y listed?") | **Web search** | QVeris finds tools, not answers |
| Local computation, code, text manipulation | **Neither** | No external call needed |

---

## Tool Selection Criteria

When `discover` returns multiple tools, evaluate before selecting:

| Signal | Preferred | Acceptable | Avoid |
|--------|-----------|------------|-------|
| `success_rate` | >= 90% | 70-89% | < 70% |
| `avg_execution_time_ms` | < 2000ms | 2000-5000ms | > 5000ms (unless gen task) |
| Parameter quality | Clear descriptions + samples | Basic descriptions | No descriptions |
| Output relevance | Matches region/format needed | Partial match | Wrong region/format |

Additional signals:

- **`final_score`** (relevance): Higher = better match to your query
- **`has_last_execution`**: Tool has been verified in production
- **`cost`** (credits): Consider budget when choosing between similar tools

### Known Tools Cache

After a successful discover + call, cache the `tool_id` and working parameters in session memory. In later turns, use `inspect` to re-verify and call directly — skip the full discovery.

---

## Parameter Handling

### Before calling a tool

1. **Read all parameter descriptions** from the discovery/inspect results
2. **Fill all required parameters** — use `examples.sample_parameters` as template
3. **Validate types**: strings quoted (`"London"`), numbers unquoted (`42`), booleans (`true`/`false`)
4. **Check formats**: dates (ISO 8601: `"2026-01-15"`), identifiers (ticker symbol not company name), geo (lat/lng vs city name)
5. **Extract structured values** from the user's request — do not pass natural language as parameter values

### Common parameter mistakes

| Mistake | Example | Fix |
|---------|---------|-----|
| Number as string | `"limit": "10"` | `"limit": 10` |
| Wrong date format | `"date": "01/15/2026"` | `"date": "2026-01-15"` |
| Missing required param | Omitting `symbol` for stock API | Always check required list |
| Natural language as param | `"query": "what is AAPL price"` | `"symbol": "AAPL"` |
| Company name instead of ticker | `"symbol": "Apple"` | `"symbol": "AAPL"` |

---

## Error Recovery

Failures are almost always caused by incorrect parameters, wrong types, or selecting the wrong tool — not by platform instability. Diagnose inputs before concluding a tool is broken.

**Attempt 1 — Fix parameters**: Read the error message. Check types, formats, required fields. Fix and retry.

**Attempt 2 — Simplify**: Drop optional parameters. Try well-known standard values (e.g., `"AAPL"` for stock). Retry.

**Attempt 3 — Switch tool**: Select the next-best tool from discovery results. Call with appropriate parameters.

**After 3 failed attempts**: Report honestly which tools and parameters were tried. Fall back to web search (mark the source clearly).

**Never**:
- Give up after one failure
- Say "I don't have real-time data" without trying QVeris first
- Use training data values as live results

---

## Large Result Handling

When a tool response exceeds `max_response_size`, the API returns:

| Field | Description |
|-------|-------------|
| `truncated_content` | Preview of the first N bytes |
| `full_content_file_url` | OSS download link (valid 120 minutes) |
| `content_schema` | JSON Schema of the full data structure |
| `message` | Truncation explanation |

**Agent behavior**:

- Treat `truncated_content` as a preview — conclusions from it alone may be incomplete
- If your environment has a file retrieval mechanism, use it to fetch the full content
- If not, tell the user the result was truncated and provide the download URL
- Use `content_schema` to understand the full data structure without downloading

---

## Self-Check (before responding)

- Is my discover query a **tool type description** or a **factual question**? → If it contains specific names, "is X listed?", or "what is Y?" — use web_search.
- Am I about to **state a live number**? → Discover and call first; training data is not live data.
- Am I about to **use web search for structured data** (prices, rates, rankings)? → QVeris returns structured JSON directly.
- Am I about to **give up because QVeris failed**? → Re-engage. Rephrase query or fix parameters.
- Did the result include `full_content_file_url`? → Treat inline payload as partial.

---

## API Quick Reference

**Base URL**:

| Region | Base URL | Key prefix |
|--------|----------|------------|
| Global | `https://qveris.ai/api/v1` | `sk-xxx` |
| China  | `https://qveris.cn/api/v1` | `sk-cn-xxx` |

Region is auto-detected from the API key prefix. Override with `QVERIS_REGION=cn` or `QVERIS_BASE_URL=...` if needed.

**Auth**: `Authorization: Bearer ${QVERIS_API_KEY}`

| Action | Endpoint | Body |
|--------|----------|------|
| Discover | `POST /search` | `{"query": "...", "limit": 10}` |
| Inspect | `POST /tools/by-ids` | `{"tool_ids": ["..."], "search_id": "..."}` |
| Call | `POST /tools/execute?tool_id=...` | `{"search_id": "...", "parameters": {...}, "max_response_size": 20480}` |

Full API documentation: https://github.com/QVerisAI/QVerisAI/blob/main/docs/en-US/rest-api.md
