Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

145 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GuardGo

Một trợ lý du lịch cho du khách nước ngoài tại Việt Nam.

Dự án dự thi Vietnam AI Innovation Challenge 2026

Xây dựng trong 48 giờ bởi nhóm AIlaToi.

Một du khách vừa bị báo giá 400.000đ cho cuốc taxi đáng lẽ chỉ 200.000đ. Họ không nói được tiếng Việt, không biết giá thật là bao nhiêu, không biết gọi ai, và người tài xế vẫn đang đứng đợi. GuardGo được xây dựng cho đúng khoảnh khắc đó.


Vấn đề

Chuyện chặt chém du khách ở Việt Nam hiếm khi là lừa đảo trắng trợn. Vấn đề nằm ở chỗ không có cách nào để kiểm chứng:

  • Không biết bát phở này lẽ ra giá bao nhiêu
  • Không đọc được thực đơn viết tay
  • Không biết cuốc xe vừa rồi tính đúng hay sai
  • Không có câu tiếng Việt nào để phản hồi lại
  • Không biết gọi số nào khi mọi chuyện đi quá xa

Mỗi khoảng trống đó là một tính năng trong ứng dụng này.


Cách hoạt động

Đề bài đặt ra ba yêu cầu: kiểm tra giá tức thì, nhận diện chiêu lừa từ lời kể, và hỗ trợ khẩn cấp kèm phiên dịch hai chiều — cho một trợ lý đa ngữ phục vụ trước tiên khách Hàn, Trung, Anh và Nga. Dưới đây là cách GuardGo giải quyết từng phần.

1 — Kiểm tra giá công bằng, ngay tại chỗ

Du khách chụp ảnh hoá đơn, thực đơn, bảng giá hoặc đồng hồ taxi. Mô hình thị giác trích xuất từng dòng món kèm giá, ánh xạ vào bộ từ vựng món ăn đã chuẩn hoá, rồi so sánh với dải giá tham chiếu của chính khu vực đó.

Kết quả không phải một lời phán "đắt" hay "rẻ", mà là một con số cụ thể: bạn trả 90.000đ, mức giá thường thấy quanh đây là 35.000–50.000đ. Có con số thì mới có căn cứ để trao đổi lại với người bán.

Cái khó không phải là phát hiện giá cao — mà là không báo động nhầm. Một ứng dụng báo "bị chặt chém" ở một quán làm ăn tử tế sẽ khiến du khách mất lòng tin vào cả những người bán trung thực, đúng như đề bài đã cảnh báo. GuardGo xử lý điều này bằng ba lớp:

Phân loại hạng quán dựa trên tín hiệu KHÔNG liên quan đến giá. Một bát phở 120.000đ là bất thường ở quán vỉa hè nhưng lại bình thường trong nhà hàng khách sạn. Mô hình thị giác chỉ mô tả những gì nhìn thấy được — hoá đơn viết tay hay in nhiệt có mã số thuế, thực đơn viết phấn hay đóng quyển, có điều hoà không, có chỗ ngồi trong nhà không — và một hàm chấm điểm cố định sẽ quy ra hạng quán. Mô hình không bao giờ được thấy giá khi phán đoán hạng quán, nên không thể suy ngược kiểu "đắt thì chắc là quán sang".

Lùi dần theo phạm vi khu vực, và giảm độ tự tin khi lùi. Hệ thống tìm dữ liệu ở ô khoảng 150m trước; không đủ thì mở rộng ra ô lớn hơn, rồi đến quận, rồi đến thành phố. Càng phải lùi xa thì kết luận càng dè dặt — và chỉ hai mức gần nhất mới được phép báo đỏ.

Phải đủ năm điều kiện cùng lúc mới báo đỏ. Đủ cỡ mẫu hiệu dụng, dữ liệu chưa quá cũ, phạm vi đủ hẹp, giá vượt ngưỡng phân vị 90 ít nhất 30%, và độ lệch chuẩn hoá đủ lớn. Thiếu một điều kiện thì hạ xuống mức vàng hoặc "chưa đủ dữ liệu". Với món ăn lạ ngoài từ điển, hệ thống vẫn ước lượng theo nhóm món tương tự nhưng bị chặn trần ở mức vàng — không bao giờ đủ chắc chắn để báo đỏ.

Nói ngắn gọn: hệ thống được thiết kế để thà bỏ sót còn hơn vu oan.

2 — Nhận diện chiêu lừa từ lời kể

Du khách bấm nút và kể lại sự việc bằng ngôn ngữ của họ — hoặc gõ chữ, nếu không tiện nói. Whisper chuyển giọng nói thành văn bản, mô hình ngôn ngữ đối chiếu với 25 kiểu lừa đảo đã được biên soạn sẵn, và trả về đúng một kiểu khớp nhất, hoặc "không khớp kiểu nào".

