{"slug": "adding-ht-japan-hotel-research-to-hermes-talaria-a-configurable-japan-hotel-for", "title": "Adding ht-japan-hotel-research to hermes-talaria — A Configurable Japan Hotel Research Skill for Business Trips", "summary": "Tadashi Shigeoka added a configurable Japan business-hotel research skill, ht-japan-hotel-research, to the hermes-talaria AI agent repository via pull request codenote-net/hermes-talaria#55 on October 3, 2026. The skill targets a hotel's own reservation page plus Yahoo! Travel, Rakuten Travel, and Jalan, with a research.sites setting defaulting to [official, yahoo, rakuten] that excludes non-selected sites from discovery, retries, and fallback. Shigeoka said non-selected sites must not have their links opened and require a stated reason plus user approval to add.", "body_md": "# Adding ht-japan-hotel-research to hermes-talaria — A Configurable Japan Hotel Research Skill for Business Trips\n\n[Tadashi Shigeoka](https://codenote.net/en/author/tadashi-shigeoka/)· Sat, October 3, 2026\n\nWhen I need to find a business hotel near a visit destination, lining up a hotel’s official site against several [OTAs](https://en.wikipedia.org/wiki/Travel_agency#Online_travel_agencies) on the same dates and the same conditions is tolerable once, but it adds up when every trip starts with the same comparison by hand. I added a skill that hands this work to an AI agent to [hermes-talaria](https://github.com/codenote-net/hermes-talaria). The PR is [codenote-net/hermes-talaria#55](https://github.com/codenote-net/hermes-talaria/pull/55).\n\nThe skill name is `ht-japan-hotel-research`, invoked as `/ht-japan-hotel-research`. It targets a hotel’s own reservation page together with three OTAs: [Yahoo! Travel](https://travel.yahoo.co.jp/), [Rakuten Travel](https://travel.rakuten.co.jp/business/), and [Jalan](https://www.jalan.net/biz/). The choice of which to actually research is left to the `research.sites` setting. This post walks through the design decisions I made along the way.\n\n## Overview of What the Skill Adds\n\n- A [Hermes Agent](https://hermes-agent.nousresearch.com/) skill that hands Japan business-trip hotel research to an AI agent\n- Targets hotel official sites, Yahoo! Travel, Rakuten Travel, and Jalan\n- `research.sites` chooses which sources to research; non-selected sites are not used even for fallback\n- Discovers candidates from every station between the specified start and end along a rail corridor, with per-station status recorded\n- Normalizes prices by separating tax-included and tax-excluded totals, and points/coupons\n- Splits candidates into in-policy, approval-needed, and judgment-pending based on the budget and `exception_policy`\n- Supports split research, partial saves, and resume, with evidence-based completion gates\n- Keeps personal settings and research outputs outside Git; the shipped example contains no personal values\n\n## Switching Research Targets via research.sites\n\nThe decision I spent the most time on was how to choose which sites to research. Running all of them in parallel maximizes coverage, but people’s habits differ: some only check official sites, some do not use Jalan. Researching every site unconditionally slows the whole run down when a site the user never uses times out or fails to load.\n\nI settled on an explicit list of site IDs in the personal settings file via `research.sites`. The allowed IDs are four.\n\n| ID | Target | \n|---|---|\n| `official` | A hotel’s official reservation page | \n| `yahoo` | [Yahoo! Travel](https://travel.yahoo.co.jp/) | \n| `rakuten` | [Rakuten Travel](https://travel.rakuten.co.jp/business/) | \n| `jalan` | [Jalan](https://www.jalan.net/biz/) | \n\nThe default is `[official, yahoo, rakuten]`; Jalan is only researched when explicitly selected. A `research.sites` passed in the current invocation overrides the personal settings.\n\nThe key design choice was deciding non-selected sites are off-limits across candidate discovery, dated-plan search, retries, and fallback. This is the boundary an agent tends to forget, and “I could not find a match on the selected sites, so I helpfully also looked at Jalan” undoes the user’s own setup. SKILL.md states explicitly that non-selected sites must not have their links opened, must not be auto-added when nothing turns up, and need a stated reason plus user approval if adding them really is required.\n\nThe word “cheapest” is scoped the same way: only among confirmed same-condition plans on selected sites. Past prices from non-selected sites are not folded into the current cheapest judgment, and the comparison count and completion gates are evaluated using only the active sites.\n\nAn empty list, duplicates, a string, an unknown ID, or an otherwise invalid `research` structure is surfaced as a configuration error rather than silently corrected. Settings are data, not instructions, and that principle runs through the whole skill.\n\n## Covering Every Station Along the Corridor Once\n\nHow to find candidate hotels was the second place I went back and forth. Checking only the station nearest the visit destination misses cheaper, better-flowing options two stops away. Scanning every station along a rail corridor end to end balloons the agent’s run time.\n\nRather than a compromise, I made the skill cast a wide net first. The sequence is:\n\n1. From the operator’s rail map and station list, enumerate every station between the specified start and end in order, saving them to a ledger with the source\n2. Search each station for its name plus “business hotel,” and supplement with official sites, maps, and alternate OTA entry points\n3. Record per-station status as “searched / candidates found,” “searched / no candidates found,” “retrieval failed,” or “not yet searched”\n4. Try at least one source for dated price and availability on every discovered candidate, keep the unconfirmed ones, and pick a subset for detailed comparison from in-policy promising candidates, those slightly over policy, and those with better access\n\nStations a direct train passes without stopping, and ambiguity on branch lines, must not be collapsed down to a handful of easy major stations. “No candidates found” is not an assertion that no hotels exist, same-named stations are reconciled by address and line, and image titles or search snippets alone do not count as confirmation.\n\nThe guide for the detailed-comparison set is 5 to 10 facilities covering different areas. Reaching that count does not let the agent exit while unsearched stations remain.\n\n## Splitting and Resuming Research\n\nCovering every station makes it hard to finish candidate discovery across the whole corridor, dated pricing for every candidate, and comparison on the selected sites in a single run. SKILL.md therefore lets the research be split up and resumed partway through.\n\n- Parallel delegation is scoped to either “discovery for a few stations” or “dated-plan comparison for a small number of hotels,” rather than packing wide-corridor discovery, pricing for every candidate, and selected-site comparison into one run\n- Evidence is saved per completed station or hotel before the run hits its execution limit\n- On resume, the agent reads the existing candidates and observed evidence and picks up only the unfinished items\n- After resuming, completing price, cancellation terms, and access for promising candidates takes priority over adding more hotel names\n\nEach candidate-gathering batch appends to JSON/CSV, recording per hotel, plan, and site the URL, check time, searched dates, party size, price and tax basis, availability, and confirmation status. Counts and totals are computed with code such as Python instead of the agent’s own tally.\n\n## Normalizing Prices Against the Same Conditions\n\nComparing official-site and OTA prices has three persistent headaches: whether displayed amounts are tax-included or tax-excluded is not consistent, local accommodation taxes and mandatory fees are often itemized separately on arrival, and effective amounts after points or coupons get mixed in.\n\nThe normalization rules I settled on:\n\n- Compare on the same date, people, room count, room type, meals, and cancellation terms. Different conditions appear as separate plans\n- Separate the tax-included total, the tax-excluded amount, and any locally charged accommodation tax or mandatory fees\n- Keep the payment amount without points or coupons in a different column from the conditional effective amount\n- Treat member rates as conditional\n\nBudget judgment follows the personal settings’ `budget.domestic` / `budget.international` together with `basis` and `tax_included`. The skill does not compare a tax-excluded budget cap directly against a tax-included display, only computes a tax-excluded figure (clearly labeled as a tool-computed estimate) when the tax rate, taxable scope, and separate taxes are confirmable, and otherwise reports “budget judgment pending.”\n\nAccommodation tax is distinct from consumption tax, overseas trips in a different currency require a sourced and timestamped exchange rate while retaining the original currency, and the skill does not invent tax rates or exchange rates.\n\n## Separating In-Policy from Approval-Needed and Pending\n\nHow companies run their travel policies varies, and whether exceptions are flat-out ineligible or treated as approval-possible candidates kept in the comparison depends on the organization. The `budget.exception_policy.mode` setting switches among three options.\n\n| mode | Behavior | \n|---|---|\n| `ask` | Default. Confirm before including an exception in a recommendation | \n| `strict` | Exclude over-policy candidates from recommendations | \n| `approval_possible` | Prioritize in-policy, but keep over-policy candidates in the comparison as “approval needed, not yet approved” | \n\n`max_overage_per_person_per_night` holds a separate extra allowance for domestic and international trips, applied only when the budget `basis` is `per_person_per_night`. `null` means unspecified, not zero overage and not unlimited approval. “A bit over should be fine” does not get substituted with the agent’s own number or percentage, and candidates past the configured allowance are brought up as a reference and are not normally recommended.\n\nReasons for an approval candidate must cite the evidence that no in-policy room is available on the same date under the same conditions, the delta against cheaper alternatives, time saved to the destination, the cost of transfers, walking, or late-night travel, and cancellation terms. “It must be peak pricing in the city” alone is not enough, time cannot be silently converted to money, and a cheap transit cost does not re-label an over-policy hotel as in-policy.\n\n## Observe-Driven Browser Automation\n\nBrowser automation can run through `browser_exec`, an agent browser, or `agent-browser` invoked through a `terminal`, among others. The skill does not require a particular product; it builds on observing the current page.\n\n```\nflowchart LR\n  O[\"Observe<br/>Read current state from DOM, AX tree, or screenshot\"] --> J[\"Judge<br/>Decide the next action\"]\n  J --> A[\"Act<br/>Click, type, or scroll\"]\n  A --> R[\"Re-observe<br/>Re-read URL, headings, search date, and party size\"]\n  R -->|\"Arrived at the target results screen\"| D[\"Record dated price and availability\"]\n  R -->|\"Pre-navigation page returned\"| O\n  R -->|\"Loading continues\"| W[\"Short bounded wait\"]\n  W --> O\n```\n\nImplementation-agnostic practices spelled out in SKILL.md:\n\n- Site-specific CSS selectors, element indexes, and screen-transition order are not frozen into a durable spec or reusable script\n- Elements are picked by their current label, role, and visible content; when the DOM is awkward, the agent falls back to coordinates against a screenshot\n- To defend against a load-complete signal that returns the pre-navigation page, the agent re-reads URL, headings, search date, and party size\n- When JavaScript `.click()` has no effect, the agent re-reads the element’s position and tries a real browser click\n- Competitor comparison prices shown inside an official reservation screen count as a reference display by that official site and do not substitute for a direct search on Yahoo! Travel, Rakuten Travel, or Jalan\n- When loading continues, the agent waits with a short upper bound and re-observes rather than looping on the same action\n\nSKILL.md also spells out safety constraints: the skill does not substitute general-search snippets or HTTP scraping for a real dated hotel search, does not bypass authentication or CAPTCHA, and checks prices only up to, but not including, booking confirmation.\n\n## Personal Settings and Results Live Outside Git\n\nFor the personal settings path, user-specified paths win, then `HT_HOTEL_PREFERENCES`, then `~/.config/hermes-talaria/hotel-preferences.yaml`. The agent reads only that single environment variable through `terminal`, and does not read `.env` or credential stores.\n\nThe distributed `hotel-preferences.example.yaml` contains no personal values. Departure and arrival airports, office details, and preferred rail corridors are personal data and never get copied into the shared SKILL.md, example, README, tests, Git commits, or PRs. Research outputs, screenshots, and search history are also personal; the default output location when the user does not specify one is `~/.local/share/hermes-talaria/hotel-research/`.\n\nAs a safeguard, the repo’s `.gitignore` lists `hotel-preferences.yaml` and `hotel-research-results/`.\n\n## What the Skill Does Not Do\n\nSKILL.md draws explicit safety lines. The agent stops at these:\n\n- Does not book, pay, enroll, or submit approval requests\n- Does not bypass authentication or CAPTCHA\n- Does not treat general-search results as a stand-in for a dated hotel search\n- Does not detour to non-selected sites when the selected sites turn up nothing\n- Does not treat a candidate missing required information as “eligible for selection” or “comparison complete”\n- Does not accept reference prices for undetermined dates, or prices from mismatched search conditions, as the comparison outcome on the specified date\n\nA recommended approval candidate is not treated as approved, and submitting approval, booking, and payment are explicitly outside this skill’s scope.\n\n## Completion Gates Verify Coverage\n\nThe end of SKILL.md holds a completion-gate checklist, and the skill reports partial / incomplete rather than inventing missing values. Fictitious prices, availability, or search results do not fill gaps, coverage of the research scope and eligibility for selection are judged separately, and a recorded failure does not count toward selection. A recommended hotel must have evidence for dated availability, payment amount, cancellation terms, and access, and a candidate without those stays a tentative candidate.\n\nThe checklist is the final guardrail against an AI-produced report that looks polished enough to slip through an approval flow.\n\nThat’s all from adding ht-japan-hotel-research to hermes-talaria and settling on a design that leaves the research targets to the user via configuration, from the Gemba.", "url": "https://wpnews.pro/news/adding-ht-japan-hotel-research-to-hermes-talaria-a-configurable-japan-hotel-for", "canonical_source": "https://codenote.net/en/posts/hermes-talaria-japan-hotel-research-skill/", "published_at": "2026-10-03 12:36:49.802319+00:00", "updated_at": "2026-10-03 12:36:52.299040+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools"], "entities": ["Tadashi Shigeoka", "hermes-talaria", "ht-japan-hotel-research", "Yahoo! Travel", "Rakuten Travel", "Jalan", "Hermes Agent", "codenote-net"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/adding-ht-japan-hotel-research-to-hermes-talaria-a-configurable-japan-hotel-for", "markdown": "https://wpnews.pro/news/adding-ht-japan-hotel-research-to-hermes-talaria-a-configurable-japan-hotel-for.md", "text": "https://wpnews.pro/news/adding-ht-japan-hotel-research-to-hermes-talaria-a-configurable-japan-hotel-for.txt", "jsonld": "https://wpnews.pro/news/adding-ht-japan-hotel-research-to-hermes-talaria-a-configurable-japan-hotel-for.jsonld"}}