ðºïž 00 - é¡¹ç®æŠè§ â
NOTE
æ¬ç« æ¯å ¥éšæŠè§ïŒéåææè¯»è ã读å®åå¯ä»¥æ¥çç 01-getting-started.md 宿å®è£ ã
ð€ XiaoQing å®äœ â
XiaoQing æ¯äžäžªåºäº Python åŒæ¥ïŒasyncioïŒå OneBot åè®® ç蜻é级 QQ æºåšäººæ¡æ¶ã
å®åšåœåä»åºäžåæ¶æ¿æ 䞀å±è§è²ã
- æºåšäººæ¡æ¶ïŒ
core/æäŸ OneBot æ¥å ¥ãæ¶æ¯ååãåœä»€è·¯ç±ãæä»¶çåœåšæãå€èœ®äŒè¯ãè°åºŠä»»å¡ãé 眮çé蜜ãè¿è¡ææ åé误å€çã - æåæºåšäººåºçšïŒ
plugins/æäŸå¯çŽæ¥å 蜜çåèœæä»¶ïŒèŠçæäººè倩ã䞪人æ¶éŽç®¡çã倩æå·¥å ·ãè¿çšè¿ç»Žãåéç»ç«¯æ§è¡ãCodex åå°ä»»å¡ã矀嚱ä¹ãå€éšä¿¡æ¯æååèªåšåä»»å¡ã
项ç®é»è®€éåé¿æè¿è¡åšäžªäººæºåšãæå¡åšæ NAS äžãQQ 客æ·ç«¯äŸ§ç± NapCatQQ ç OneBot å®ç°èŽèŽ£ïŒXiaoQing äžæ³šäºäºä»¶å€çãäžå¡æä»¶åååºçæã
â¡ äžåéçè§£ â
忬¡é 读æ¶å è®°äœäžç¹ïŒåé¢çé çœ®åæºç é 读äŒèœ»æŸåŸå€ã
- XiaoQing çæ žå¿æ¯
core/ïŒèŽèŽ£æ¶æ¯æ¥å ¥ãåœä»€è·¯ç±ãäŒè¯ç®¡çåè°åºŠã - 倧éšåèœåéœæ¥èª
plugins/ïŒä»¥åžŠplugin.jsonçç®åœäœäžºçæ£çæä»¶åå ã - é¡¹ç®æ¢æ¯æè倩åæä»¶ïŒä¹æ¯æå
pendoè¿ç§åžŠ Web æ§å¶å°çå€åæä»¶ã
äžå¥è¯æè¿° â
æ¥æ¶ QQ æ¶æ¯ â è§£æåœä»€ â è°çšæä»¶å€ç â è¿åååº
æ žå¿ç¹æ§ â
| ç¹æ§ | 诎æ |
|---|---|
| æä»¶å | æ¯äžªåèœç¬ç«ææä»¶ïŒå¯æåšé蜜ïŒé 眮æä»¶é»è®€èªåšçæ§ïŒæä»¶æä»¶ watcher 坿éåŒå¯ |
| åŒæ¥äŒå | åºäº asyncio å€çå¹¶åæ¶æ¯ |
| åè®®æ å | åºäº OneBot åè®®ïŒå Œå®¹å€ç§ QQ 客æ·ç«¯å®ç° |
| åŒåæ¥å£ | æäŸæä»¶ APIãæ¥å¿åè¿è¡ææ ç»è®¡ |
| Web æ§å¶å° | pendo æä»¶å 眮 FastAPI + åç JS SPAïŒæ¯ææµè§åšç®¡çäžªäººæ°æ®ãç»è®¡åè¿ç§» |
| åå°ä»»å¡ | æä»¶å¯ä»¥èªå»ºç¬ç«éåå¹¶äž»åšååæåæåŸçç»æïŒé¿ä»»å¡äžå¿ å çšæ¡æ¶å€èœ®äŒè¯ |
ð åœå项ç®èœåçåŸ â
| é¢å | æä»¶ | èœå |
|---|---|---|
| æäººè倩 | xiaoqing_chat | 倿š¡æçŸ€è/ç§èãåŸçå衚æ äžäžæãè®°å¿ãPFC è¡äžºè§åãreply checkerã衚蟟åŠä¹ |
| 䞪人管ç | pendo | æ¥çšãåŸ åãç¬è®°ãæ¥è®°ã莊æ¬ãæéãæçŽ¢ãç»è®¡ãWeb æ§å¶å°ãScriptable å°ç»ä»¶ |
| æ žå¿ç®¡ç | bot_core | /helpã/reloadã/pluginsãéé³ãé
眮管çãmetrics |
| åºç¡è倩 | smalltalk, chat, voice | ç®åé²èãCoze 对è¯å TTS |
| è¿ç»Žäžæ§è¡ | qingssh, shell, codex, jupyter, minecraft | SSHãåé shellãCodex åå°äŒè¯éåå arXiv æèŠäŒè¯ãJupyter REPLãMinecraft RCON |
| ç§ç /倩æ | apod, arxiv_filter, ads_paper, astro_tools, dict, chime | 倩æåŸã论æçéäžæèŠäŸ§è·¯ãADSã倩æè®¡ç®ãè¯å žãFRB çæµ |
| å€éšä¿¡æ¯ | github, earthquake, twitter, url_parser, signin, adnmb | Trendingãå°éãåŸçæåãéŸæ¥é¢è§ãçŸå°ãA å² |
| åš±ä¹å·¥å · | choice, guess_number, qingpet, color, wolframalpha, echo | æœå¥ãçæ°åãçŸ€å® ç©ãé¢è²ã计ç®ã瀺äŸåæŸ |
宿޿件åœä»€åé çœ®åš 09-plugins.mdã
ð¡ æ žå¿æŠå¿µ â
åç»ææ¡£äŒåå€äœ¿çšä»¥äžæ žå¿æŠå¿µã
1. OneBot åè®® â
OneBot æ¯è倩æºåšäººçæ ååè®®ãå®å®ä¹äºä»¶æ ŒåŒãAPI æ ŒåŒåéä¿¡æ¹åŒã
- äºä»¶æ ŒåŒïŒQQ æ¶æ¯åŠäœè¡šç€ºäžº JSON
- API æ ŒåŒïŒåŠäœåéæ¶æ¯ãè·åä¿¡æ¯
- éä¿¡æ¹åŒïŒHTTPãWebSocket ç
XiaoQing äžçŽæ¥è¿æ¥ QQïŒèæ¯éè¿ OneBot åè®®äž OneBot å®ç°ïŒåŠ NapCatQQãgo-cqhttpïŒéä¿¡ïŒ
QQ æå¡åš ââ OneBot å®ç° ââ XiaoQing æ¡æ¶ ââ äœ çæä»¶
(NapCatQQ) (æ¬é¡¹ç®)2. æä»¶ïŒPluginïŒ â
æä»¶æ¯ XiaoQing çåèœåå ãæ¯äžªæä»¶ïŒ
- ç¬ç«çæä»¶å€¹ïŒåŠ
plugins/echo/ïŒ - å
å«
plugin.jsonïŒé 眮ïŒåmain.pyïŒä»£ç ïŒ - ååºç¹å®åœä»€æäºä»¶
- å¯ä»¥è¢«çé蜜
plugins/
âââ echo/ # echo æä»¶
â âââ plugin.json # æä»¶é
眮
â âââ main.py # æä»¶ä»£ç
âââ guess_number/ # çæ°åæä»¶
âââ ...3. åœä»€ïŒCommandïŒ â
åœä»€æ¯çšæ·è§Šåæä»¶çæ¹åŒïŒ
/echo hello world
â â
åœä»€ åæ°åœä»€ç± plugin.json äžç triggers å®ä¹ïŒ
{
"commands": [{
"name": "echo",
"triggers": ["echo", "å€è¯»"], // è§Šåè¯
"help": "å€è¯»äœ 诎çè¯"
}]
}4. æ¶æ¯æ®µïŒSegmentïŒ â
OneBot çš"æ¶æ¯æ®µ"è¡šç€ºæ¶æ¯å 容ïŒ
# çº¯ææ¬
{"type": "text", "data": {"text": "äœ å¥œ"}}
# åŸç
{"type": "image", "data": {"file": "https://example.com/pic.jpg"}}
# ç»åæ¶æ¯
[
{"type": "text", "data": {"text": "çåŸïŒ"}},
{"type": "image", "data": {"file": "..."}}
]XiaoQing æäŸäŸ¿æ·åœæ°ïŒ
from core.plugin_base import text, image_url, segments
# çä»·äºäžé¢çç»åæ¶æ¯
return [text("çåŸïŒ"), image_url("https://example.com/pic.jpg")]
# æè
æŽç®å
return segments("äœ å¥œ") # èªåšèœ¬æ¢äžºæ¶æ¯æ®µ5. äžäžæïŒContextïŒ â
æ¯æ¬¡å€çæ¶æ¯æ¶ïŒæä»¶äŒæ¶å°äžäžª context 对象ïŒå
å«ïŒ
- æä»¶äœçšåçåªè¯»é
眮äžç§å¯ïŒäŒå
䜿çš
context.get_config()ãcontext.get_secret()ïŒ - æ¥å¿å·¥å
·ïŒ
context.loggerïŒ - HTTP 客æ·ç«¯ïŒ
context.http_sessionïŒ - äŒè¯ç®¡çïŒ
context.create_session()ïŒ - æ°æ®ç®åœïŒ
context.data_dirïŒ
ðïž ç³»ç»æ¶æç®åŸ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â XiaoQingApp (app.py) â
â åºçšå
¥å£ïŒç®¡çææç»ä»¶ â
ââââââââ¬âââââââââââââââââââââ¬âââââââââââââââââââââ¬âââââââââââââ
â â â
⌠⌠âŒ
âââââââââââââââ âââââââââââââââ âââââââââââââââââââ
â OneBot WS â â Inbound â â Scheduler â
â Client â â Server â â 宿¶ä»»å¡ â
â (äž»åšè¿æ¥) â â (è¢«åšæ¥æ¶) â âââââââââââââââââââ
ââââââââ¬âââââââ ââââââââ¬âââââââ
â â
ââââââââââ¬ââââââââââ
â æ¶æ¯äºä»¶
âŒ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Dispatcher (dispatcher.py) â
â æ¶æ¯åååšïŒè§£æãè·¯ç±ãäŒè¯ç®¡ç â
âââââââââââââââââââââââââââââ¬ââââââââââââââââââââââââââââââââââ
â
âŒ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Router (router.py) â
â åœä»€è·¯ç±ïŒå¹é
è§Šåè¯ â
âââââââââââââââââââââââââââââ¬ââââââââââââââââââââââââââââââââââ
â
âŒ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â PluginManager (plugin_manager.py) â
â æä»¶ç®¡çïŒå 蜜ãåžèœœãçé蜜 â
âââââââââââââââââââââââââââââ¬ââââââââââââââââââââââââââââââââââ
â
âŒ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Plugin (main.py) â
â äœ çæä»¶ä»£ç â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
ïŒpendo æä»¶é¢å€å
眮 FastAPI Web ServerïŒç¬ç«æäŸ HTTP æ§å¶å°æå¡ïŒcodex æä»¶ç»Žæ€èªå·±çåå°ä»»å¡éåå¹¶éè¿ OneBot äž»åšååæåååŸçç»æïŒä¹äžº arxiv_filter æäŸ `astro-ph` æèŠäŒè¯ïŒðš æ¶æ¯å€çæµçš â
äžæ¡æ¶æ¯ä»æ¶å°å°ååºïŒç»åä»¥äžæ¥éª€ïŒ
1. æ¶å°æ¶æ¯
â
âŒ
2. Dispatcher è§£æ
- æåææ¬ãuser_idãgroup_id
- 倿æ¯åŠéèŠå€çïŒç§èãåœä»€åçŒãbot_nameã@æºåšäººãå
³é矀èåç§°éå¶ææŽ»è·äŒè¯ïŒ
â
âŒ
3. æ£æ¥äŒè¯
- 掻è·äŒè¯äŒå
æ¶è޹åç»èŸå
¥ïŒå
æ¬äžå
šå±åœä»€ååæçº¯ç©ºçœçèŸå
¥
- äŒè¯å€çåšæç¡®è¿å `None` æ¶æç»§ç»åœä»€è·¯ç±
â
âŒ
4. åœä»€è·¯ç±
- Router å¹é
è§Šåè¯
- æŸå°å¯¹åºæä»¶ååœä»€
â
âŒ
5. æéæ£æ¥
- admin_only åœä»€æ£æ¥ç®¡çåæé
â
âŒ
6. æ§è¡æä»¶
- è°çš plugin.handle(command, args, event, context)
- æä»¶è¿åæ¶æ¯æ®µå衚
â
âŒ
7. åéååº
- éè¿ OneBot API åéæ¶æ¯ð ç®åœç»æ â
XiaoQing/
âââ main.py # çšåºå
¥å£
âââ requirements.txt # 项ç®äžå
眮æä»¶ççŽæ¥äŸèµ
âââ pyproject.toml # æå
ãpytestãcoverage äžéææ£æ¥é
眮
âââ scripts/ # å¯åšã绎æ€ã忥å arXiv æšçå·¥å
·
â âââ run-bot.vbs # Windows åå°å¯åšå
¥å£
â âââ run-bot-monitor.ps1 # æºåšäººçæ§åš
â âââ run_process_with_rotating_logs.py # æ¥å¿èœ®èœ¬æ§è¡åš
â âââ run_full_uat.sh # Git Bash/macOS/Linux å
šé UAT å
¥å£
â âââ run_full_uat.py # UAT é犻ãçåœåšæäžæ¥åæ§è¡åš
â âââ run_command_matrix.py # HTTP/WS åœä»€äžäžå¡åºæ¯ç©éµ
â âââ run_core_pressure.py # Core å
¥ç«èåäžæ¢å€åæµ
â âââ run_xiaoqing_chat_quality.py # çå®è倩莚ééšçŠ
â âââ sync_to_remote.sh # è¿ç«¯ rsync é¢è§/忥å
¥å£
â âââ arxiv_inference_cli.py # arXiv æšçå
¥å£
â
âââ config/ # é
眮æä»¶
â âââ config.json # åºç¡é
眮ïŒå¯æäº€å° GitïŒ
â âââ secrets.json # ææé
眮ïŒäžèŠæäº€ïŒïŒ
â
âââ core/ # æ žå¿æ¡æ¶
â âââ app.py # äž»åºçšç±»
â âââ dispatcher.py # æ¶æ¯åååš
â âââ router.py # åœä»€è·¯ç±
â âââ plugin_manager.py # æä»¶ç®¡ç
â âââ plugin_base.py # æä»¶å·¥å
·åœæ°
â âââ context.py # æä»¶äžäžæ
â âââ session.py # äŒè¯ç®¡çïŒå€èœ®å¯¹è¯ïŒ
â âââ scheduler.py # 宿¶ä»»å¡
â âââ onebot.py # OneBot éä¿¡
â âââ server.py # Inbound æå¡åš
â âââ config.py # é
眮管ç
â âââ ai.py # ç»äž AI/VLM æš¡åè·¯ç±äž fallback
â âââ plugin_execution.py # æ¯æä»¶æ§è¡ gateã忥 bulkhead äžå
¬å¹³è°åºŠ
â âââ message.py # æ¶æ¯å€çå·¥å
·
â âââ args.py # åœä»€åæ°è§£æïŒParsedArgsïŒ
â âââ metrics.py # è¿è¡ææ ç»è®¡ïŒMetricsCollectorïŒ
â âââ interfaces.py # Protocol æ¥å£å®ä¹
â âââ safe_http.py # åºç« URL SSRF 鲿€ïŒfail-closedïŒ
â âââ exceptions.py # èªå®ä¹åŒåžž
â âââ models.py # éçšæ°æ®æš¡å
â âââ clock.py # æ¶åº/æ¶éŽå·¥å
·
â âââ constants.py # å
šå±åžžé
â âââ logging_config.py # æ¥å¿é
眮
â
âââ plugins/ # æä»¶ç®åœïŒå¯çŽæ¥å 蜜çå
眮æä»¶ïŒ*_deprecated ç®åœé»è®€äžåäžå 蜜ïŒ
â âââ bot_core/ # æ žå¿åœä»€ïŒhelpãreloadïŒ
â âââ xiaoqing_chat/ # å€æš¡ææäººè倩ïŒattention gateãè®°å¿ãè§åãreply checkerïŒ
â âââ pendo/ # 䞪人æ¶éŽäžä¿¡æ¯ç®¡çäžæ¢ïŒæ¥çš/åŸ
å/ç¬è®°/æ¥è®°/莊æ¬/æé/Web æ§å¶å°ïŒ
â âââ codex/ # Codex åå°äŒè¯ãä»»å¡éåå arXiv æèŠäŒè¯
â âââ qingpet/ # QQçŸ€å® ç©å
»æç³»ç»
â âââ qingssh/ # SSH è¿çšæ§å¶
â âââ jupyter/ # Python ä»£ç æ§è¡
â âââ astro_tools/ # 倩æè®¡ç®å·¥å
·ç®±
â âââ ads_paper/ # NASA ADS 论æç®¡ç
â âââ github/ # GitHub Trending
â âââ arxiv_filter/ # arXiv 论æçéå Codex æèŠäŸ§è·¯
â âââ apod/ # æ¯æ¥å€©æåŸ
â âââ chime/ # FRB é倿Žçæµ
â âââ minecraft/ # MC æå¡åšéä¿¡
â âââ smalltalk/ # é²èæä»¶
â âââ chat/ # AI 对è¯
â âââ voice/ # è¯é³åèœ
â âââ memo_deprecated/ # å·²åçšç memo å
Œå®¹ç®åœïŒæ plugin.jsonïŒ
â âââ choice/ # éæºéæ©
â âââ wolframalpha/ # äžèœè®¡ç®åš
â âââ url_parser/ # éŸæ¥è§£æ
â âââ shell/ # ç»ç«¯åœä»€ïŒç®¡çåçœåå + è·¯åŸåœäžåïŒ
â âââ earthquake/ # å°é快讯
â âââ signin/ # èªåšçŸå°
â âââ twitter/ # Twitter åŸç
â âââ guess_number/ # çæ°åæžžæ
â âââ dict/ # 倩æåŠè¯å
ž
â âââ color/ # é¢è²æ¥è¯¢
â âââ adnmb/ # Aå²å¿åç
â âââ echo/ # åæŸç€ºäŸ
â
âââ logs/ # æ¥å¿ç®åœïŒèªåšçæïŒ
â âââ xiaoqing.log # æææ¥å¿
â âââ xiaoqing_error.log # é误æ¥å¿
â
âââ tests/ # æµè¯æä»¶
â âââ test_app_*.py # åºçšçåœåšæãæéãèœåäžä»»å¡æµè¯
â âââ test_dispatcher_*.py # æ¶æ¯è§£æãåœä»€äžäžäžææµè¯
â âââ plugins/
â âââ integration/
â âââ helpers/
â
âââ test_reports/ # å¯äžä¿ççæ¬å°å®æŽéªè¯åºçº¿äžè¯Žæ
â
âââ docs/ # ææ¡£ïŒäœ æ£åšççïŒð¯ 讟计åå â
TIP
è¿äºåå莯穿æŽäžªä»£ç åºïŒçè§£å®ä»¬æå©äºå¿«éæŸå°æ£ç¡®çæ©å±æ¹åŒã
XiaoQing ç讟计éµåŸªä»¥äžååïŒ
1. ç®åäŒå â
- æå°å¿ èŠçæœè±¡
- 代ç å³ææ¡£
- æ°æèœå¿«éäžæ
2. 纊å®äŒäºé 眮 â
- æä»¶æŸ
plugins/ç®åœ - å
¥å£æä»¶å«
main.py - é
眮æä»¶å«
plugin.json
3. åŒæ¥åç â
- ææ I/O æäœåŒæ¥æ§è¡
- 䜿çš
asyncioåaiohttp - äžé»å¡äºä»¶åŸªç¯
4. æä»¶é犻 â
- æ¯äžªæä»¶ç¬ç«ç®åœ
- ç¬ç«çæ°æ®ååš
- äºäžå¹²æ°ïŒå¯åç¬çé蜜ïŒå¯éè¿
enable_plugin_watcheråŒå¯è¿è¡æ¶ watcher èªåšçæ§
âïž äžå ¶ä»æ¡æ¶å¯¹æ¯ â
| ç¹æ§ | XiaoQing | NoneBot2 | Koishi |
|---|---|---|---|
| è¯èš | Python | Python | TypeScript |
| å€æåºŠ | ç®å | äžç | äžç |
| åŠä¹ æ²çº¿ | äœ | äž | äž |
| æä»¶çæ | å° | 倧 | 倧 |
| éååºæ¯ | 䞪人/å°å | éçš | éçš |
XiaoQing éçšåºæ¯
- æ³èŠç®åãçŽæ¥çæ¡æ¶
- å¿«éåŒå䞪人æºåšäºº
- åŠä¹ æºåšäººåŒååç
â¡ïž äžäžæ¥ â
äžäžæ¥é 读 01-getting-started.mdïŒå®æå®è£ åé 眮ã