Điểm mấu chốt trong thiết kế: hệ thống lựa chọn, chứ không tự sáng tác. Mọi lời khuyên đều do con người viết trước và lưu trong kho mẫu — mô hình chỉ làm nhiệm vụ chọn ra mẫu phù hợp nhất. Để một mô hình tự nghĩ ra cách xử lý cho một người đang bị gây áp lực ngoài đường là rủi ro mà ứng dụng này không chấp nhận.

Mỗi kiểu lừa khớp được sẽ trả về ba thứ:

  • Một câu hỏi để phân biệt — loại trừ trường hợp trông giống nhưng khác bản chất
  • Các bước xử lý cụ thể, ưu tiên xuống thang căng thẳng trước
  • Một câu tiếng Việt để chìa ra, đọc to lên được ngay mà không cần biết tiếng Việt

Câu tiếng Việt đó là phần quan trọng nhất. Du khách không cần học tiếng Việt — họ chỉ cần đưa điện thoại ra.

Khi không khớp mẫu nào, ứng dụng nói thẳng là không khớp, và nói rõ điều đó không đồng nghĩa với việc bạn đang an toàn. Một công cụ dò lừa đảo tuyệt đối không được vô tình khiến người dùng nghĩ "chắc mình ổn rồi".

3 — Hỗ trợ khẩn cấp và phiên dịch hai chiều

Tab SOS có mặt ở mọi màn hình. Ba việc, xếp theo mức độ cần kíp:

Gọi ngay. Số Công an (113) và Cấp cứu (115) là nút lớn nhất trên màn hình, chữ to, bấm được kể cả khi tay đang run. Số được hardcode để vẫn gọi được ngay cả khi mạng, backend và hệ thống định tuyến đều gặp sự cố. Ngoài ra, hệ thống còn tự động định tuyến đến đường dây nóng du lịch của đúng khu vực nơi người dùng đang đứng.

Statement Mode. Một câu tiếng Việt hiện toàn màn hình và tự đọc to, lặp lại sau mỗi 3 giây — vì người đang chìa điện thoại ra cho người khác đọc thì không thể vừa làm vậy vừa bấm nút phát lại.

Phiên dịch hai chiều. Đặt điện thoại xuống bàn, giữa hai người. Màn hình chia đôi, nửa bên kia xoay ngược 180° để hướng về phía người đối diện. Mỗi lượt nói: ghi âm → nhận dạng giọng nói → dịch → đọc to bằng ngôn ngữ của người nghe. Bản chép lời hiện ra trước bản dịch, vì máy có thể nghe nhầm, và dịch một câu đã nghe nhầm là cách nhanh nhất để nói ra một điều vô nghĩa giữa lúc căng thẳng.

SOS còn liệt kê bệnh viện và đồn công an gần nhất tính từ vị trí thật, sắp xếp theo khoảng cách, luôn kèm nút chỉ đường.

Bài toán dữ liệu — thu thập, ước lượng, cập nhật

Đề bài nói đúng: dữ liệu giá tham chiếu và các mẫu lừa đảo ở Việt Nam gần như chưa được số hoá. GuardGo giải quyết bằng bốn nguồn dữ liệu, mỗi nguồn có một kỷ luật cập nhật riêng:

Loại dữ liệu Cách có được Cách giữ cho luôn mới
Dải giá món ăn Khai thác từ diễn đàn, hội nhóm du lịch, đối chiếu chéo Trọng số giảm dần theo thời gian — dữ liệu cũ tự mất hiệu lực, khu vực nào lâu không có dữ liệu mới sẽ ngừng báo động thay vì báo sai
Biểu giá taxi Lấy trực tiếp từ bảng giá do hãng công bố Script cào lại định kỳ; mỗi file đều ghi rõ ngày lấy dữ liệu và nhắc cập nhật trước khi dùng
Mẫu lừa đảo Biên soạn thủ công từ báo chí và phản ánh thực tế của du khách Thêm một file YAML là có ngay mẫu mới, không cần sửa code
Địa điểm, giá vé Khảo sát trực tiếp, đối chiếu với nguồn chính thức Mỗi mục mang cờ verified; nếu chưa xác minh thì hiện cảnh báo ngay trên màn hình

Và quan trọng nhất: dữ liệu tự lớn lên cùng người dùng. Mỗi lần kiểm tra giá cho kết quả đỏ, hoặc mỗi lần khớp trúng một kiểu lừa, hệ thống ghi lại đúng một dòng: loại sự việc, ô khu vực, thời điểm. Không lưu người dùng, không thiết bị, không toạ độ. Chính những dòng dữ liệu đó dựng nên bản đồ cảnh báo mà những du khách sau nhìn thấy — càng nhiều người dùng thì bản đồ càng chính xác.

