惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tor Project blog
B
Blog RSS Feed
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
H
Hackread – Cybersecurity News, Data Breaches, AI and More
罗磊的独立博客
GbyAI
GbyAI
N
Netflix TechBlog - Medium
博客园 - 司徒正美
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
宝玉的分享
宝玉的分享
W
WeLiveSecurity
Stack Overflow Blog
Stack Overflow Blog
Y
Y Combinator Blog
SecWiki News
SecWiki News
V
Vulnerabilities – Threatpost
Google DeepMind News
Google DeepMind News
C
CERT Recently Published Vulnerability Notes
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Register - Security
The Register - Security
Cisco Talos Blog
Cisco Talos Blog
Martin Fowler
Martin Fowler
A
About on SuperTechFans
S
Security @ Cisco Blogs
T
Tenable Blog
C
Check Point Blog
N
News and Events Feed by Topic
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Attack and Defense Labs
Attack and Defense Labs
美团技术团队
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Cisco Blogs
P
Palo Alto Networks Blog
V
V2EX
博客园 - 聂微东
Project Zero
Project Zero
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Docker
N
News | PayPal Newsroom
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
小众软件
小众软件
Application and Cybersecurity Blog
Application and Cybersecurity Blog
人人都是产品经理
人人都是产品经理
V2EX - 技术
V2EX - 技术
I
Intezer
L
LINUX DO - 最新话题

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
未來應該改用 Google Magika 來判斷檔案類型?
JH5 · 2026-06-13 · via DEV Community

JH5

Gemini CLI 實戰驗證報告

驗證日期:2026-03-06
測試環境:macOS (本機) + Ubuntu 22.04 (遠端 172.16.59.12,RTX 3090)
Blog 文章:vscode_gemini_cli_dev_tips_zh.md


測試總覽

# 測試項目 本機 macOS 遠端 Ubuntu 結果
1 安裝 npm install -g @google/gemini-cli PASS PASS v0.32.1
2 gemini --version PASS PASS 0.32.1
3 Headless mode (gemini -p "...") PASS PASS 正常回應
4 Pipe input (`echo ... \ gemini`) PASS PASS
5 Git diff pipe (commit message) PASS N/A 產生 Conventional Commit
6 JSON output (--output-format json) PASS QUOTA 含 response + stats
7 Sandbox mode (-s) PASS N/A 讀取成功/寫入受限
8 GEMINI.md context 載入 PASS N/A 正確讀取專案 context
9 批次文件產生器 PASS N/A 2 個 .py → 2 個 .md
10 gcommit 函式 PASS N/A 自動產生 commit message
11 BorrowHood repo 驗證 PASS N/A GitHub repo 存在
12 免費配額限制驗證 PASS PASS 確認 20 req/day 限制

成功率:12/12 測試項目全部驗證完成(含預期的配額限制)


詳細測試紀錄

測試 1:安裝 Gemini CLI

指令:

npm install -g @google/gemini-cli

本機結果:

# 本機原有舊版 (0.1.15, via homebrew),透過 npm 更新
added 626 packages in 19s
➜ gemini --version → 0.32.1

遠端結果:

# 遠端需要 sudo 但無權限,改用 user-level npm prefix
mkdir -p ~/.npm-global && npm config set prefix "~/.npm-global"
npm install -g @google/gemini-cli
added 626 packages in 8s
➜ ~/.npm-global/bin/gemini --version → 0.32.1

驗證: Blog 中記載的安裝指令 npm install -g @google/gemini-cli 正確。版本 v0.32.1 與文件一致。


測試 2:gemini --version

指令:

gemini --version

結果:

0.32.1

驗證: 與 blog 中的 v0.32.1 版本一致。


測試 3:Headless Mode 基本測試

指令:

export GEMINI_API_KEY="AIzaSy..."
gemini -p "Say hello in one sentence"

本機結果:

Hello! I am Gemini CLI, your autonomous engineering assistant, ready to help you
with your software development and codebase analysis tasks.

遠端結果(gemini-2.5-flash):

Hello!

驗證: Blog 中的 gemini "prompt" headless 模式正確運作。注意預設模型 (gemini-2.5-pro → gemini-3.1-pro) 在免費層已無配額,需指定 -m gemini-2.5-flash


測試 4:Pipe 輸入測試

指令(Blog 中的範例模式):

