Skip to main content

Search Tuning

Search tuning is the process of improving tool retrieval without turning the LLM prompt into the only source of truth. Tune the catalog evidence first, then the ranking policy, and only then the prompt.

The goal is not to make one manual query look better. The goal is to make a named query suite improve in a way that can be reproduced, reviewed, and rolled back.

Tuning Loop

choose query suite
-> capture baseline evidence
-> classify misses
-> improve evidence
metadata/contracts/aliases
-> rerun the same suite
-> compare metrics
and evidence
-> promote repeatable
improvements

Use the same fixture, source artifact, and Top-K value before and after the change. Otherwise, the result is not a meaningful comparison.

Start With A Query Suite

Create a small suite that represents real work. Each case should have a query, the expected target, and the stage you want to validate.

{
"id": "refund_list",
"query": "find refund-ready orders",
"expected_target": "searchOrders",
"mode": "search",
"top_k": 8
}

Keep the suite small during development. Broaden it before release or public quality claims.

Capture Evidence

Use include_evidence=True whenever you tune search. The evidence object is the debuggable contract between retrieval, target selection, planning, and product UI.

from graph_tool_call import ToolGraph
from graph_tool_call.graphify import retrieve_graphify

graph = ToolGraph.load("collection.json")
baseline = retrieve_graphify(
graph,
query="find refund-ready orders",
top_k=8,
include_evidence=True,
)

for row in baseline["results"]:
print(row["name"])
print(row["score_breakdown"])
print(row.get("semantic_evidence", {}))

Capture:

  • ranked candidate names
  • expected target rank
  • score breakdown
  • semantic and contract evidence
  • graph expansion source
  • token budget used
  • selector decision, if target selection is part of the case

Do not store raw auth headers, cookies, full request bodies, full response bodies, user identifiers, or secrets.

Read The Signals

Start with evidence quality. Weight changes should be the last step.

SignalInspect WhenLikely Fix
seedexpected tool is outside Top-Knames, summaries, aliases
action_matchsearch/read/create/update/delete intent is wrongcanonical_action derivation
resource_matchright action but wrong objectprimary_resource or resource aliases
module_matchlarge catalog returns another domainpath_module, operation group, module aliases
shape_matchlist/detail/count/mutation sibling is wrongresult_shape derivation
contract_matchquery entities are ignoredrequest/response contract extraction
graph_expansionproducer or next-step tool is missingdata-flow edges and producer expansion
learningrepeated successful corrections are not reusedshadow/promotion state

If a signal is empty, fix the source evidence. If a signal exists but is underweighted across many cases, then consider tuning weights.

Miss Taxonomy

Classify every failing case before changing code.

CategoryMeaningFirst Place To Look
not_retrievedexpected target is outside Top-Kindexed text and semantic metadata
low_rankexpected target appears but is below weaker siblingsscore breakdown and shape/resource evidence
wrong_shapelist/detail/count/mutation is confusedresult_shape, response schema, operation id
wrong_resourceaction is right but business object is wrongprimary_resource, path module, aliases
module_leakanother domain wins in a large catalogpath_module, source label, module aliases
producer_missingtarget found, plan cannot fill required fieldsapi_contract.produces and data-flow edges
selector_mismatchcorrect tool is in Top-K but final target is wrongtarget_selector.rank_signals
auth_or_executesearch/plan passed but API call failedauth readiness, runner events, HTTP status

Do not mix categories. A search miss and an execution auth failure need different fixes.

Tuning Actions

Apply the smallest product-neutral fix that improves the evidence.

ActionScopeNotes
add generic aliasesadapter optionsGood when users use business terms absent from OpenAPI
improve semantic derivationengineGood when many operations share the same naming pattern
repair response schemassource or adapter repairRequired for producer expansion and result shape
repair request schemassource or adapter repairRequired for plan synthesis and missing field diagnostics
add manual edgeartifact metadataUse for known workflow relations that the source cannot express
promote learning suggestioncollection-localUse only after repeated validated success
adjust ranking weightengine policyUse only after evidence exists and many cases support the change

Avoid one-off operation-name hacks in the engine. If the rule mentions a single customer, endpoint, or private field name, it belongs in adapter options or manual metadata.

Alias Strategy

Aliases are useful when users and OpenAPI authors use different words.

artifact = build_openapi_collection_artifact(
"openapi.json",
semantic_options={
"resource_aliases": {
"refund": "claim",
"buyer": "customer",
"delivery": "shipment",
},
"action_aliases": {
"lookup": "read",
"find": "search",
},
},
)

Keep aliases generic. Product adapters can pass customer-specific aliases at build time; the library should remain reusable.

Selector Tuning

When the expected target is already in Top-K, inspect target selection instead of widening retrieval.

from graph_tool_call.graphify import select_target_candidate

selection = select_target_candidate(
query=case["query"],
candidates=[
row["name"]
for row in retrieval["results"]
],
tools=artifact["tools"],
retrieval_results=retrieval["results"],
llm_target=llm_target,
)

print(selection["selected_target"])
print(selection["reason_codes"])
print(selection["rank_signals"])

A selector override is healthy only when strong evidence and enough margin exist. Weak evidence should produce ambiguous_target, not a silent correction.

Learning Evidence

Trace learning should be conservative:

  1. Store scrubbed attempts.
  2. Create suggestions in shadow mode.
  3. Compare baseline rank with learning-applied shadow rank.
  4. Promote only repeated successful target or plan-path evidence.
  5. Keep learning boosts low-weight and visible in rank_signals.

Never treat one successful run as permanent ranking truth.

Acceptance Gates

A tuning change should report at least:

MetricWhy It Matters
query countprevents overclaiming from one example
Top-1 hit ratedirect ranking quality
Top-3 or Top-8 hit raterecall for LLM/selector handoff
average candidate countcontext pressure
max candidate countworst-case prompt size
selector override countguardrail activity
selector ambiguity countunresolved sibling confusion
plan hit ratewhether search results are usable by planning
unsatisfied_field countcontract quality
uncaught error countadapter/runtime stability

For public claims, record model/provider information whenever an LLM is part of the result.

Anti-Patterns

Avoid:

  • hard-coding product-specific operation names in the engine
  • boosting raw descriptions until noisy OpenAPI text dominates results
  • changing global weights to fix one query
  • declaring improvement from a manual demo query
  • widening Top-K until the correct tool appears but the LLM sees too much
  • storing secrets or raw API payloads as search evidence
  • promoting learning suggestions without repeated validation