Quyền riêng tư

Toạ độ GPS được làm mờ ngay trên máy thành một ô rộng khoảng 150m trước khi rời khỏi điện thoại. Máy chủ từ chối mọi toạ độ chính xác hơn mức đó ngay ở lớp kiểm tra dữ liệu — vị trí thật không thể tới được hệ thống, kể cả khi có lỗi lập trình.

Ảnh chụp và bản ghi âm chỉ tồn tại trong thời gian xử lý một yêu cầu, không ghi ra đĩa, không lưu vào cơ sở dữ liệu. Lịch sử trò chuyện với trợ lý không được lưu ở phía máy chủ — dữ liệu nằm trên máy người dùng, và xoá ứng dụng là mất luôn.

Không có tài khoản, không có hồ sơ người dùng, không có gì để rò rỉ.


GuardGo làm được gì

Ứng dụng là một PWA tối ưu cho điện thoại, chia làm 5 tab.

Map — Quanh bạn

Bản đồ MapLibre với các địa điểm được khảo sát thực tế tại Hà Nội, Đà Nẵng và TP. Hồ Chí Minh — giá vé theo từng hạng, giờ mở/đóng cửa, ảnh chụp, cảnh báo, và ước tính cước taxi từ vị trí hiện tại của bạn đến địa điểm đó.

Có lớp phủ "Khu vực được báo cáo" — một bản đồ nguy hiểm được dựng hoàn toàn từ chính các lần kiểm tra giá của người dùng. Mỗi báo cáo chỉ gồm (loại, ô khu vực, thời điểm) — không người dùng, không thiết bị, không toạ độ.

Bản đồ ghi rõ Quần đảo Hoàng SaQuần đảo Trường Sa là lãnh thổ Việt Nam, cùng với Biển Đông. Hầu hết các nền bản đồ khác hoặc bỏ qua hai quần đảo này, hoặc né tránh tên gọi. Trên một ứng dụng làm cho Việt Nam, sự im lặng đó không hề trung lập — vì vậy chúng tôi tự vẽ lớp nhãn của riêng mình.

Assistant — Trợ lý

Chat — hỏi bất cứ điều gì về việc đi lại an toàn ở Việt Nam. Trợ lý nắm toàn bộ dữ liệu của ứng dụng — các kiểu lừa đảo, địa điểm kèm giá và giờ mở cửa, các lưu ý theo từng thành phố — nên trả lời bằng số liệu thật, và khi không biết thì nói thẳng là không biết rồi hướng người dùng sang công cụ phù hợp.

Kiểm tra thủ công — ba công cụ dành cho từng câu hỏi cụ thể:

Công cụ Việc nó làm
Check a price Chụp thực đơn / hoá đơn / bảng giá / đồng hồ taxi → mô hình thị giác đọc ra từng món → so sánh với dữ liệu giá của khu vực
Scam check Kể lại chuyện đang xảy ra bằng ngôn ngữ của bạn → đối chiếu với các kiểu lừa đã biết → đưa ra các bước xử lý cùng một câu tiếng Việt để chìa ra cho người kia
Fare check Nhập hãng xe, quãng đường, số tiền bị thu → dựng lại số tiền đúng theo biểu giá công bố của hãng

Talk — Bộ đàm phiên dịch

Đặt điện thoại giữa hai người. Màn hình chia đôi, nửa bên kia xoay ngược 180° để hướng về phía người đối diện. Mỗi lượt: ghi âm → nhận dạng giọng nói → dịch → đọc to. Bản chép lời hiện ra trước bản dịch, vì việc nhận dạng có thể nghe nhầm, và dịch một câu đã nghe nhầm là cách để nói ra một điều vô nghĩa.

Money — Quy đổi tiền tệ

Quy đổi VNĐ sang tiền tệ của bạn theo tỷ giá trung bình thị trường, kèm theo ngày cập nhật của bảng tỷ giá — vì tỷ giá trôi mỗi ngày, và trình bày một con số cũ như thể nó còn mới là một kiểu nói dối.

SOS — Khẩn cấp

Ba việc, xếp theo mức độ cần kíp:

  1. Gọi ngay — Công an (113) và Cấp cứu (115), nút lớn, chữ to, hardcode để vẫn bấm được khi mạng, backend và hệ thống định tuyến đều gặp sự cố
  2. Statement Mode — một câu tiếng Việt hiện toàn màn hình, tự đọc to, lặp lại sau mỗi 3 giây, vì người đang chìa điện thoại ra không thể vừa làm vậy vừa bấm nút phát lại
  3. Nearest help — bệnh viện và đồn công an gần nhất tính từ vị trí thật, sắp xếp theo khoảng cách, luôn kèm nút chỉ đường

