Để sử dụng TradingAgents theo cách thiết thực và nhanh nhất, bạn nên chạy nó như một gói Python, đóng gói nó trong một dịch vụ FastAPI nhỏ, sau đó kiểm thử dịch vụ đó trong Apidog. Điều đó mang lại cho bạn một quy trình làm việc lặp lại để kích hoạt phân tích, thăm dò kết quả, ghi lại hợp đồng yêu cầu và chia sẻ thiết lập với nhóm của bạn. ## Giới thiệu TradingAgents dễ dàng được ngưỡng mộ từ bên ngoài. Kho lưu trữ GitHub hiển thị một quy trình làm việc giao dịch đa tác nhân, một CLI được trau chuốt, hỗ trợ nhiều nhà cung cấp mô hình và một bài báo nghiên cứu giải thích thiết kế khuôn khổ. Phần khó hơn bắt đầu khi bạn cố gắng sử dụng nó trong một quy trình làm việc kỹ thuật thực tế. Hầu hết các nhóm không muốn một kho lưu trữ mà chỉ một nhà phát triển có thể chạy cục bộ. Họ muốn một cách lặp lại để kích hoạt phân tích, truyền vào một mã chứng khoán và ngày, trả về một ID công việc, kiểm tra kết quả sau này và chuyển quy trình làm việc đó cho các đồng đội frontend, QA hoặc nền tảng mà không biến mọi câu hỏi thành một phiên gỡ lỗi Python. Và bởi vì bất kỳ hệ thống nghiên cứu giao dịch nào cuối cùng cũng sẽ được sử dụng để đưa ra các quyết định về tiền thật, nên việc đóng gói TradingAgents trong một API được kiểm soát, có tài liệu còn quan trọng hơn là để nó như một tập lệnh dùng một lần trên máy tính xách tay của ai đó. Apidog phù hợp một cách tự nhiên vào quy trình làm việc này. Bạn có thể nhập lược đồ OpenAPI từ FastAPI, lưu các môi trường cho việc triển khai cục bộ và từ xa, trích xuất biến từ phản hồi, xâu chuỗi các yêu cầu thăm dò vào một kịch bản và xuất bản tài liệu cho phần còn lại của nhóm bạn. Tải xuống Apidog miễn phí để làm theo. button
## TradingAgents là gì và không phải là gì Trước khi bạn bắt đầu viết mã, việc định nghĩa công cụ một cách chính xác sẽ hữu ích. TradingAgents là một khung giao dịch đa tác nhân mã nguồn mở. Kho lưu trữ mô tả một tập hợp các vai trò chuyên biệt phản ánh cấu trúc của một công ty giao dịch: * Các nhà phân tích cho các yếu tố cơ bản, tâm lý, tin tức và tín hiệu kỹ thuật * Các nhà nghiên cứu tăng giá và giảm giá để tranh luận * Một tác nhân giao dịch * Các vai trò quản lý rủi ro * Một nhà quản lý danh mục đầu tư cho quyết định cuối cùng Kho lưu trữ cũng nêu rõ rằng khung được xây dựng bằng LangGraph và hỗ trợ nhiều nhà cung cấp mô hình, bao gồm OpenAI, Google, Anthropic, xAI, OpenRouter và Ollama. Trong cấu hình mặc định công khai, dự án hiện sử dụng các giá trị như: * `llm_provider = "openai"` * `deep_think_llm = "gpt-5.2"` * `quick_think_llm = "gpt-5-mini"` * `backend_url = "https://api.openai.com/v1"` * `max_debate_rounds = 1` Điều đó quan trọng vì nó cho bạn biết bạn đang thực sự làm việc với cái gì: một khung Python có thể cấu hình, không phải là một API SaaS có sẵn. Kho lưu trữ cũng cẩn thận về phạm vi. TradingAgents được trình bày như một khung nghiên cứu, không phải lời khuyên tài chính. Nếu bạn sử dụng nó nội bộ hoặc xây dựng phần mềm xung quanh nó, hãy giữ nguyên cách trình bày đó trong tài liệu và trải nghiệm người dùng của bạn. ## Bước 1: Cài đặt TradingAgents Bắt đầu với việc thiết lập từ chính kho lưu trữ: ```bash git clone https://github.com/TauricResearch/TradingAgents.git cd TradingAgents conda create -n tradingagents python=3.13 conda activate tradingagents pip install . ``` Nếu bạn cũng muốn xây dựng trình bao API từ hướng dẫn này, hãy thêm FastAPI và Uvicorn: ```bash pip install fastapi uvicorn ``` Kho lưu trữ TradingAgents cũng bao gồm một `.env.example` với các biến nhà cung cấp như: ```bash OPENAI_API_KEY= GOOGLE_API_KEY= ANTHROPIC_API_KEY= XAI_API_KEY= OPENROUTER_API_KEY= ``` Tùy thuộc vào lựa chọn mô hình và dữ liệu của bạn, bạn cũng có thể cần các thông tin đăng nhập của nhà cung cấp khác, chẳng hạn như Alpha Vantage. Hai quy tắc thực tế quan trọng ở đây: 1. Giữ thông tin đăng nhập trong biến môi trường hoặc trình quản lý bí mật. 2. Không truyền bí mật của nhà cung cấp qua phần nội dung yêu cầu API công khai của bạn sau này. Sự tách biệt đó sẽ làm cho môi trường Apidog của bạn sạch hơn và mô hình bảo mật của bạn an toàn hơn nhiều. ## Bước 2: Chạy TradingAgents trong Python trước tiên Trước khi bạn xây dựng bất kỳ trình bao API nào, hãy chứng minh rằng khung cốt lõi chạy trong môi trường của bạn. README hiển thị một mẫu sử dụng Python tối thiểu: ```python from tradingagents.graph.trading_graph import TradingAgentsGraph from tradingagents.default_config import DEFAULT_CONFIG ta = TradingAgentsGraph(debug=True, config=DEFAULT_CONFIG.copy()) _, decision = ta.propagate("NVDA", "2026-01-15") print(decision) ``` Đây là điểm kiểm tra đầu tiên đúng đắn vì nó trả lời câu hỏi duy nhất quan trọng ngay từ đầu: máy của bạn, thiết lập mô hình và các phụ thuộc có thực sự có thể thực thi một lần chạy TradingAgents không? Nếu điều đó hoạt động, thì bạn có thể chuyển sang cấu hình được kiểm soát. Kho lưu trữ cũng cho thấy bạn có thể ghi đè cấu hình mặc định: ```python from tradingagents.graph.trading_graph import TradingAgentsGraph from tradingagents.default_config import DEFAULT_CONFIG config = DEFAULT_CONFIG.copy() config["llm_provider"] = "openai" config["deep_think_llm"] = "gpt-5.2" config["quick_think_llm"] = "gpt-5-mini" config["max_debate_rounds"] = 2 ta = TradingAgentsGraph(debug=True, config=config) _, decision = ta.propagate("NVDA", "2026-01-15") print(decision) ``` Ví dụ thứ hai đó quan trọng hơn vẻ ngoài của nó. Nó cho bạn biết các tham số nào đáng để hiển thị trong một API sau này: * `ticker` * `analysis_date` * `llm_provider` * `deep_think_llm` * `quick_think_llm` * độ sâu nghiên cứu hoặc số vòng tranh luận Nếu bạn bỏ qua giai đoạn Python cục bộ này và chuyển thẳng sang HTTP, bạn sẽ làm cho việc gỡ lỗi khó khăn hơn mức cần thiết. ## Bước 3: Quyết định cách bạn muốn sử dụng TradingAgents Tại thời điểm này, bạn có ba cách phổ biến để sử dụng khung. ### Tùy chọn 1: Chỉ CLI Kho lưu trữ bao gồm một CLI tương tác nơi bạn có thể chọn mã chứng khoán, ngày, nhà cung cấp và độ sâu nghiên cứu. Đây là một cách tốt để khám phá dự án một cách nhanh chóng. Sử dụng điều này khi: * bạn đang học công cụ * bạn đang chạy các thí nghiệm solo * bạn không cần một hợp đồng ổn định cho ứng dụng khác Đừng dừng lại ở đây nếu bước tiếp theo của bạn là một giao diện người dùng, công cụ quản trị, dịch vụ chia sẻ hoặc quy trình làm việc QA. ### Tùy chọn 2: Chỉ Python Gọi trực tiếp `TradingAgentsGraph` từ Python tốt hơn CLI khi bạn cần điều phối tùy chỉnh hoặc các tập lệnh cục bộ. Sử dụng điều này khi: * bạn muốn sổ ghi chép hoặc tự động hóa cục bộ * bạn cần kiểm soát bằng lập trình * một nhà phát triển sở hữu quy trình làm việc từ đầu đến cuối Điều này vẫn còn thiếu sót khi nhiều nhóm cần sử dụng quy trình làm việc. ### Tùy chọn 3: Trình bao API cộng với Apidog Đây là thiết lập nhóm hữu ích nhất. Bạn giữ TradingAgents làm công cụ thực thi, hiển thị nó thông qua một dịch vụ FastAPI nhỏ và sử dụng Apidog để kiểm tra và ghi lại hợp đồng. Sử dụng điều này khi: * một giao diện người dùng cần kích hoạt phân tích * QA cần một luồng yêu cầu lặp lại * bạn muốn môi trường, khẳng định và tài liệu ở một nơi * quy trình làm việc có thể chạy đủ lâu để thăm dò có ý nghĩa hơn là một yêu cầu đồng bộ Đối với hầu hết các nhóm, đây là điểm mà "cách sử dụng TradingAgents" trở thành một câu trả lời triển khai thực tế thay vì chỉ là một bản demo cục bộ. ## Bước 4: Đóng gói TradingAgents trong một dịch vụ FastAPI Mô hình sạch nhất cho một trình bao đầu tiên là một API dựa trên công việc. Tại sao dựa trên công việc? Bởi vì một phân tích đa tác nhân có thể mất đủ thời gian để giữ một yêu cầu mở gây khó xử cho khách hàng. Một mô hình tốt hơn là: ```text POST /analyses -> trả về analysis_id GET /analyses/{id} -> trả về đã xếp hàng, đang chạy, đã hoàn thành hoặc thất bại ``` Cấu trúc đó dễ dàng hơn cho trình duyệt, dễ dàng hơn cho QA và dễ dàng hơn để ghi lại trong Apidog. ### Tạo hợp đồng API Một hợp đồng tối thiểu trông như thế này:
| Điểm cuối | Mục đích |
|---|---|
GET /health | kiểm tra sức khỏe cơ bản |
POST /analyses | kích hoạt một lần chạy TradingAgents |
GET /analyses/{analysis_id} | lấy trạng thái công việc và kết quả cuối cùng |
### Xây dựng trình bao Đây là một ví dụ FastAPI nhỏ gọn: ```python from concurrent.futures import ThreadPoolExecutor from datetime import date, datetime from uuid import uuid4 from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field from tradingagents.default_config import DEFAULT_CONFIG from tradingagents.graph.trading_graph import TradingAgentsGraph app = FastAPI(title="TradingAgents API", version="0.1.0") executor = ThreadPoolExecutor(max_workers=2) jobs: dict[str, dict] = {} class AnalysisRequest(BaseModel): ticker: str = Field(..., min_length=1, examples=["NVDA"]) analysis_date: date llm_provider: str = Field(default="openai") deep_think_llm: str = Field(default="gpt-5.2") quick_think_llm: str = Field(default="gpt-5-mini") research_depth: int = Field(default=1, ge=1, le=5) def run_analysis(job_id: str, payload: AnalysisRequest) -> None: jobs[job_id]["status"] = "running" jobs[job_id]["started_at"] = datetime.utcnow().isoformat() config = DEFAULT_CONFIG.copy() config["llm_provider"] = payload.llm_provider config["deep_think_llm"] = payload.deep_think_llm config["quick_think_llm"] = payload.quick_think_llm config["max_debate_rounds"] = payload.research_depth config["max_risk_discuss_rounds"] = payload.research_depth try: graph = TradingAgentsGraph(debug=False, config=config) _, decision = graph.propagate( payload.ticker, payload.analysis_date.isoformat(), ) jobs[job_id].update( { "status": "completed", "finished_at": datetime.utcnow().isoformat(), "result": decision, } ) except Exception as exc: jobs[job_id].update( { "status": "failed", "finished_at": datetime.utcnow().isoformat(), "error": str(exc), } ) @app.get("/health") def health() -> dict: return {"status": "ok"} @app.post("/analyses", status_code=202) def create_analysis(payload: AnalysisRequest) -> dict: analysis_id = str(uuid4()) jobs[analysis_id] = { "status": "queued", "ticker": payload.ticker, "analysis_date": payload.analysis_date.isoformat(), "created_at": datetime.utcnow().isoformat(), } executor.submit(run_analysis, analysis_id, payload) return {"analysis_id": analysis_id, "status": "queued"} @app.get("/analyses/{analysis_id}") def get_analysis(analysis_id: str) -> dict: job = jobs.get(analysis_id) if not job: raise HTTPException(status_code=404, detail="Analysis not found") return job ``` Khởi động dịch vụ: ```bash uvicorn app:app --reload ``` Khi máy chủ khởi động, FastAPI sẽ hiển thị: * `http://localhost:8000/docs` * `http://localhost:8000/openapi.json` URL thứ hai đặc biệt hữu ích vì Apidog có thể nhập trực tiếp. ## Bước 5: Sử dụng TradingAgents thông qua API Giờ đây, bạn đã sẵn sàng sử dụng TradingAgents theo cách ổn định và lặp lại. ### Kích hoạt phân tích Gửi yêu cầu `POST /analyses` với phần thân như sau: ```json { "ticker": "NVDA", "analysis_date": "2026-03-26", "llm_provider": "openai", "deep_think_llm": "gpt-5.2", "quick_think_llm": "gpt-5-mini", "research_depth": 2 } ``` Phản hồi sẽ nhanh và nhỏ gọn: ```json { "analysis_id": "88f9f0f5-7315-4c73-8ed5-d0a71f613d31", "status": "queued" } ``` Đó chính xác là những gì bạn muốn. Khách hàng của bạn không cần báo cáo cuối cùng ngay lập tức. Họ cần một xử lý ổn định cho lần chạy đó. ### Thăm dò kết quả Sử dụng `GET /analyses/{analysis_id}` để kiểm tra tiến độ: ```json { "status": "running", "ticker": "NVDA", "analysis_date": "2026-03-26", "created_at": "2026-03-26T06:00:00.000000", "started_at": "2026-03-26T06:00:01.000000" } ``` Khi quy trình làm việc hoàn tất, phản hồi có thể bao gồm quyết định cuối cùng: ```json { "status": "completed", "ticker": "NVDA", "analysis_date": "2026-03-26", "result": { "decision": "hold" } } ``` Nếu có lỗi xảy ra, hãy trả về trạng thái `failed` rõ ràng và thông báo lỗi thay vì để khách hàng phải đoán. ## Bước 6: Nhập API vào Apidog Đây là lúc quy trình làm việc trở nên dễ dàng bảo trì hơn nhiều. Trong Apidog, nhập lược đồ OpenAPI từ: ```text http://localhost:8000/openapi.json ``` Sau khi nhập, bạn sẽ thấy các điểm cuối của mình với cấu trúc yêu cầu và phản hồi đã được đặt sẵn. Điều đó mang lại cho bạn một vài lợi ích ngay lập tức: * tài liệu khớp với việc triển khai * các tham số đường dẫn được tạo đúng cách * nội dung yêu cầu vẫn phù hợp với mã của bạn * đồng đội không cần xây dựng lại bộ sưu tập bằng tay Nếu bạn đang chuyển từ việc kiểm tra cURL ad hoc, đây là một bản nâng cấp có ý nghĩa. Nếu bạn đang chuyển từ một công cụ chỉ yêu cầu, đây là nơi Apidog bắt đầu quan trọng hơn vì bạn có thể giữ thiết kế, kiểm tra, môi trường và tài liệu ở một nơi. ## Bước 7: Tạo môi trường Apidog Khi API được nhập, hãy tạo một môi trường cho dịch vụ cục bộ của bạn. Các biến ví dụ: ```text base_url = http://localhost:8000 analysis_id = ``` Nếu API của bạn sử dụng xác thực, hãy bao gồm cả điều đó: ```text internal_api_key = your-local-dev-key ``` Bước này trông nhỏ, nhưng nó ngăn chặn rất nhiều ma sát: * bạn có thể chuyển đổi giữa cục bộ, dàn dựng và sản xuất nhanh hơn * các yêu cầu của bạn vẫn có thể tái sử dụng * đồng đội của bạn không phải viết lại URL và tiêu đề mỗi lần Đây là một trong những lý do đơn giản nhất mà Apidog là một người bạn đồng hành mạnh mẽ cho TradingAgents. Khung tự nó xử lý logic phân tích. Apidog xử lý quy trình làm việc chung xung quanh nó. ## Bước 8: Kiểm tra toàn bộ quy trình làm việc trong Apidog Giờ đây, bạn có thể sử dụng Apidog để kiểm tra TradingAgents theo cách mà một khách hàng thực sự sẽ làm. ### Yêu cầu 1: Tạo phân tích Cấu hình: * phương thức: `POST` * URL: `{{base_url}}/analyses` * nội dung: ```json { "ticker": "NVDA", "analysis_date": "2026-03-26", "llm_provider": "openai", "deep_think_llm": "gpt-5.2", "quick_think_llm": "gpt-5-mini", "research_depth": 2 } ``` Thêm một tập lệnh kiểm tra để xác thực trạng thái và lưu ID: ```javascript pm.test("Status is 202", function () { pm.response.to.have.status(202); }); const data = pm.response.json(); pm.expect(data.analysis_id).to.exist; pm.environment.set("analysis_id", data.analysis_id); ``` ### Yêu cầu 2: Thăm dò phân tích Cấu hình: * phương thức: `GET` * URL: `{{base_url}}/analyses/{{analysis_id}}` Sau đó thêm một xác nhận như: ```javascript pm.test("Analysis has a valid status", function () { const data = pm.response.json(); pm.expect(["queued", "running", "completed", "failed"]).to.include(data.status); }); ``` Nếu bạn cũng muốn kiểm tra đường dẫn thành công: ```javascript pm.test("Completed jobs include a result", function () { const data = pm.response.json(); if (data.status === "completed") { pm.expect(data.result).to.exist; } }); ``` ### Xâu chuỗi cả hai yêu cầu vào một kịch bản Đây là lúc Apidog trở thành nhiều hơn một ứng dụng khách API. Xây dựng một kịch bản mà: 1. gửi `POST /analyses` 2. lưu `analysis_id` 3. đợi vài giây 4. chạy `GET /analyses/{{analysis_id}}` Điều đó mang lại cho nhóm QA và kỹ thuật của bạn một cách có thể tái tạo để xác thực vòng đời thay vì chỉ kiểm tra xem một điểm cuối có trả về `200` hay không. ## Bước 9: Xuất bản tài liệu nội bộ cho nhóm của bạn Khi các yêu cầu hoạt động, đừng dừng lại ở việc kiểm tra. Sử dụng Apidog để xuất bản tài liệu nội bộ giải thích: * những nhà cung cấp nào được phép * `research_depth` có nghĩa là gì trong triển khai của bạn * những giá trị trạng thái nào khách hàng nên mong đợi * thời gian chạy thường mất bao lâu * những lỗi nào có thể thử lại * nơi áp dụng tuyên bố miễn trừ trách nhiệm chỉ dành cho nghiên cứu Đây là một trong những phần quan trọng nhất của việc sử dụng TradingAgents một cách hiệu quả. Khung cốt lõi rất thông minh, nhưng các khung thông minh trở thành nút thắt cổ chai của nhóm khi hợp đồng chỉ tồn tại trong đầu của một nhà phát triển. Tải xuống Apidog miễn phí để biến TradingAgents thành một quy trình làm việc API có tài liệu với môi trường, xác nhận và các kịch bản sẵn sàng cho nhóm có thể tái sử dụng. ## Những sai lầm phổ biến khi sử dụng TradingAgents theo cách này ### Coi khung là một API được lưu trữ TradingAgents không phải là một dịch vụ công cộng làm sẵn. Nó là một khung Python. Xây dựng hợp đồng mà bạn muốn nhóm của mình sử dụng thay vì mong đợi kho lưu trữ cung cấp nó cho bạn. ### Truyền bí mật qua phần thân yêu cầu Giữ các khóa nhà cung cấp trong quản lý môi trường. Đừng để chúng rò rỉ vào các ví dụ, cuộc gọi giao diện người dùng hoặc ảnh chụp màn hình được chia sẻ. ### Trả về một phản hồi đồng bộ dài Đối với quy trình làm việc tác nhân nhiều bước, API dựa trên công việc thường dễ quản lý hơn là một yêu cầu chặn dài. ### Hiển thị quá nhiều nút cấu hình Kho lưu trữ có các tùy chọn cấu hình hữu ích, nhưng API của bạn không cần phải hiển thị mọi cài đặt nội bộ ngay từ đầu. Bắt đầu với một hợp đồng nhỏ, ổn định. ### Chỉ giữ kết quả trong bộ nhớ Mã hướng dẫn sử dụng một từ điển trong bộ nhớ vì nó dễ hiểu. Trong sản xuất, hãy lưu trữ trạng thái công việc trong Redis, Postgres hoặc một backend bền vững khác. ### Che giấu tuyên bố từ chối trách nhiệm nghiên cứu Nếu dịch vụ của bạn đóng gói TradingAgents, hãy giữ nguyên cảnh báo mà dự án sử dụng. Khung này dành cho nghiên cứu và thử nghiệm, không phải lời khuyên tài chính. ## Kết luận Cách tốt nhất để sử dụng TradingAgents phụ thuộc vào những gì bạn đang cố gắng làm. Nếu bạn đang khám phá khung một mình, CLI và gói Python là đủ. Nếu bạn muốn một quy trình làm việc nhóm ổn định, lặp lại, hãy đóng gói TradingAgents trong một API nhỏ và sử dụng Apidog để kiểm tra và ghi lại nó. Nếu bạn muốn chuyển từ kho GitHub sang quy trình làm việc nhóm có thể sử dụng nhanh chóng, hãy cài đặt TradingAgents, xác nhận `TradingAgentsGraph` hoạt động cục bộ, thêm `POST /analyses` và `GET /analyses/{id}`, sau đó nhập lược đồ vào Apidog và xây dựng một kịch bản end-to-end. Con đường đó dễ bảo trì hơn nhiều so với một tập hợp các lệnh terminal và kiến thức truyền miệng. button ## Câu hỏi thường gặp ### Làm thế nào để bạn sử dụng TradingAgents lần đầu tiên? Bắt đầu bằng cách cài đặt kho lưu trữ, đặt các biến môi trường của nhà cung cấp mô hình và chạy ví dụ Python với `TradingAgentsGraph`. Khi điều đó hoạt động, hãy quyết định xem bạn chỉ cần CLI hay bạn nên đóng gói nó trong một API. ### TradingAgents có đi kèm với API REST chính thức không? Không phải từ các tài liệu kho lưu trữ công khai được xem xét vào ngày 26 tháng 3 năm 2026. Dự án được trình bày dưới dạng gói CLI và Python, đó là lý do tại sao nhiều nhóm sẽ muốn thêm một lớp FastAPI mỏng. ### Cách dễ nhất để sử dụng TradingAgents trong một ứng dụng giao diện người dùng là gì? Không gọi trực tiếp khung Python từ giao diện người dùng. Hiển thị nó thông qua một API backend trả về `analysis_id`, sau đó để giao diện người dùng thăm dò kết quả. ### Tại sao sử dụng Apidog với TradingAgents? Apidog cung cấp cho bạn một nơi sạch sẽ để nhập lược đồ OpenAPI, lưu các giá trị môi trường, lưu trữ các yêu cầu ví dụ, thêm các xác nhận và chia sẻ quy trình làm việc với các đồng đội, những người không cần phải đảo ngược kỹ thuật mã Python. ### Những cài đặt TradingAgents nào đáng để hiển thị trong một API? Bộ khởi đầu an toàn nhất là mã chứng khoán, ngày phân tích, nhà cung cấp, lựa chọn mô hình và độ sâu nghiên cứu. Bạn luôn có thể mở rộng sau này nếu trường hợp sử dụng là thực tế. ### Tôi có thể giữ trạng thái công việc ví dụ trong bộ nhớ không? Chỉ để học hoặc tạo mẫu. Trong sản xuất, hãy lưu trữ trạng thái công việc và kết quả trong một backend bền vững để việc khởi động lại dịch vụ không xóa các phân tích đang hoạt động. ### TradingAgents có phù hợp cho các quyết định tài chính trực tiếp không? Các tài liệu dự án công khai mô tả nó là một khung nghiên cứu và nói rõ rằng nó không phải là lời khuyên tài chính hoặc đầu tư. Coi nó là một hệ thống nghiên cứu và thử nghiệm trừ khi bạn thêm các kiểm soát, xác thực và quản trị của riêng mình.