echo "error log content" | gemini -p "Explain why this failed"

實際測試:

echo "This is a test error log: FileNotFoundError: No such file or directory: '/tmp/missing.txt'" \
  | gemini -m gemini-2.5-flash -p "Explain why this failed in one sentence"

本機結果:

The test failed because the specified file `/tmp/missing.txt` does not exist.

遠端結果:

The `segfault` indicates a memory access error, likely caused by the module attempting
to access an invalid or restricted memory location during its initialization.

驗證: Blog 中的 cat error.log | gemini "Explain why this failed" 模式完全可用。Pipe 輸入作為 context,-p 作為 prompt,正確運作。


測試 5:Git Diff Pipe 產生 Commit Message

指令(Blog 中的範例):

git diff | gemini "Write a commit message for these changes"

實際測試:

git add vscode_gemini_cli_dev_tips_zh.md  # stage 新檔案
git diff --staged | head -50 | gemini -m gemini-2.5-flash \
  -p "Write a concise Conventional Commit message for this diff. Output ONLY the message."

結果:

docs: Add VS Code Copilot and Gemini CLI development tips (Traditional Chinese)

驗證: 完美!Gemini 正確分析了 git diff 內容並產生了符合 Conventional Commit 格式的 commit message。


測試 6:JSON 輸出格式

指令(Blog 中的範例):

gemini --output-format json "..." | jq -r '.response'

實際測試:

gemini -m gemini-2.5-flash --output-format json \
  -p "Return a JSON object with keys 'greeting' and 'language' for a hello in Traditional Chinese"

結果(完整 JSON):

