TrainLCD org ã® Issueã»PRã»ãªããžããªææžã»ãŠãŒã¶ãŒãã£ãŒãããã¯ãæ€çŽ¢ãããããã¬ã¹APIãé¢é£æ§ã®å€å®ãé äœä»ããåç §ææžã®éžæãåŒç𿀿»ã Rust/WASMã®ããŒã«ã«ã«ãŒã«ã§å®è¡ãããDecisionã®å€éšAPIãã¢ãã«éã¿ãGPUã¯äžèŠã
ãããã¬ã¹åŽã®ã«ãŒãã£ã³ã°ã»èªèšŒã»æ€çŽ¢ã»D1æäœã»GitHubåæã»ãªãªãŒã¹å€å®ã»Webhookã»Queuesã»åçæ€æ»ã»SSEåŠç㯠backend/ ã®Rustå®è£
ãsrc/host.ts ãš src/worker.ts ã¯Cloudflareã®I/Oãã€ã³ãã£ã³ã°ã ããæ
åœãããå€å®ã³ã¢ã¯ãã€ãã£ãã®JSON Lines CLIãšããŠãåäœããã
- å
¬éç¯å²ã確èªããŠããD1ã®ææžåè£ãèªãã540ææžãã€èªã¿èŸŒã¿ãèš±å¯ãããç¯å²ãå
šä»¶èµ°æ»ããã
MAX_SCREENED_DOCUMENTSãè¶ ããã°422ã§çµäºããéšåçãªèµ°æ»ãæåæ±ãããªãã - Rustã§NFKCæ£èŠåãæ¥è±ã®çšèªå¯Ÿå¿ãæè¡èå¥åãçªå·ãæªç¥ã®æ¥æ¬èªåãç
§åãããèªã®ã«ããŒçãšèŠåºãã®äžèŽãéã¿ä»ããããèªåœãšéæ¥çãªææããã¯
rust/rules.rsãšrust/lib.rsã«çœ®ãã - äžäœ30ææžãšã¹ã³ã¢0.5è¶ ã®ææžãæ®ããæ€çŽ¢ç¯å²å ã®æç€ºçãªåäžãªããžããªåç §ã1段ã ããã©ããåŸæ¥ã®AIã«ããç²ãã°ã«ãŒãéžå¥ã¯è¡ããªãã
- æ¬æåºéãRustã§ç¬ç«æ¡ç¹ãã0.5è¶
ãé¢é£æ¬æãšãããåç¹ã¯å
ã®é çªãç¶æãããAPIã®
relevanceããã³å éšäºæåprobabilityã¯ã«ãŒã«ã¹ã³ã¢ã§ãããæ ¡æ£ããã確çã§ã¯ãªãã - Webã¯å šé¢é£æ¬æãååŸåŸã«10ä»¶ãã€è¡šç€ºãããå šä»¶æ°ã»ç·ããŒãžæ°ã¯åãçµæéåããç®åºããããŒãžéãã§ã¯æ€çŽ¢ã»å€å®ã»æç« çæãåå®è¡ããªãã
/answer ã®æç« çææ¥ç¶ãšSSEã¯ç¶æãããããŒã«ã«æ€æ»ã¯åŒçšIDãåæäžèŽãçšèªã®å¯Ÿå¿ãåŠå®ã»æ¡ä»¶ã»æšæž¬è¡šçŸãæ°å€ãåå ã»é
ä¿¡ã»å€æŽã®æå®ãæ€æ»ãããåæãšå®å
šäžèŽããªãã ãã§åçãåé€ãããåŒçšå
ãšé¢é£ãããæç€ºçãªã«ãŒã«éåãèŠã€ãããªãèšãæããè¿ããèªå¥ã®é¡äŒŒã¯æå³ã®èšŒæã§ã¯ãªããããverification.method=local_support_rulesãsemantic_status=unknown ãšããreasonsã§åæäžèŽã»ã«ãŒã«ã«ããæ¯æã»æå³çæ¯æã®æªç¢ºå®ãåºå¥ãããåçã®å®å
šæ§ãšæå³çãªççŸæ€åºãunknownã§ãããåŒçšå
äžæã»é¢é£ãªãã»æ€åºå¯èœãªåŠå®åè»¢ãæ ¹æ ã®ãªãé
ä¿¡æå®ãªã©ã¯é€å€ããæ®ãåçããªããã°åæããè³æã®èšèŒããšããŠåŒçšããã
æ€çŽ¢çµæã¯ä»¥åã®ã¢ãã«ãšäžèŽãããšã¯éããªããå®è³æ40åºéã§ã®åçŸå¯èœãªæ¯èŒãšæªæ€èšŒç¯å²ã¯ rust-local-decisions.md ãåç §ã
| 察象 | å 容 |
|---|---|
| orgå Issue | æ¬æãå šã³ã¡ã³ããç¶æ ãã©ãã«ãæçš¿è |
| orgå PR | æ¬æãäŒè©±ãã¬ãã¥ãŒãã€ã³ã©ã€ã³ã¬ãã¥ãŒã倿Žãã¡ã€ã«åãããŒãžæ¥æãããŒãžå ãã©ã³ã |
| åãªããžããªææž | ããã©ã«ããã©ã³ãã® .md, .mdx, .rst, .adoc, .txtãvendor/buildçãé€å€ |
TrainLCD/Issues |
åãIssueãéè€ç»é²ãã feedback ãšããŠä¿å |
åå POST /sync ã§orgå
ã®ã¢ã¯ã»ã¹å¯èœãªãªããžããªãåæããQueuesã§åå²åã蟌ã¿ããã6æéããšã®CronãšWebhookã§æŽæ°ãããIssue/PRã®å·®åå·¡åã«ã¯10åã®éè€æéãèšãããææžã®URLã¯ã³ãããSHAåºå®ãææžåé€ã¯å®å
šãªããªãŒååŸåŸã«åæ ããå€ãã³ãããã®ãžã§ãã¯ç Žæ£ããã
ãªããžããªããšã«GitHubã®ææ°æ£åŒãªãªãŒã¹ãåæããããªãªãŒã¹ã¿ã°ãæãã³ãããã®å±¥æŽã«PRã®ããŒãžã³ããããå«ãŸãããšç¢ºèªã§ããå Žåãæ ¹æ ã« metadata.github_releaseïŒã¿ã°ãURLãå
¬éæ¥æïŒã远å ãããç»é¢ã¯ãã®GitHubãªãªãŒã¹ã«åé²ãããããšã衚瀺ãããååºããŒãžã§ã³ãApp Storeã»Google Playã®é
ä¿¡ç¶æ³ã¯å¥ã®æ
å ±æºãå¿
èŠã«ãªãã
Node.js 24以éãšRust stableãå¿
èŠããã¹ã㯠node:sqlite ã䜿ãã
rustup target add wasm32-unknown-unknown
cargo install wasm-bindgen-cli --version 0.2.129 --locked
npm ci
cargo test --workspace --locked
npm run build:rust
npm run check
npm test
npx wrangler d1 create trainlcd-decision-rag
npx wrangler queues create trainlcd-rag-sync
npx wrangler queues create trainlcd-rag-sync-dlqäœæãããD1 IDã wrangler.jsonc ã® database_id ã«èšå®ããããŒãã®IDã¯äŸç€ºçšã§ãããå®ç°å¢ã«ã¯ãã®ãŸãŸãããã€ããªãã
npm run db:remote
npx wrangler secret put API_TOKEN
npx wrangler secret put WEBHOOK_SECRET
npx wrangler secret put GITHUB_TOKENAPI_TOKEN: ãã£ãŒãããã¯æ€çŽ¢ã»åæã»ç®¡ççšã®BearerããŒã¯ã³ãååé·ãã©ã³ãã å€ãèšå®ãããWEBHOOK_SECRET: GitHub Webhookãšåãå€ãGITHUB_TOKEN: orgå 察象ãªããžããªã®Metadataã»Contentsã»Issuesã»Pull requestsã®èªã¿åãæš©éãå¿ èŠããªããžããªäœæã»æžãèŸŒã¿æš©éã¯äžèŠã- å€å®ã¯Rust/WASMå
ã§å®çµããã
AIã¯æç« çæã«ã®ã¿äœ¿çšãããSCREENING_MODELãTYPESAFE_API_KEYãJEV_MODELã¯æ¬çªã®å€å®ã§ã¯åç §ããªãã
æ¢å®ã®æç« çæã«ã¯ Cloudflare Workers AI ã® AI ãã€ã³ãã£ã³ã°ã䜿ããå¥ã®çæãµãŒãã¹ã䜿ãå Žåã¯ãANSWER_MODELã»ANSWER_BASE_URL ãèšå®ããwrangler secret put ANSWER_API_KEY ãå®è¡ãããOpenAIäºæã® /chat/completions ãšJSON objectåºåã«å¯Ÿå¿ãããããã€ããŒãæ³å®ããããµã³ãã«Webã¢ããªã§ã¯SSEã¹ããªãŒãã³ã°ïŒstream: trueãstream_options.include_usage: trueïŒãžã®å¯Ÿå¿ãå¿
èŠãšãªããéã¹ããªãŒãã³ã°ãžã®ãã©ãŒã«ããã¯ã¯ãªããæªå¯Ÿå¿ã®ãããã€ããŒã§ã¯Webã¢ããªã®èŠçŽã倱æããå ŽåããããAcceptããããŒãçç¥ããJSON APIã¯åŒãç¶ãéã¹ããªãŒãã³ã°ã§åäœãããæ ¹æ ã®æ¬æã¯èšå®ãããæç« çæãµãŒãã¹ã«ã®ã¿éä¿¡ããããæ€çŽ¢ã ãã§ã¯AIãµãŒãã¹ãžã®éä¿¡ã¯çºçããªãã
workers_dev ã¯æ¢å®ã§ falseãå©çšãããã¹ãåã®routeãèšå®ããããæå³ã㊠true ã«å€æŽããŠãã npm run deploy ãå®è¡ãããå
¬éè³æã®æ€çŽ¢ã»èŠçŽã¯èªèšŒãªãã§äœ¿ããããã£ãŒãããã¯æ€çŽ¢ãåæã管çAPIã¯BearerèªèšŒãå¿
é ãWebhookã¯HMAC-SHA256çœ²åæ€èšŒãå¿
é ãè€æ°ãŠãŒã¶ãŒåãã®ACLã¯å®è£
ããŠããªãããããã®APIããŒã¯ã³ãä»è
ã«é
åžããªãããšã
ããŒã«ã«éçº:
cp .dev.vars.example .dev.vars
# .dev.varsã®å€ãèªåã®ããŒã«èšå®ãã
npm run db:local
npm run dev.dev.varsã.envãããŒã«ã«D1ããŒã¿ã¯git察象å€ã
npm run dev ã§è¡šç€ºãããããŒã«ã«URLã® / ããå
¬éè³æãæ€çŽ¢ã§ãããããã£ãŒãããã¯ãå«ããããéžãã ãšãããããããŒã®ã¡ãã¥ãŒããåææäœããããšãã¯ãAPI_TOKEN ã§æ¥ç¶ãããèªèšŒã«æåããå©çšããŒã¯åããã©ãŠã¶ãŒã«ä¿åãããæ¬¡åã¢ã¯ã»ã¹æã«åèªèšŒããããæ¥ç¶è§£é€ãŸãã¯ä¿åæžã¿ã®ããŒãèªèšŒã§æåŠããããšãã«æ¶å»ãããã
æ¢åã® trainlcd-decision-rag Worker ã察象ã«ãããæå¹åã®åã«ãå
¬éäžã® Worker ã®ãœãŒã¹ãããã©ã«ããã©ã³ããžåã蟌ã¿ãD1 ãš Queues ã®ãã€ã³ãã£ã³ã°ã wrangler.jsonc ãšäžèŽããããšã確èªããã
- GitHub ã® Settings â Environments â
productionã§ãDeployment branches and tags ã Selected branches and tags ã«èšå®ããããã©ã«ããã©ã³ãïŒçŸåšã¯mainïŒã ãã Branch ã«ãŒã«ã«è¿œå ãããæ¬çªãããã€ã«æ¿èªãå¿ èŠãªå Žåã¯ãåãç°å¢ã§ Required reviewers ãèšå®ãããåãç°å¢ã«CLOUDFLARE_API_TOKENãšCLOUDFLARE_ACCOUNT_IDã Secrets ãšããŠç»é²ããã - åãç°å¢ã® Variables ã«ãæ¢åã®æ¬çª D1 ã® ID ã
DECISIONRAG_D1_DATABASE_IDãšããŠç»é²ããã - Cloudflare ã®æ¬çª Worker ã® Variables and Secrets ã§
GITHUB_ORGãTrainLCDã«èšå®ãããŠããããšã確èªããã - ãªããžããªã® Actions Variables ã«
DECISIONRAG_DEPLOY_ENABLED=trueãèšå®ããã
æå¹ååŸã¯ãããã©ã«ããã©ã³ããžã® push ãŸãã¯åãã©ã³ãã§ã®æåå®è¡ã§ CI ãèµ°ããæ€èšŒãééãããããã€ãžã§ãã¯é çªã«å®è¡ãããåãžã§ãããããã€çŽåã«ããã©ã«ããã©ã³ãã®ææ°ã³ããããã©ããã確èªãããèªåãããã€ã¯ wrangler.jsonc ã® vars ãé€å€ããCloudflare ã«ç»é²æžã¿ã®æ¬çªå€æ°ãš Secrets ãåŒãç¶ããSUPPORT_THRESHOLD ãªã©ã®æ¬çªå€ã¯ãCloudflare ã®æ¬çª Worker ã® Variables and Secrets ã§å€æŽããã
CI 㯠wrangler versions upload ãš wrangler versions deploy ã§ã³ãŒãã®ããŒãžã§ã³ãæŽæ°ãããworkers.devãã«ã¹ã¿ã ãã¡ã€ã³ãCron ãªã©ã®å
¬éçµè·¯ãããªã¬ãŒã¯ Cloudflare åŽã®æ¢åèšå®ã䜿ãããããã倿Žããå Žå㯠Cloudflare åŽã§å¥éèšå®ããã
åäžãªããžããªã® PR 㯠CI æååŸãPreview PR ãžã§ãã§æ¬çª Worker ã®æªå
¬éããŒãžã§ã³ãã¢ããããŒããããActions ã®ãžã§ã Summary ã«ãã Open preview ãã確èªã§ãããURL ã¯åã¢ããããŒãã«åºå®ãããpr-çªå· ã®ãšã€ãªã¢ã¹ãçºè¡ãããæ¬çªãã©ãã£ãã¯ã®åãæ¿ãã¯è¡ããªãã
æ¬çª D1ãCloudflare ç»é²æžã¿ã®å€æ°ã»Secretsãçæ AI ãå
±æãããç»é¢ã¯ PR ã®ã³ãŒããšéçãã¡ã€ã«ã§åäœããããã¬ãã¥ãŒå°çšã® src/preview.ts ã¯æ€çŽ¢ã»åçã»ãã«ã¹ãã§ãã¯ã»èªèšŒæžã¿åæç¶æ³ã®åç
§ã ããèš±å¯ããåæãåé€ãWebhook 㯠403 ãè¿ããQueue ãã€ã³ãã£ã³ã°ãš Cron ãé€å€ããæ¢å Worker ã®æ€èšŒã«å¿
èŠãªããã¯ã°ã©ãŠã³ããã³ãã©ãŒã¯åŠçãå®è¡ããæåŠããããªã¢ãŒããã€ã°ã¬ãŒã·ã§ã³ã¯å®è¡ããªããæªé©çšã®ã¹ããŒã倿Žã«äŸåãã PR ã¯ãæ¬çªã¹ããŒããšã®äºææ§ãå¿
èŠã«ãªãã
æ¢åã® production GitHub Environment ã® Cloudflare Secrets ãš D1 IDãããã³ DECISIONRAG_DEPLOY_ENABLED=true ãåå©çšãããããããŒã®è€è£œã¯äžèŠãEnvironment ã®ãã©ã³ãå¶éãèšå®ããå Žåã¯ããã¬ãã¥ãŒå¯Ÿè±¡ã® refs/pull/*/merge ãèš±å¯ããå¿
èŠããããæ¬çªãžã§ãèªäœã¯åŒãç¶ãããã©ã«ããã©ã³ãã ãã§å®è¡ãããCloudflare ã®æ¢å Worker ã§ã¯ Version URLsïŒæ§ Preview URLsïŒãæå¹ã«ãããç¡å¹ãªå ŽåãURL ãååŸã§ãããžã§ãã¯å€±æããã
æ¬çªè³æºãžã®ã¢ã¯ã»ã¹ã䌎ããããfork ãš Dependabot ã® PR ã¯å¯Ÿè±¡å€ãåäžãªããžããªå ã®ä¿¡é Œãã倿Žã«äœ¿çšãããæŽæ°çŠæ¢ã¯ã¢ããªã®å ¥å£ã§ã®å¶çŽã§ãããD1 èªäœã®èªã¿åãå°çšæš©éã§ã¯ãªããæ€çŽ¢ã»åçã® API 䜿çšéãšã¬ãŒãå¶éã¯æ¬çªãšå ±æããããPR ãéããŠãçºè¡æžã¿ã® Version URL ã¯èªååé€ãããªãããã¬ãã¥ãŒçšããŒãžã§ã³ãæåã§æ¬çªã«ææ ŒãããããŒãžåŸã®éåžž CI ã«æ¬çªãããã€ãä»»ããã
CI ã®ãã€ã°ã¬ãŒã·ã§ã³ã¯ããŒã«ã« D1 ã«ã®ã¿é©çšãããæ¬çªã®ã¹ããŒã倿Žã«äŸåãã PR ã¯ã次ã®é ã§åæ ããã
Wrangler ã¯ãã¡ã€ã«åã§é©çšæžã¿ã®ãã€ã°ã¬ãŒã·ã§ã³ãèšé²ãããæ¬çªã«é©çšãããã¡ã€ã«ã¯åºå®ããä¿®æ£ã¯æ°ãããã€ã°ã¬ãŒã·ã§ã³ãšããŠè¿œå ããŠãåãæé ã§ããŒãžåã«é©çšããã
-
çŸè¡ Worker ã§ãåãäºææ§ã®ãããã€ã°ã¬ãŒã·ã§ã³ãçšæãããåã®åé€ãåå倿Žãå¿ èŠãªããæ°æ§ã¹ããŒãã«å¯Ÿå¿ã§ãã Worker ãå ã«ãããã€ããæ§ã¹ããŒããåç §ããªããªã£ãŠããåé€ããã
-
ããŒãžåã«ã察象ã®ãã€ã°ã¬ãŒã·ã§ã³ãã¡ã€ã«ãå«ãäœæ¥ããªãŒã®ã«ãŒãã§
wrangler.jsoncãwrangler.production.jsoncã«ã³ããŒãããã³ããŒã®d1_databasesã«ããDBãã€ã³ãã£ã³ã°ã®database_idããGitHub ã®productionç°å¢ã«ç»é²ããDECISIONRAG_D1_DATABASE_IDã®å€ã«çœ®ãæãããã³ããŒã¯ããŒã«ã«ã®äœæ¥çšã«äœ¿ãããã®ãã¹ãæå®ããŠæªé©çšã®ãã€ã°ã¬ãŒã·ã§ã³ã確èªããé©çšãããé©çšåŸã«æªé©çšåããªãããšãšãçŸè¡ Worker ã®/sync/statusãæ¬çª D1 ãèªã¿åããããšã確èªãããexport DECISIONRAG_PROD_CONFIG=./wrangler.production.jsonc npx wrangler d1 migrations list DB --remote --config "$DECISIONRAG_PROD_CONFIG" npx wrangler d1 migrations apply DB --remote --config "$DECISIONRAG_PROD_CONFIG" npx wrangler d1 migrations list DB --remote --config "$DECISIONRAG_PROD_CONFIG"
-
é©çšãšåäœç¢ºèªãæåããŠãã PR ãããŒãžããWorker ã®èªåãããã€ãžé²ããã©ã¡ããã倱æãããããŒãžãä¿çãããå ã«ããŒãžããå¿ èŠãããå Žåã¯ãããŒãžåã«
DECISIONRAG_DEPLOY_ENABLED=falseãèšå®ããå®è¡åŸ ã¡ã®æ¬çªãããã€ããã£ã³ã»ã«ãããè€æ°ã®ãã€ã°ã¬ãŒã·ã§ã³ã®éäžã§å€±æããå Žåãå ã«æåããåã¯é©çšæžã¿ãªã®ã§ãå詊è¡åã«æªé©çšåã確èªããã -
èªåãããã€ã忢ããŠããŒãžããå Žåã¯ããã€ã°ã¬ãŒã·ã§ã³ãšåäœç¢ºèªãæåããŠãã
DECISIONRAG_DEPLOY_ENABLED=trueã«æ»ãã倿°ã®å€æŽã ãã§ã¯ CI ã¯èµ·åããªããGitHub Actions ã®CIã§ Run workflow ãéžã³ãããã©ã«ããã©ã³ãïŒçŸåšã¯mainïŒãæå®ãããGitHub CLI ãªãgh workflow run ci.yml --ref mainã§èµ·åããã
| Method | Path | åœ¹å² |
|---|---|---|
| GET | /health |
ããã»ã¹ã®çå確èªãå€éšãµãŒãã¹çéã¯ç¢ºèªããªã |
| POST | /sync |
å šãªããžããªã®åæããã¥ãŒã«ç»é² |
| GET | /sync/status |
åæãžã§ãã倱æããœãŒã¹æ°ãæçµåæã«ãŒãœã« |
| POST | /search |
éå±€æ¢çŽ¢ã«ããæ ¹æ ã»åºå žã»Rustå€å®ãã¬ãŒã¹ |
| POST | /answer |
æ ¹æ ãæ€çŽ¢ããçæã¢ãã«ãããã°åºå žä»ãã®äž»åŒµãçæã»æ€èšŒãããã¢ãã«ããªããã°æ ¹æ ãè©äŸ¡ãã |
| POST | /admin/purge |
{"repo":"TrainLCD/Example"} ã®çŽ¢åŒãåé€ |
| POST | /webhooks/github |
GitHubã€ãã³ãåä¿¡ã眲åå¿ é |
curl "$RAG_URL/sync" -X POST -H "Authorization: Bearer $RAG_API_TOKEN"
curl "$RAG_URL/search" \
-H 'Content-Type: application/json' \
--data '{"query":"å°äžã§äœçœ®æŽæ°ãæ¢ãŸãåé¡ã«ã€ããŠãã©ããªå¯Ÿå¿ãè°è«ãããïŒ"}'/searchã»/answer ã«ã¯1ã1,500æåã® query ãšãä»»æã®çåœå€ include_feedback ãæå®ã§ãããèªèšŒãªãããŸã㯠include_feedback: false ã®å Žåã¯ãGitHubãçŸåšå
¬éãšè¿ããªããžããªã®è³æã ããæ€çŽ¢ãããinclude_feedback: true ãšæå¹ãªBearerããŒã¯ã³ãéããšãå
¬éè³æã« TrainLCD/Issues ã®ãã£ãŒãããã¯ãå ãããäºææ§ã®ãããæå¹ãªBearerããŒã¯ã³ã ããéã£ãŠ include_feedback ãçç¥ãããšãåŸæ¥ã©ããèªèšŒæžã¿ã®çŽ¢åŒå
šäœãæ€çŽ¢ãããèªèšŒãªãã®å©çšã¯IPã¢ãã¬ã¹ããšã« Cloudflare ã®ã¬ãŒãå¶éãé©çšããã
å
¬éç¯å²ã¯æ€çŽ¢ããšã« GitHub ã§å確èªããETag ã«å¯Ÿã㊠304 Not Modified ãè¿ã£ãå Žåã¯ãªããžããªäžèЧã®å¿çãåå©çšããã確èªã«å€±æããå Žåã¯æ€çŽ¢ãäžæ¢ããã
ã¬ã¹ãã³ã¹ã«ã¯ evidenceïŒåŒçšIDããœãŒã¹IDãæ¬æåºéãURLãrepoãç¶æ
çã®metadataãé¢é£åºŠïŒãhit_countïŒéžæææžã®äžã§é¢é£ãããšå€å®ããæ¬æåºéã®ç·æ°ïŒãtraceïŒã¹ããŒãžãåè£æ°ãã¢ãã«ãåŒã³åºãæ°ã䜿çšããŒã¯ã³ãæéïŒãelapsed_ms ãå«ããtimings ã«ã¯å
¬éç¯å²ã®ç¢ºèªãD1ååŸãRustå€å®ãèŠçŽçæãæ€çŽ¢å®äºãŸã§ã®æéãããªç§ã§èšé²ãããå
¬éç¯å²ã確èªããŠããD1ã®åè£ãèªã¿èŸŒããæ€çŽ¢ã¯ã«ãŒã«ã«åºã¥ãéžå¥ã§ãããæå³çãªç¶²çŸ
æ§ã¯ä¿èšŒããªããäºç®è¶
éã¯422ãšããŠè¿ãã
æ¢å®ã®çæã¢ãã«ã¯1åã®åŒã³åºãã§ã質åãžã®çŽæ¥ã®åçïŒæå€§3æïŒãç¶ããŠè³æããšã®èŠçŽãçæãããanswer ã«åçãticket_summaries ã«åºå
žIDã»æ¬æã»åŒçšIDãæã€èŠçŽãŸãã¯åæã®åŒçšãè¿ããåããã±ããã®æ¬æåºéã¯ãŸãšããçæå¯Ÿè±¡ã¯äžäœ20åºéã«éããããŒã«ã«å€å®ã¯åçã®å®å
šæ§ãèªå®ããªããããæåæãåå summarized ãè¿ããèšãæããããŒã«ã«ã§æ€èšŒã§ããªãå Žåã¯åæã®åŒçšã«æ»ããgenerate_answer ã¹ããŒãžã«ã¯ãçæã¢ãã«ãšæèŠæéããããã€ããŒãè¿ããå
¥åºåããŒã¯ã³æ°ãèšé²ããã
ãµã³ãã«Webã¢ããªã®èŠçŽã¯ã¹ããªãŒãã³ã°ã§è¡šç€ºãããPOST /answer ã« Accept: text/event-stream ãæå®ãããšãæ€çŽ¢å®äºæã® sourcesãçæéäžã® draftãåºå
žæ€èšŒåŸã® result ãSSEã§è¿ããdraft ã® answer / summaries ã¯çæéäžã®æååé
åã§ãæªæ€èšŒã®ä»®è¡šç€ºã«ã®ã¿äœ¿ããæçµ result ã¯åŸæ¥ã®JSONå¿çãšåãæ§é ã§ããã仮衚瀺ãå¿
ã眮ãæãããéäžã® error ã€ãã³ãã result ã®ãªãåæã§ã¯ä»®è¡šç€ºãç Žæ£ãããããŒãžå岿ã¯ããã®ããŒãžã®æ€çŽ¢å®äºåŸã«çæãéå§ãããAcceptããããŒãçç¥ããAPIå©çšã¯åŸæ¥ã®JSONå¿çãç¶æããã
/searchã»/answer ã« paginated: true ãæå®ãããšãpagination ã« pageãtotal_pagesãnext_cursor ãè¿ããç¶ãã¯åã queryã»include_feedbackã»èªèšŒæ¡ä»¶ãš cursor: next_cursor ãéããnext_cursor: null ãæçµããŒãžãtotal_pages ã¯è©äŸ¡åã®æ¬æåºéã20ä»¶ãã€åããããŒãžæ°ã§ãããŒãžã«ãã£ãŠé¢é£æ¬æã0ä»¶ã«ãªãããšããããhit_countãåçãèŠçŽã¯çŸåšã®ããŒãžã ãã察象ãšãããçç¥æã®APIã¯åŸæ¥ã©ããéžæææžã®å
𿬿ãè©äŸ¡ããã
ã«ãŒãœã«ã¯ API_TOKEN ãéµãšããŠæå·åã»èªèšŒããååæ€çŽ¢ãã15åã§å€±å¹ãããå
¬éãªããžããªäžèЧãååŸããæ€çŽ¢æ¡ä»¶ïŒèªèšŒãªãããŸã㯠include_feedback ãæç€ºããæ€çŽ¢ïŒã§ã¯ãç¶ç¶æã«ãGitHubã§ææ°ã®å
¬éç¯å²ã確èªãããBearerèªèšŒã§ include_feedback ãçç¥ããäºæã¢ãŒãã¯çŽ¢åŒå
šäœã察象ãšããå
¬éç¯å²ã®å€æŽãå確èªããªããååæ€çŽ¢ã®èšç»ã«ä¿åãããææžã«ã€ããŠãæ¬æã»ã¡ã¿ããŒã¿ãå
¬éç¯å²ã®å€åã§èªã¿èŸŒãŸããåºéãå€ãã£ãå Žå㯠409 search_results_changed ãè¿ããåæ€çŽ¢ãæ±ãããæ°ãã«å
¬éãããææžããååã®èšç»ã§éžæãããªãã£ãææžã®è¿œå ã»å€æŽã¯æ€åºãããããã ãã§ã¯409ãè¿ããªããäžæ£ã»æéåãã»æ€çŽ¢æ¡ä»¶äžäžèŽã®ã«ãŒãœã«ã¯ 400 invalid_search_cursorãAPI_TOKEN ã®å€æŽã§ãæ¢åã«ãŒãœã«ã¯ç¡å¹ã«ãªãã
Webã¢ããªã®ãåãžãã¯è¡šç€ºæžã¿ããŒãžãã¡ã¢ãªãã埩å ãããæ°ããæ€çŽ¢ã»æ¥ç¶è§£é€ã»åèªã¿èŸŒã¿ã§ç Žæ£ãããæ¬¡ããŒãžã§ãšã©ãŒãèµ·ããå Žåã¯åã®çµæãæ®ããå詊è¡ã§ããã
/answer ã®status:
answered: 質åã«çããæç« ãšåŒçšIDãè¿ãããsummarized: 質åã®äžéšã«ã€ããŠãè³æã§ç¢ºèªã§ããå 容ãåŒçšIDä»ãã§è¿ãããevidence_ready: æ ¹æ ã¯ååãšå€å®ããããçæã¢ãã«ã¯æªèšå®ãinsufficient_evidence: æ ¹æ äžè¶³ãåçã¯nullãconflicting_evidence: åãå¯Ÿè±¡ã»æç¹ã«ã€ããŠæ ¹æ ãççŸããåçãæ€èšŒã§ããªãã£ããåçã¯nullãverification_failed: çæçµæãæ ¹æ æ€æ»ã§åŽäžãåçã¯nullãgeneration_unavailable: æ¢å®ã®çæã¢ãã«ããå©çšã§ããèŠçŽãåŸãããªãã£ããæ€çŽ¢ã§åŸãè³æã¯è¿ãã
æ€çŽ¢äºç®è¶
éã»WASMå
¥åäžéã¯HTTP 422ãããŒã«ã«å®è¡å€±æã¯ 503 local_decision_failedãDecisionãããã€ããŒã®å®¹éäžè¶³ã»ã¯ã©ãŒã¿ã»ã¬ãŒãå¶éã¯çºçããªããå
¬éæ€çŽ¢ã®ã¬ãŒãå¶éãšæç« çæãµãŒãã¹ã®ãšã©ãŒåŠçã¯ç¶æãããSSEéå§åŸã®äŸå€ã¯ error ã€ãã³ãã«ãªããæ¢å®çæã¢ãã«ã倱æããå Žåãå©çšå¯èœãªæ ¹æ ããåŒçšãè¿ããå¥éèšå®ããå€éšçæãµãŒãã¹ã®æ¥ç¶ãšã©ãŒã¯åŸæ¥ã©ããéç¥ããã
Org WebhookãŸãã¯åãªããžããªã®Webhookãããããã€å
ã® /webhooks/github ã«èšå®ããã
- Content type:
application/json - Secret:
WEBHOOK_SECRETãšåãå€ - Events: IssuesãIssue commentsãPull requestsãPull request reviewsãPull request review commentsãPushesãRepositoriesãReleases
éè€é
ä¿¡ã¯èš±å®¹ãããåžžã«GitHubäžã®ææ°ç¶æ
ãååŸããŠupsertãããIssueåé€ã»ç§»ç®¡ããªããžããªåé€ã»ç§»ç®¡ã®ã€ãã³ãã§çŽ¢åŒãåé€ãããåæå€±æã¯æå€§5åå詊è¡ããDLQã«ç§»ãã/sync/status ã®ãšã©ãŒãšDLQãç£èŠããåå è§£æ¶åŸã«ååŠçãããåæã«ãŒãœã«ã¯ãåãžã§ãã®ç»é²å®äºãã衚ããã®ã§ãåã蟌ã¿å®äºãä¿èšŒããªãã
- æ°èŠçµ±åãã¹ãã¯å®éã®Rust/WASMãå®è¡ãããæ¢åã®éä¿¡ã»ããŒãžåå²å¥çŽãã¹ãã¯
test/legacy-judge.tsã®æ§å€å®ã¢ãã¯ãæ³šå ¥ãããæ§ã¢ãã«å°çšãã¹ãã®æåã¯ããŒã«ã«å€å®ã®ç²ŸåºŠèšŒæã§ã¯ãªãã - æ¢å®ã§éžææå 20,000ææžãéžæææžå 4,000æ¬æåºéãŸã§ãè¶ éã¯æç€ºçã«å€±æãããææžåè£ããããåäœã§è©äŸ¡ãããããéžæãããææžãå€ãã»ã©APIåŒã³åºãæ°ãå¢ããã
MAX_SCREENED_DOCUMENTSïŒæå€§100,000ïŒãSUPPORT_THRESHOLDãCONFLICT_THRESHOLDãç°å¢å€æ°ã§å€æŽå¯èœã- 1ãœãŒã¹600KBãGitHubã³ã¡ã³ãçã®ããŒãžããŒã·ã§ã³100ããŒãžãäžéãåãæšãŠãåæãšã©ãŒã«ãããGitããªãŒãtruncatedã®å Žåãåæãšã©ãŒã«ãããéåžžã«å€§ããææžçŸ€ã»ã¹ã¬ããã¯è¿œå ã®åå²åã蟌ã¿ãå¿ èŠã
- PRå·®åã³ãŒãå šäœãGitHub Wikiãæ·»ä»ç»åã»PDFã»å€éšãªã³ã¯å ãReleaseã¯åã蟌ãŸãªãã
- Webhook忢äžã«åé€ãããIssueãã¢ã¯ã»ã¹æš©ã倱ã£ããªããžããªã¯ãå·®åå·¡åã ãã§ã¯åé€ãæ€ç¥ã§ããªãã該åœãœãŒã¹ã管çè
ãåé€ããããDBãåæ§ç¯ããŠå
šä»¶åæããã
/admin/purgeåŸã§ãæ¢åã®åæãžã§ããæ¬¡åå·¡åã§åç»é²ããããããæä¹ çãªé€å€èšå®ã§ã¯ãªãã - ãžã§ããå€ãGitHubç¶æ ãååŸããçŽåŸã«æ°ãããžã§ããšç«¶åãããšã次ã®å·®åå·¡åãŸã§äžæçã«å€ãå 容ã«ãªãå Žåãããã
- ããã³ããã€ã³ãžã§ã¯ã·ã§ã³ãžã®æç€ºåé¢ãšçœ²åæ€èšŒã¯å®è£ ããããã¢ãã«ã«ãã誀å€å®ãæé€ã§ããªããèªåã§Issueã»PRãäœæãããã³ãŒããæžãæãããããæ©èœã¯ãªãã
npm run build:rust
npm run check
npm test
npx wrangler d1 migrations apply trainlcd-decision-rag --local
npx wrangler deploy --dry-run --outdir distãã¹ãã¯éå±€æ¢çŽ¢ãå ±æã³ã³ããã¹ãã§ã®é äœä»ããäºç®è¶ éãèŠçŽã®åŒçšãšççŸã®æ€èšŒãPRç¶æ ããã£ãŒãããã¯ã®éè€æé€ãææžåé€ãWebhook眲åã»orgå¢çãAPIèªèšŒãšå ¬éç¯å²ã®åæ€èšŒã確èªããã
- Wan et al., Retriever-Free Retrieval: Navigating Documents with Decision Models, 2026.
- Cloudflare Workers
- Cloudflare D1
- Cloudflare Queues
HTTPSã§éããiOSã§ã¯å ±æã¡ãã¥ãŒã®ãããŒã ç»é¢ã«è¿œå ããAndroidã»PCã§ã¯ãã©ãŠã¶ãŒã®ã€ã³ã¹ããŒã«æäœã§è¿œå ã§ããŸããæ€çŽ¢ã»èŠçŽã«ã¯éä¿¡ãå¿ èŠã§ããååãªã³ã©ã€ã³èµ·ååŸã¯ãåå€ã§ã®èµ·åæã«æ¥ç¶æ¡å ã衚瀺ããŸãã
æ°ããŒãžã§ã³ã¯èµ·åæãç»é¢ãžã®åŸ©åž°æããªã³ã©ã€ã³åŸ©åž°æã衚瀺äžã¯1æéããšã«ç¢ºèªããŸãããæŽæ°ããããæŒããç»é¢ã ããåèªã¿èŸŒã¿ããŸããå ¥åå å®¹ã»æ€çŽ¢çµæã»ã¡ã¢ãªäžã®å©çšããŒã¯æŽæ°æã«æ¶å»ãããŸããService Workerã¯ãªãã©ã€ã³æ¡å ã®HTML/CSSã®ã¿ãä¿åããAPIå¿çã»æ€çŽ¢çµæã»å©çšããŒã¯ä¿åããŸããã
public/offline.html / public/offline.css ã®å€æŽæã¯ public/sw.js ã®ãã£ãã·ã¥ããŒãžã§ã³ã倿ŽããŠãã ãããä»ã®ããã³ããšã³ã倿Žã§ãæŽæ°ãæ€ç¥ã§ãããããCIã¯ãããã€åã«å
¬éãã¡ã€ã«ã®å
容ããService Workerã®ãªããžã§ã³ãçæããŸããããŒã«ã«ãããããã€ããå Žåãnpmã®deployã¹ã¯ãªããã䜿çšããŠãã ããã
æ€çŽ¢ã»èŠçŽã®å€æŽã¯ãPRäœæåã«æ¬çªãšåãè³æã»è³ªåã§ç²ŸåºŠãšååå¿çæéã宿ž¬ããããã¹ãæåã ããåäœç¢ºèªãšããããã¬ãã¥ãŒã®å®ãã©ãŠã¶ãŒã§ã¹ããªãŒãã³ã°ã次ã»åããŒãžããšã©ãŒããã®åŸ©åž°ã確èªããæ¯èŒæ¡ä»¶ãšåãããŒããèšé²ããã倿ŽåŸã«å€å®çµæãå€ãã£ãå Žåã¯åæ€èšŒããã
è³æãä¿åãããš vocabulary ãžã§ããç»é²ããWorkers AI ã§æ¬æåºéããšã«ç¥ç§°ã»å¥åã®åè£ãæœåºãããæ€çŽ¢äžã«ã¯æœåºã¢ãã«ãåŒã°ãªããæ¢åè³æã»æªå®äºã®æœåºã¯ãªããžããªåææã® vocabulary_scan ã§è£å®ãããæœåºã«å€±æããŠãè³æã®ä¿åã¯ç¶æããéåžžã®åæãžã§ããšåãå詊è¡ã»ãšã©ãŒç£èŠã䜿ããWorkers AI ã® AI ãã€ã³ãã£ã³ã°ãå¿
èŠã§ãåççæã®å€éšãããã€ããŒèšå®ãšã¯ç¬ç«ããŠããã
åè£ã¯åæã®å®å
šäžèŽåŒçšãäž¡æ¹ã®èªãæç€ºçãªå®çŸ©åœ¢åŒïŒWayfinder (WF)ãX abbreviated as Y ãªã©ïŒãRustã§ç¢ºèªããŠèªåæ¡çšãããé¢é£èªã®å
±èµ·ãæšæž¬ãã翻蚳ãåŠå®ã»ä»®å®ãå«ãæ¬æåºéã¯æ¡çšããªãããã®ä¿å®çãªåœ¢åŒãã§ãã¯ã§ãæå³ã®æ£ããã¯ä¿èšŒããªããå
šåºéã®æœåºãå®äºããŠããæå¹ã«ããè³æã®æ¬æã»ã¿ã€ãã«å€æŽæã¯å€ã察å¿ãå³åº§ã«ç¡å¹åãããåé€ã»purgeã§ãæ ¹æ ãšäžç·ã«åé€ãããè³æIDã»URLã»æ¬æåºéçªå·ã»å
容ãªããžã§ã³ã»æ ¹æ åŒçšã»æ¡ç𿥿ãä¿åããã
åºå®èŸæžã¯ç¶æããDBã®å¯Ÿå¿ãæ€çŽ¢ã¹ã³ã¢ã«ã ã远å ãããæ€çŽ¢ããšã«çŸåšã®å
¬éç¯å²ã§èŸæžã®æ ¹æ è³æãçµã蟌ã¿ãéå
¬éè³æã察象å€ãã£ãŒãããã¯ã®èªåœãå
¬éæ€çŽ¢ãžäœ¿çšããªããå±éã¯1段ã®ã¿ã§ãæªç¥ã®èå¥åã®çŽæ¥äžèŽãç¶æããã1æ€çŽ¢ã§128çµãè¶
ããåè£ã¯422 vocabulary_expansion_budget_exceededãåçæ€èšŒã»å®è£
æžã¿ã»ãªãªãŒã¹æžã¿ã®å€å®ã«ã¯åçèŸæžãæž¡ããªããæ€çŽ¢ã«é¢ä¿ããèŸæžã®å€æŽã¯ããŒãžç¶ç¶æã«409 search_results_changedãšãªããåæ€çŽ¢ãæ±ããã
管çAPIã¯ããããBearerèªèšŒãå¿ é ã§ãPRãã¬ãã¥ãŒã§ã¯çŠæ¢ããã
| Method | Path | å 容 |
|---|---|---|
| GET | /admin/vocabulary |
æ ¹æ ä»ãã®å¯Ÿå¿äžèЧïŒå é 100ä»¶ïŒãšæœåºé²æ |
| POST | /admin/vocabulary/list |
kind: entries / blocks / auditãoffsetã§ç¶ããååŸãnext_offset: nullãæçµ |
| POST | /admin/vocabulary |
termã»aliasã»blockedã»reasonã§å¯Ÿå¿ãç¡å¹åïŒè§£é€ |
誀ã£ãçµã¿åãã㯠{"term":"WF","alias":"Wayfinder","blocked":true,"reason":"å¥ã®æå³ã ã£ã"} ã®ããã«ç¡å¹åãããçµã¿åããã¯NFKCã»å°æååã»é åºçµ±äžããŠç®¡çããåæœåºãããŠããããã¯ã¯æ®ããè§£é€ã¯åãçµã¿åããã« blocked:false ãšçç±ãæå®ããã倿Žå±¥æŽã¯auditäžèЧã§ç¢ºèªã§ãããåè£äžèЧã¯ãªãã»ããæ¹åŒãªã®ã§ãåæäžã«å
šä»¶ã確èªãããšãã¯åæçµäºåŸã«åãçŽãã
å°å
¥æã¯ 0003_search_vocabulary.sql ãæ¢åã®æ¬çªãã€ã°ã¬ãŒã·ã§ã³æé ã§é©çšããŠããããŒãžãããæ¢åWorkerãšã®äºææ§ãç¶æãã远å ã¹ããŒãã§ãããæªé©çšã®PRãã¬ãã¥ãŒã§ã¯åºå®èŸæžã ãã§æ€çŽ¢ã§ããããèªåèŸæžã®åäœç¢ºèªã«ã¯ãã€ã°ã¬ãŒã·ã§ã³æžã¿DBãå¿
èŠãã³ãŒãå°å
¥åŸã®éåžžåæã§æ¢åè³æãé æ¬¡æœåºãããååã¯æ¬æåºéããšã«çæAPI䜿çšéãçºçããã