:構建無盡冬日科技研究規(guī)劃助手)
如果你是 SLG 玩家大概率經歷過《無盡冬日》里這種選擇困難科技研究隊列排不下到底是先點資源產出還是先提速建造前置科技沒解鎖辛辛苦苦囤的資源又不能亂花。與其靠感覺硬點科技樹不如直接用 AI 做一個“無盡冬日科技研究規(guī)劃助手”。這期我們看的是一個偏實戰(zhàn)的 AI 應用開發(fā)項目以清源AI 作為開發(fā)平臺從零搭建一個能根據玩家當前科技進度、資源存量和階段目標自動輸出科技研究路線規(guī)劃的工具。項目本身不是用來做自動點擊、自動操作這類違規(guī)腳本的而是把“科技樹數據 玩家目標 AI 推理”結合起來生成可參考的研究優(yōu)先級建議和分階段執(zhí)行計劃。先給結論如果你有 Python 或 Node.js 基礎熟悉基本的接口調用跟著這篇文章可以完整跑通一個“AI 開發(fā) 游戲資料整理 批量規(guī)劃”的小型應用。沒有現成的清源AI 平臺賬號也可以用其他兼容大模型 API 的平臺替換核心邏輯是一樣的。1. 開發(fā)目標與核心能力速覽能力項說明項目類型AI 應用開發(fā)實戰(zhàn)屬于信息整理與策略推薦類工具開發(fā)平臺以清源AI 為例需要按其官方文檔接入模型服務和鑒權核心功能科技樹數據管理、玩家目標分析、研究路線推薦、分階段計劃生成輸入內容當前已解鎖科技、可用資源、研究目標、時間預算輸出內容科技研究優(yōu)先級列表、分階段規(guī)劃、資源缺口提示支持批量任務可以批量生成多個賬號/多個目標的規(guī)劃方案前端方式可選先用命令行或 Streamlit 做簡單看板API 能力后端提供 HTTP 接口便于接入 Web 或移動端運行門檻普通開發(fā)機即可模型調用走遠程 API不需要高端顯卡適合人群想學習 AI Agent 開發(fā)、想做一個游戲資料查詢/規(guī)劃工具的人這套架構本質上是一個典型的“大模型 API 結構化數據 業(yè)務邏輯”應用。你不需要訓練模型也不需要部署大模型重點是把科技樹數據整理成模型能理解的結構再用 Prompt 控制它輸出穩(wěn)定、可執(zhí)行的規(guī)劃結果。2. 需求拆解無盡冬日科技研究到底要解決什么問題《無盡冬日》這類 SLG 游戲的科技系統通常有多個研發(fā)方向比如城市發(fā)展、資源產出、軍事作戰(zhàn)、首領成長等。每個科技項一般包含等級上限、前置科技、研究時間、資源消耗、生效效果。玩家的核心訴求是在有限的時間和資源里選擇當前收益最高的研究路線。這里要明確一點清源AI 并不能直接讀取你游戲里的實時數據也不應該去抓取游戲的非公開接口。它的價值在于“基于已知的科技樹規(guī)則”做路線規(guī)劃和優(yōu)先級分析。所以我們把需求拆成三個模塊。2.1 科技樹數據結構化第一步是把游戲內的科技項整理成結構化數據??萍柬椫g有關聯關系比如“前置科技 A 到達 5 級后才能研發(fā) B”。如果這一層數據是散的AI 推薦時就會出現“推薦了一個根本還沒解鎖的科技”的尷尬結果。2.2 目標與約束匹配玩家目標可以是“前期快速開荒”“中期提升采集效率”“偏向 PVP 打架”等。不同目標對應的科技優(yōu)先級差異很大。約束條件包括當前已研究科技、可用資源量、時間預算、研究隊列數量。2.3 AI 規(guī)劃生成清源AI 在這里承擔的是“策略推理 自然語言輸出”的能力。它根據結構化的科技樹和玩家狀態(tài)輸出一個帶有優(yōu)先級排序的研究計劃并解釋為什么這樣推薦。一句話總結清源AI 負責智力部分我們負責把數據喂給它再把結果包裝成可用的工具。3. 科技樹數據建模規(guī)劃類 AI 應用最容易翻車的地方是數據結構設計得不夠清晰。模型不是人類它不會自動理解“城市發(fā)展”這個字符串的含義。建議先把科技樹整理成 JSON 結構。下面是一份示例數據模型字段可以按你的項目需要調整{ tech_id: city_development_building_1, name: 基礎建設, branch: city_development, max_level: 10, prerequisites: [], cost_per_level: { wood: [500, 800, 1200, 1800, 2600], coal: [0, 0, 200, 400, 800] }, duration_per_level: [ 00:30:00, 01:00:00, 02:00:00, 04:00:00, 08:00:00 ], effects: [ { type: build_speed_up, value_per_level: 0.02 } ] }字段說明tech_id唯一標識用于程序處理。branch所屬科技分支分組篩選時用。prerequisites前置科技列表每一項可以寫成基礎建設:5表示該科技到 5 級。cost_per_level每一級消耗的資源。這里用數組表示每一級的消耗量。duration_per_level每一級研究時長。effects該科技帶來的效果方便 AI 判斷收益。實際開發(fā)時這個 JSON 文件會有點大。建議拆成多個文件按分支存放然后通過一個加載腳本合并。import json import pathlib DATA_DIR pathlib.Path(./data/tech_trees) def load_all_techs(): techs [] for path in DATA_DIR.glob(*.json): with open(path, r, encodingutf-8) as f: techs.extend(json.load(f)) return techs tech_list load_all_techs() print(f已加載科技項數量: {len(tech_list)})這里有一個坑如果你從網上找科技樹資料不能直接用來做結構化數據必須逐項核對是否是最新版本。游戲版本更新后科技數值和前置條件可能變化。穩(wěn)妥的做法是保留一份data_version字段。4. Prompt 設計方案Prompt 是這個 AI 規(guī)劃工具的核心。同樣的清源AI 模型Prompt 寫得好不好輸出質量差距非常大。設計思路是先給模型設定角色再給它具體的科技樹數據最后要求它按照固定格式輸出規(guī)劃結果。SYSTEM_PROMPT 你是一名《無盡冬日》科技研究規(guī)劃助手。 你的任務是根據玩家當前的科技進度、資源存量和階段目標推薦合理的科技研究方向。 規(guī)則 1. 只能推薦本次提供的科技列表中的科技。 2. 必須考慮前置科技是否滿足。 3. 必須結合玩家目標和資源約束。 4. 輸出使用 Markdown 列表包含優(yōu)先級、科技名稱、目標等級、研究預估時長、理由。 5. 如果玩家資源不足需要給出資源缺口提示。 6. 如果玩家目標信息不明確先讓玩家補充目標不要直接給出推薦。 USER_PROMPT_TEMPLATE 玩家當前科技進度{current_tech} 玩家可用資源{resources} 玩家階段目標{goal} 玩家可投入時間{time_budget} 科技樹數據 {tech_tree_data} 這里有幾個細節(jié)需要注意。第一{tech_tree_data}不能把整個 JSON 塞進去會超過上下文長度。建議只傳入相關分支的科技項或者壓縮字段只保留名稱、等級上限、前置、時間和主要消耗。第二輸出格式一定要固定。如果模型偶爾不聽話可以在代碼里做一次解析校驗解析失敗就自動重試一次。第三清源AI 如果支持 agent 模式你可以把“查詢科技樹”“計算資源缺口”“生成規(guī)劃”拆成多個工具函數讓模型自主調用。這樣比一次性大 Prompt 更穩(wěn)定。5. 開發(fā)環(huán)境準備開始寫代碼之前先把環(huán)境準備干凈。下面是通用檢查清單。5.1 基礎軟件Python 3.10 或更高版本。Node.js 18 或更高版本如果前端用。Git用于代碼管理。一個支持 Markdown 的編輯器VS Code 或任意習慣的編輯器均可。python --version node -v npm -v git --version5.2 Python 依賴根據實際使用情況安裝。pip install fastapi uvicorn pydantic requests python-dotenv如果前端使用 Streamlit再裝pip install streamlit5.3 環(huán)境變量清源AI 的 API Key 不要硬編碼在代碼里。用環(huán)境變量或.env文件管理。# .env 示例實際值要自己申請和配置 QINGYUAN_API_KEYyour_api_key_here QINGYUAN_BASE_URLhttps://your_qingyuan_api_endpoint QINGYUAN_MODELyour_model_name然后在代碼里加載import os from dotenv import load_dotenv load_dotenv() API_KEY os.getenv(QINGYUAN_API_KEY) BASE_URL os.getenv(QINGYUAN_BASE_URL) MODEL os.getenv(QINGYUAN_MODEL)這里要特別說明不同平臺的接口地址、模型名稱、鑒權方式可能不一樣。上面的字段是通用命名實際開發(fā)時一定要以你所使用的清源AI 平臺的官方文檔為準不要照搬。5.4 初始化項目目錄qingyuan-endless-winter/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI 入口 │ ├── planner.py # 規(guī)劃邏輯 │ ├── llm_client.py # 清源AI 接口封裝 │ └── schemas.py # 請求和響應模型 ├── data/ │ ├── tech_trees/ # 科技樹 JSON 文件 │ └── player_states/ # 玩家狀態(tài)示例 ├── scripts/ │ └── batch_plan.py # 批量規(guī)劃腳本 ├── .env └── requirements.txt目錄結構不用完全照抄但“數據文件、業(yè)務邏輯、接口封裝”三層分離是必要的后期維護會輕松很多。6. 后端服務搭建核心規(guī)劃接口后端采用 FastAPI主要是因為接口定義簡單、自帶文檔頁面適合快速開發(fā)。6.1 請求和響應數據結構from pydantic import BaseModel, Field from typing import List, Dict, Optional class PlanRequest(BaseModel): goal: str Field(..., description玩家階段目標例如前期開荒) current_tech: Dict[str, int] Field( default_factorydict, description當前科技等級格式{基礎建設: 5} ) resources: Dict[str, int] Field( default_factorydict, description可用資源格式{wood: 10000, coal: 5000} ) time_budget_hours: int Field(24, description可投入研究時間單位小時) branch: Optional[str] Field(None, description限定科技分支) class PlanAction(BaseModel): priority: int Field(..., description優(yōu)先級1 最高) tech_name: str target_level: int estimated_time: str reason: str class PlanResponse(BaseModel): status: str plan: List[PlanAction] resource_gaps: Dict[str, int] {} raw_text: str 6.2 接口實現from fastapi import FastAPI from .planner import generate_plan from .schemas import PlanRequest, PlanResponse app FastAPI(title無盡冬日科技研究規(guī)劃助手) app.post(/api/tech/plan, response_modelPlanResponse) def create_plan(request: PlanRequest): result generate_plan(request) return result重點是generate_plan的邏輯準備科技樹數據組裝 Prompt調用清源AI 模型接口再解析輸出。from .llm_client import chat_with_qingyuan from .schemas import PlanRequest, PlanResponse def generate_plan(request: PlanRequest): tech_tree_data load_tech_tree_by_branch(request.branch) user_prompt USER_PROMPT_TEMPLATE.format( current_techrequest.current_tech, resourcesrequest.resources, goalrequest.goal, time_budgetrequest.time_budget_hours, tech_tree_datatech_tree_data ) raw_text chat_with_qingyuan(SYSTEM_PROMPT, user_prompt) actions parse_plan_output(raw_text) resource_gaps compute_resource_gaps(request, actions) return PlanResponse( statusok, planactions, resource_gapsresource_gaps, raw_textraw_text )parse_plan_output是工作量比較大的地方。模型輸出 Markdown 列表時需要正則或字符串解析把它轉成結構化對象。如果你的 Prompt 控制得足夠穩(wěn)定可以用 JSON 輸出模式讓模型直接返回 JSON 數組。7. 清源AI 接口調用封裝清源AI 的接入方式要嚴格按官方文檔來。這里給一個通用的大模型 HTTP 調用模板接口路徑和參數需要替換為實際平臺支持的格式。import requests import os class QingyuanClient: def __init__(self): self.api_key os.getenv(QINGYUAN_API_KEY) self.base_url os.getenv(QINGYUAN_BASE_URL) self.model os.getenv(QINGYUAN_MODEL) def chat(self, system_prompt: str, user_prompt: str) - str: url f{self.base_url}/chat/completions headers { Authorization: fBearer {self.api_key}, Content-Type: application/json } payload { model: self.model, messages: [ {role: system, content: system_prompt}, {role: user, content: user_prompt} ], temperature: 0.3 } response requests.post(url, headersheaders, jsonpayload, timeout120) response.raise_for_status() data response.json() return data[choices][0][message][content]幾點經驗temperature設置為 0.3 左右讓輸出更穩(wěn)定。規(guī)劃類任務不需要太多創(chuàng)造性。超時時間不要設置太短長文本生成經常要 30 秒以上。建議 120 秒。如果平臺支持流式輸出也可以在長任務中開啟流式提升用戶體驗。接口調用失敗時要做好重試。網絡抖動很常見。import time def chat_with_retry(client, system_prompt, user_prompt, retries3): for attempt in range(retries): try: return client.chat(system_prompt, user_prompt) except Exception as e: if attempt retries - 1: raise e time.sleep(2 * (attempt 1))8. 前端看板把推薦結果可視化命令行能跑通之后可以加一個簡單的 Web 界面。這里推薦 Streamlit寫起來最快不需要復雜的前端工程。import streamlit as st from app.planner import generate_plan from app.schemas import PlanRequest st.set_page_config(page_title無盡冬日科技研究助手, page_icon) st.title(無盡冬日科技研究規(guī)劃) goal st.text_input(階段目標, value前期開荒優(yōu)先資源產出) time_budget st.number_input(可投入時間小時, min_value1, value24) current_tech_text st.text_area( 當前科技等級, value基礎建設:5, 資源采集:3 ) resources_text st.text_area( 可用資源, value木材:50000, 煤礦:20000 ) if st.button(生成研究規(guī)劃): current_tech {} for item in current_tech_text.split(,): if : in item: name, level item.split(:) current_tech[name.strip()] int(level.strip()) resources {} for item in resources_text.split(,): if : in item: name, amount item.split(:) resources[name.strip()] int(amount.strip()) request PlanRequest( goalgoal, current_techcurrent_tech, resourcesresources, time_budget_hoursint(time_budget) ) result generate_plan(request) st.markdown(result.raw_text)啟動方式streamlit run webapp.pyStreamlit 會在本地開一個端口瀏覽器訪問頁面即可。這個界面只適合個人使用如果要發(fā)布給其他玩家還是建議用 FastAPI 提供接口再做單獨的前端工程。這里也提一下如果你有精力可以把前后端工程化前端用 Vue 或 React玩過前端開發(fā)的人可以順手接上。后端增加用戶體系保存多個玩家的科技進度。設計一個任務隊列把批量規(guī)劃任務異步化。9. 批量任務多賬號、多目標同時規(guī)劃批量任務是這個項目比較實用的功能。比如你有多個游戲區(qū)服的存檔或者想一次性對比“開荒路線”“資源流路線”“戰(zhàn)斗流路線”可以用腳本批量生成。import json import csv from app.planner import generate_plan from app.schemas import PlanRequest def build_batch_requests(): return [ PlanRequest( goal前期開荒優(yōu)先采集和建造速度, current_tech{基礎建設: 3, 資源采集: 1}, resources{wood: 30000, coal: 10000}, time_budget_hours24 ), PlanRequest( goal中期資源流提升采集效率和倉庫容量, current_tech{基礎建設: 7, 資源采集: 5}, resources{wood: 80000, coal: 40000}, time_budget_hours48 ), PlanRequest( goal后期戰(zhàn)斗優(yōu)先兵種屬性和出征加成, current_tech{基礎建設: 10, 軍事科技: 6}, resources{wood: 200000, coal: 150000}, time_budget_hours72 ) ] def run_batch(): requests build_batch_requests() results [] for index, request in enumerate(requests, start1): print(f正在生成第 {index}/{len(requests)} 個規(guī)劃...) result generate_plan(request) results.append({ index: index, goal: request.goal, status: result.status, plan: [action.dict() for action in result.plan] }) with open(batch_results.json, w, encodingutf-8) as f: json.dump(results, f, ensure_asciiFalse, indent2) print(批量任務完成結果已保存到 batch_results.json) if __name__ __main__: run_batch()批量任務的核心是不要讓單個失敗中斷整個流程。項目規(guī)模大了以后建議把run_batch改成異步任務隊列后端慢慢消費。每一條任務記錄單獨狀態(tài)比如pending、running、success、failed。失敗的任務自動重試重試次數限制在 2 到 3 次。輸出結果按任務 ID 分開保存不要全部塞到一個數組里。import time def run_batch_with_retry(requests, max_retries2): results [] for index, request in enumerate(requests, start1): for attempt in range(max_retries 1): try: result generate_plan(request) results.append({index: index, success: True, data: result}) break except Exception as e: if attempt max_retries: results.append({index: index, success: False, error: str(e)}) else: time.sleep(3) return results10. 資源占用與性能觀察這個項目不涉及本地大模型推理所以沒有顯存壓力也不需要高端顯卡。主要性能開銷在網絡請求和處理時間上。需要關注三個點。10.1 模型接口響應耗時一次規(guī)劃請求的耗時要看你用的模型復雜度和輸入長度??萍紭鋽祿眉舻迷骄嗧憫娇臁H绻看握埱蠖家?60 秒以上檢查是否傳入了太多無用的上下文。10.2 請求并發(fā)與速率限制清源AI 平臺一般會對 API 調用頻率有限制。批量任務如果一次性發(fā)幾十個請求很容易觸發(fā)頻控。建議在批量腳本里加一個time.sleep(1)或使用信號量控制并發(fā)數。import threading import time semaphore threading.Semaphore(3) def limited_request(request): with semaphore: result generate_plan(request) time.sleep(1) return result10.3 進程與端口管理FastAPI 默認端口是 8000Streamlit 默認端口是 8501。如果端口被占用啟動時會報錯。Windows 和 Linux 上分別可以用下面的命令排查。# Windows netstat -ano | findstr :8000 # Linux/macOS lsof -i :8000確認占用后要么換端口要么殺掉占用進程。uvicorn app.main:app --host 127.0.0.1 --port 800111. 功能測試與效果驗證開發(fā)完成后不要急著寫一堆花哨功能先把核心鏈路跑通再逐步加場景。11.1 最小可用測試先測一個最簡單的場景沒有前置科技資源充足目標是“提升建造速度”。測試條件目標前期開荒優(yōu)先提升建造速度 當前科技基礎建設 3 級 資源木材 100000煤礦 50000 時間預算24 小時判斷標準返回結果是否給出 3 到 5 個推薦科技項。每個推薦項是否前置條件滿足。輸出格式是否可解析成結構化 JSON 或 Markdown 列表。研究時長和資源消耗是否在玩家約束范圍內。11.2 邊界測試邊界測試比正常測試更重要。測試場景預期結果失敗排查方向玩家未填寫目標提示補充目標不給推薦Prompt 約束是否生效資源嚴重不足生成計劃同時給出資源缺口資源計算邏輯是否正確前置科技未解鎖推薦里不應該出現該科技科技樹數據是否加載完整科技樹 JSON 為空返回友好報錯不崩潰數據目錄是否存在重復調用接口返回結果穩(wěn)定不出現亂碼模型參數是否固定批量任務中途失敗單條失敗不阻斷后續(xù)是否有重試機制11.3 輸出質量評估AI 規(guī)劃的輸出質量不能只看一次結果。同一個輸入多跑幾次看結果是否穩(wěn)定。不穩(wěn)定的話優(yōu)先調整temperature或者給 Prompt 增加更明確的“必須輸出 JSON 數組”的約束。{ plan: [ { priority: 1, tech_name: 基礎建設, target_level: 6, estimated_time: 04:00:00, reason: 提升建造速度縮短后續(xù)建筑升級時間 } ] }這里建議加一層解析校驗如果模型返回的不是 JSON就嘗試提取 Markdown 列表如果兩種都失敗就返回錯誤碼讓調用方知道是解析失敗而不是規(guī)劃失敗。12. 常見問題與排查方法實際開發(fā)中最容易踩的坑不在 AI 本身而在數據、解析和接口層。問題現象可能原因排查方式解決方案返回結果包含不存在的科技科技樹數據未加載或版本過期檢查 JSON 數據加載路徑更新科技樹數據文件推薦了前置條件不滿足的科技前置關系未寫進 Prompt檢查prerequisites字段把前置條件拼進 Prompt輸出格式不是 JSON 也不是 Markdown模型輸出不穩(wěn)定查看原始返回文本降低 temperature增加重試解析接口報 401 或 403API Key 配置錯誤檢查.env和請求頭重新配置環(huán)境變量請求超時輸入上下文過長或模型響應慢查看模型日志和請求耗時裁剪科技樹數據加長超時時間批量任務卡住單條請求未設置超時檢查網絡和接口日志給請求加超時和重試啟動時端口被占用本地已有服務占用端口用netstat或lsof查看換端口啟動中文內容亂碼編碼問題檢查控制臺編碼和文件編碼統一使用 UTF-8排查的時候先看日志再看請求參數最后看模型返回原文。很多問題不是模型不夠強而是前端把參數傳錯了。另外如果你在開發(fā)過程中發(fā)現某個科技數值和游戲實際不一致直接改數據文件即可不需要改代碼。13. 最佳實踐與合規(guī)提示13.1 工程化建議第一科技樹數據要有版本標記。每次游戲版本更新后對照官方公告核對這些數值。數據是規(guī)劃工具的地基地基錯了AI 推薦得再好也沒用。第二Prompt 模板和業(yè)務代碼分離。把 Prompt 放到單獨的配置文件里后續(xù)調優(yōu)不用改代碼。# prompt_config.py PROMPTS { system: ..., user_template: ... }第三設置合理的temperature和max_tokens。規(guī)劃類任務建議temperature: 0.3max_tokens根據輸出長度設置避免生成到一半截斷。第四接口服務要限制訪問范圍。如果后端部署在服務器上只監(jiān)聽127.0.0.1或者加一層簡單的 API Key 校驗不要暴露到公網裸奔。13.2 合規(guī)與版權提示這個項目本質是“基于已知游戲資料做策略分析”必須注意幾點不要制作任何自動登錄、自動點擊、模擬操作類的腳本這類工具違反游戲用戶協議且有封號風險。不要抓取游戲的非公開接口數據只使用公開可查的科技樹資料。科技樹文案和數值如果來自其他作者的整理帖要注意版權最好自己重新整理或標明來源。AI 生成的規(guī)劃建議僅供參考最終是否采納由玩家自己判斷。不要用這個項目批量注冊、批量操控游戲賬號。簡單來說清源AI 在這里是一個“策略分析師”不是“外掛執(zhí)行器”。開發(fā)過程中保持這個邊界項目才安全。14. 總結與下一步清源AI 開發(fā)教程落到“無盡冬日科技研究”這個場景本質上是一次典型的 AI 應用開發(fā)全流程需求拆解、數據建模、Prompt 設計、后端接口、前端展示、批量任務、效果評測。跑通這個項目后你可以把同一套架構復用到其他游戲攻略、文檔問答、個性化推薦等場景。最值得先驗證的功能是“科技路線規(guī)劃接口”。先準備好一份科技樹 JSON再寫好 Prompt最后用 FastAPI 接口接收游戲目標并返回規(guī)劃列表。只要這條路通了后面的批量任務和前端看板都只是包裝層。最容易踩的坑有兩個一是科技樹數據不完整導致 AI 推薦錯科技二是模型輸出格式不穩(wěn)定導致下游解析失敗。前者靠數據結構化解決后者靠 Prompt 約束和解析重試解決。后續(xù)可以繼續(xù)擴展的方向包括接入更多游戲數據源、增加玩家歷史研究記錄分析、把規(guī)劃結果導出成圖片或 PDF、支持多語言輸出、甚至做成一個公開的攻略查詢服務。建議先把最小可用版本跑通再逐步加功能。代碼不難難點在于數據整理和 Prompt 調優(yōu)。如果你正準備入門 AI Agent 開發(fā)這個項目是一個很好的練手題目。