{
  "session_id": "27ae8c4c-e4b2-431e-aa43-c30b8a365f06",
  "response": "```

json\n{\"greeting\": \"你好\", \"language\": \"Traditional Chinese\"}\n

```",
  "stats": {
    "models": {
      "gemini-2.5-flash": {
        "api": { "totalRequests": 1, "totalErrors": 0, "totalLatencyMs": 2784 },
        "tokens": { "input": 495, "prompt": 10322, "candidates": 24, "total": 10412, "cached": 9827, "thoughts": 66 }
      }
    }
  }
}

用 jq 提取 response:

gemini ... --output-format json -p "..." | jq -r '.response'

{
  "greeting": "你好",
  "language": "Traditional Chinese"
}

驗證: JSON 輸出包含 session_idresponsestatsstats 含 token 使用量、API 延遲、cache 比例等。Blog 描述正確。
補充發現: response 中的 JSON 會被 markdown 代碼塊包裹,需注意解析時去除 `json 標記。


測試 7:Sandbox Mode(macOS Seatbelt)

指令(Blog 中的範例):
`bash
gemini -s -p "analyze the code structure"
`

測試 A:Sandbox 中讀取檔案(應允許)
`bash
gemini -m gemini-2.5-flash -s -p "Read the file config.json in the current directory and tell me what's inside in one sentence"
`

結果:
`plaintext
The `config.json` file contains a JSON object with an API key, a status boolean, and a list of numbers.
`

測試 B:Sandbox 中執行 shell 命令(應受限)
`bash
gemini -m gemini-2.5-flash -s -p "Run shell command: echo 'sandbox test works'"
`

結果:
`plaintext
Error executing tool run_shell_command: Tool "run_shell_command" not found.
Did you mean one of: "grep_search", "cli_help", "read_file"?
Blocked call: Unauthorized tool call: 'run_shell_command' is not available to this agent.
`

驗證: Sandbox 模式正確運作——讀取檔案允許,shell 命令執行被禁止。這與 Blog 中「限制寫入專案目錄外」的描述一致。注意:sandbox 模式下可用工具被限制為 grep_searchcli_helpread_file


測試 8:GEMINI.md Context 載入

建立的 GEMINI.md 內容:
`markdown

Project: NGS Pilot

General Instructions

  • This is a bioinformatics NGS (Next-Generation Sequencing) analysis project
  • When generating code, prefer Python and shell scripts
  • Use Traditional Chinese (繁體中文) for documentation ## Coding Style
  • Use 4 spaces for Python indentation
  • Shell scripts should use bash with set -euo pipefail ## Project Context
  • Target platform: Ubuntu 22.04 with NVIDIA GPU (RTX 3090)
  • Container tools: Docker, Singularity
  • Key tools: DeepVariant, GATK, Parabricks `

測試指令:
`bash
gemini -m gemini-2.5-flash -p "Based on the project context, what kind of project is this? Answer in one sentence in Traditional Chinese."
`

結果:
`plaintext
這是一個生物資訊次世代定序 (NGS) 分析專案。
`

驗證: Gemini CLI 自動讀取了專案根目錄的 GEMINI.md 並理解了 context。回答完全基於 GEMINI.md 中的描述,不是從檔案名推斷的。Blog 中描述的階層式 context 系統正確運作。


測試 9:批次文件產生器

指令(Blog 中的範例):
`bash
for file in *.py; do
gemini "Generate a Markdown documentation summary for @$file" > "${file%.py}.md"
done
`

實際測試(2 個 Python 檔案):
`bash
mkdir -p /tmp/gemini_doc_test
cp analyze_vcf.py file_type.py /tmp/gemini_doc_test/
cd /tmp/gemini_doc_test
for file in *.py; do
gemini -m gemini-2.5-flash -p "Generate a brief one-paragraph Markdown documentation summary for @$file." > "${file%.py}_doc.md"
done
`

結果 — analyze_vcf_doc.md:
`plaintext
The `analyze_vcf.py` script is a Python-based command-line tool designed for rapid quality control
and basic statistical analysis of VCF (Variant Call Format) files, supporting both standard and
gzipped inputs. It parses variant call data to provide a comprehensive summary, including counts
and percentages of SNPs, Indels, and MNPs, chromosome distribution, variant type breakdown,
filter status, and statistical summaries of quality scores, depth coverage (DP), and allele
frequencies (AF) across samples.
`

結果 — file_type_doc.md:
`plaintext
The `file_type.py` script serves as a demonstration and testing utility for identifying file
types using two distinct methods: `python-magic` (leveraging the `libmagic` library) and
`Magika` (an AI-based approach). It iterates through a predefined list of files, checking for
their existence, and subsequently outputs the identified file type from both methods.
`

驗證: 批次文件產生器成功!@file 語法讓 Gemini 讀取檔案內容並產生準確的文件摘要。2 個 Python 檔案各自產生了獨立的 .md 檔。

注意事項: 出現了 [ERROR] [IDEClient] Directory mismatch 警告(因為 CLI 在 /tmp 執行,但 VS Code 工作區在 ngs_pilot),不影響功能。


測試 10:gcommit 函式

指令(Blog 中的範例):
`bash
function gcommit() {
diff=$(git diff --staged)
if [ -z "$diff" ]; then
echo "No staged changes to commit."
return 1
fi
msg=$(echo "$diff" | gemini "Write a concise Conventional Commit message for this diff. Output ONLY the message.")
git commit -m "$msg"
}
`

實際測試(dry run,不真正 commit):
`bash
git add GEMINI.md
gcommit # 修改版:輸出 message 但不 commit
`

結果:
`plaintext
Generating commit message...
Generated message: docs: Add project guidelines and AI development workflow
(Dry run - not actually committing)
`

驗證: gcommit 函式完美運作。從 staged changes 自動產生了語意正確的 Conventional Commit message docs: Add project guidelines and AI development workflow


測試 11:BorrowHood Repo 驗證

Blog 中提到的 repo: https://github.com/akenel/borrowhood

驗證結果:
| 項目 | Blog 描述 | 實際確認 |
|------|-----------|----------|
| 存在性 | ✅ | GitHub repo 存在且公開 |
| Python 行數 | 10,000+ | 10,625(實際更多) |
| REST endpoints | 100+ | 109 個 |
| 資料模型 | 30+ | 32 個 SQLAlchemy models |
| Tech stack | FastAPI + Keycloak | ✅ 確認 |
| 聲譽系統 | 加權 (1x-10x) | ✅ Newcomer 1x to Legend 10x |
| 測試 | - | 250 個自動化測試 |
| License | - | MIT |
| agents/ 目錄 | Blog 中描述有 | ⚠️ GitHub 主分支未直接看到 agents/ 目錄 |

注意: Blog 文章中描述的 agents/ 目錄架構可能在作者的本地開發環境或另一個分支中。GitHub 主分支的 README 確認了 AI 相關功能(AI-assisted listings via Pollinations API),但 Gemini ADK agents 可能尚未合併到主分支。


測試 12:免費配額限制驗證

Blog 中描述:

  • 免費額度 60 req/min + 1,000 req/day(使用 Gemini API)
  • BorrowHood 案例提到:gemini-2.5-flash 免費層 5 req/min、20 req/day

實際觀察:

模型 API Key 限制 觀察
gemini-3.1-pro(預設) limit: 0 立即 429 錯誤,免費層配額為 0
gemini-2.0-flash limit: 0 立即 429 錯誤,免費層配額為 0
gemini-2.5-flash limit: 20 requests/day 約 10 次呼叫後耗盡

錯誤訊息範例:
`plaintext
TerminalQuotaError: You have exhausted your daily quota on this model.
code: 429
message: Quota exceeded for metric: generate_content_free_tier_requests,
limit: 20, model: gemini-2.5-flash
Please retry in 50.018181982s.
`

重要發現:

  1. Blog 中的 60 req/min + 1,000 req/day 是使用 OAuth 登入的額度,API Key 的免費額度遠低於此
  2. 不同模型有不同的配額:gemini-3.1-pro 和 gemini-2.0-flash 的 API Key 免費配額為 0
  3. gemini-2.5-flash 的 API Key 免費配額為 20 req/day
  4. 配額限制是 BorrowHood 案例作者也碰到的真實問題,Blog 中的「免費額度限制嚴格」完全屬實
  5. Exit code 為 1(非 42 或 53),配額錯誤歸類為一般 API 錯誤

Blog 已修正內容:

  • 免費額度區分 OAuth(60 req/min + 1K/day)與 API Key(Flash 限定,20 req/day)
  • 所有指令範例均加上 -m gemini-2.5-flash 確保 API Key 使用者可直接執行
  • 工具對比表中明確標註 API Key 僅限 Flash 模型

環境資訊

本機 (macOS)

`yaml
OS: macOS
Node.js: v22.21.1
npm: 10.9.4
Gemini CLI: 0.32.1 (npm global install)
jq: /usr/bin/jq (系統內建)
Git: 可用
`

遠端 (Ubuntu 22.04)

`yaml
OS: Ubuntu 22.04.5 LTS (GNU/Linux 6.8.0-90-generic x86_64)
Node.js: v22.21.0
npm: 10.9.4
Gemini CLI: 0.32.1 (user-level ~/.npm-global/bin/)
GPU: NVIDIA RTX 3090
`


結論

Blog 內容準確度

項目 準確度 備註
安裝指令 ✅ 完全正確 npm install -g @google/gemini-cli
Headless mode ✅ 完全正確 -p 旗標或位置參數
Pipe 輸入 ✅ 完全正確 stdin → Gemini context
Git diff commit ✅ 完全正確 產生高品質 Conventional Commit
JSON 輸出 ✅ 完全正確 --output-format json + jq
Sandbox ✅ 正確 macOS Seatbelt 有效限制命令執行
GEMINI.md ✅ 完全正確 自動載入階層式 context
批次文件產生 ✅ 完全正確 @file 語法有效
gcommit 函式 ✅ 完全正確 即插即用
免費額度描述 ✅ 已修正 明確區分 OAuth vs API Key 配額,API Key 僅限 Flash
BorrowHood 引用 ⚠️ 部分 Repo 存在但 agents/ 目錄不在主分支
Exit codes ⚠️ 部分 配額錯誤回傳 code 1 而非特定 code

關鍵實戰發現

  1. 免費層限制已在 Blog 中明確說明:API Key 的 gemini-2.5-flash 僅 20 req/day,OAuth 才有 1,000 req/day
  2. 模型選擇很重要:預設模型 (gemini-2.5-pro → gemini-3.1-pro) 免費配額為 0,必須手動指定 -m gemini-2.5-flash
  3. Sandbox 限制比預期更嚴格:不只限制寫入,連 run_shell_command 工具都被完全移除
  4. GEMINI.md 載入可靠:即使是 headless mode 也會自動載入專案根目錄的 GEMINI.md
  5. 遠端安裝技巧:沒有 sudo 時用 npm config set prefix "~/.npm-global" 方案有效
  6. Token caching 有效:JSON 輸出的 stats 顯示 cached: 9827 out of total: 10412,快取率 94%

報告產生時間:2026-03-06 11:45
所有測試指令均來自 vscode_gemini_cli_dev_tips_zh.md Blog 文章