Kiến trúc

┌──────────────┐   /api/*   ┌──────────────┐        ┌──────────────┐
│  frontend    │──────────► │   backend    │──────► │   tts-api    │
│  React 19    │   cùng     │   FastAPI    │        │  OmniVoice   │
│  + nginx     │  origin    │              │        │  (GPU)       │
└──────────────┘            └──────┬───────┘        └──────────────┘
                                   │
                            ┌──────▼───────┐   ┌────────────────────┐
                            │  PostgreSQL  │   │  FPT AI Marketplace│
                            └──────────────┘   │  VLM · LLM · STT   │
                                               └────────────────────┘

nginx vừa phục vụ PWA, vừa proxy /api sang backend, nên trình duyệt chỉ nói chuyện với một origin duy nhất — không có CORS, và cùng một image chạy được trên localhost, IP mạng LAN lẫn domain thật mà không cần build lại.

Mô hình sử dụng

Việc Mô hình Chạy ở đâu
Đọc ảnh thực đơn / hoá đơn Qwen2.5-VL-7B-Instruct FPT AI Marketplace
Dịch · phân loại lừa đảo · chat Qwen3.6-27B FPT AI Marketplace
Nhận dạng giọng nói whisper-large-v3-turbo FPT AI Marketplace
Tổng hợp giọng nói đa ngữ k2-fsa/OmniVoice Tự host trên GPU

Công nghệ sử dụng

Frontend — React 19, Vite, Tailwind, MapLibre GL, h3-js, PWA, hỗ trợ 5 ngôn ngữ (Việt · Anh · Hàn · Trung · Nga) dùng chung một bộ khoá dịch được đồng bộ giữa cả 5.

Backend — FastAPI, Pydantic v2 (extra="forbid"), SQLAlchemy 2, PostgreSQL, đánh chỉ mục vị trí bằng H3. 21 endpoint.


Chạy dự án

cp backend/.env.example backend/.env     # điền GUARDGO_LLM_API_KEY + POSTGRES_PASSWORD
docker compose up                        # → http://localhost:8080

docker compose --profile seed run --rm seed   # chạy một lần, khi DB còn trống

Chi tiết xem tại DOCKER.md.

Compose đọc trực tiếp từ backend/.env — một file cấu hình duy nhất cho cả dự án. Chỉ frontend mở cổng ra ngoài; backendtts-api chỉ tồn tại trong mạng nội bộ của Docker.


Kiểm thử

cd backend  && pytest -q      # bộ test backend
cd frontend && npm test       # bộ test frontend

Bộ test locale kiểm tra cả 5 ngôn ngữ có cùng một tập khoá, không có giá trị rỗng, và giữ nguyên các tham số nội suy — một bản dịch âm thầm đánh rơi {pct} sẽ tạo ra một câu bị lỗi, và không ai nhận ra cho đến lúc demo.


Nguồn dữ liệu

Nguồn Nội dung
Khảo sát trực tiếp của nhóm Giá vé, giờ mở cửa, giá món ăn của các địa điểm
OpenStreetMap (ODbL) Toạ độ bệnh viện và đồn công an
Nomira Tài liệu tham khảo về các mẫu lừa đảo (có trích dẫn nguồn, qua MCP API của họ)
ECB · Ngân hàng Trung ương Nga Tỷ giá trung bình thị trường
VinaSun · Mai Linh Biểu giá taxi công bố
Báo cáo thực tế của du khách Dữ liệu bản đồ nguy hiểm

Tỷ giá và biểu giá taxi trôi theo từng ngày — cần cập nhật lại trước mỗi buổi demo. Mỗi file dữ liệu đều ghi rõ điều này trong phần ghi chú của nó.


Trạng thái hiện tại

Được xây dựng trong một hackathon 48 giờ. Những gì đã kiểm chứng thì chạy thật, và những gì chưa thì được nói ra một cách thẳng thắn:

  • Đã kiểm chứng: toàn bộ endpoint đã được thử nghiệm trực tiếp với backend thật
  • Đã kiểm chứng: có bộ test tự động bao phủ cả backend và frontend
  • Còn thiếu: /parse chưa từng được thử với ảnh thực đơn Việt Nam thật — đây là khoảng trống kiểm thử lớn nhất còn lại
  • Còn thiếu: địa điểm và ghi chú theo thành phố hiện mới phủ Hà Nội, Đà Nẵng và TP. Hồ Chí Minh, trong khi định tuyến khẩn cấp đã phủ một phạm vi thành phố rộng hơn

Vietnam AI Innovation Challenge 2026

About

Travel assistant for foreign visitors in Vietnam: price checks, scam detection, translation, SOS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages