<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Metrics · Nhân Tài Đức</title>
    <link>https://jared.lynskey.co.nz/vi/tags/metrics/</link>
    <description>Những câu chuyện ngắn về kỹ thuật phần mềm và lãnh đạo đội ngũ kỹ sư — performance review, tuyển dụng và mở rộng team, CI/CD, giám sát DevOps và AI agent. Viết từ Seoul.</description>
    <generator>Hugo</generator>
    <language>vi</language>
    <copyright>© 2026 Nhân Tài Đức</copyright>
    <lastBuildDate>Wed, 28 Oct 2026 00:00:00 +1300</lastBuildDate>
    <atom:link href="https://jared.lynskey.co.nz/vi/tags/metrics/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Thuật toán xếp hạng nội dung: những tín hiệu ngoài lượt xem và lượt thích</title>
      <link>https://jared.lynskey.co.nz/vi/posts/2023/2023-10-06-reinenforcement-learning/</link>
      <guid isPermaLink="true">https://jared.lynskey.co.nz/vi/posts/2023/2023-10-06-reinenforcement-learning/</guid>
      <pubDate>Fri, 06 Oct 2023 00:30:03 +0000</pubDate>
      <dc:creator>Jared Lynskey</dc:creator>
      <category>content ranking</category>
      <category>metrics</category>
      <category>SEO</category>
      <category>machine learning</category>
      <category>user engagement</category>
      <category>content strategy</category>
      <description>Thuật toán xếp hạng nội dung (content ranking) làm gì, vì sao chỉ xếp theo lượt xem và lượt thích thì bài nổi càng thêm nổi, và những tín hiệu nào đáng gộp vào một điểm số chung.</description>
      <content:encoded><![CDATA[<p>Thuật toán xếp hạng nội dung (content ranking algorithm) là thứ quyết định một bảng tin (feed), một trang kết quả tìm kiếm hay một danh sách “bài nổi bật” sẽ hiện cái gì trước, cái gì sau. Nó chấm cho mỗi nội dung một điểm số dựa trên nhiều tín hiệu (người dùng phản ứng với nội dung ra sao, bản thân nội dung thế nào, mới và liên quan đến đâu), rồi sắp xếp theo điểm số đó. Nhưng nếu chỉ xếp hạng theo lượt xem và lượt thích, bạn sẽ rơi vào vòng lặp “giàu càng thêm giàu”: bài nào nằm trên cùng thì được nhiều người thấy, nên gom thêm lượt xem và lượt thích, nên lại tiếp tục nằm trên cùng.</p>
<p>Đó chính là khuyết điểm dễ thấy của lượt xem và lượt bình chọn (upvote): chúng chỉ thưởng cho những gì vốn đã nổi. Nội dung mới thì chết đói dưới đáy bảng tin, và dần dần nền tảng biến thành một kênh chiếu lại. Ở chỗ tôi làm, xếp hạng bảng tin cho tốt là một trong những bài toán khó mà ít ai để ý, nên tôi đã dành khá nhiều thời gian nghĩ xem còn những tín hiệu nào khác đáng tin.</p>

<h3 class="relative group">Nhìn vào việc người ta làm, đừng chỉ nhìn chỗ họ bấm
    <div id="nhìn-vào-việc-người-ta-làm-đừng-chỉ-nhìn-chỗ-họ-bấm" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#nh%c3%acn-v%c3%a0o-vi%e1%bb%87c-ng%c6%b0%e1%bb%9di-ta-l%c3%a0m-%c4%91%e1%bb%abng-ch%e1%bb%89-nh%c3%acn-ch%e1%bb%97-h%e1%bb%8d-b%e1%ba%a5m" aria-label="Cọc dấu">#</a>
    </span>
    
</h3>
<p>Người dùng hiếm khi chủ động góp ý, mà có góp ý thì cũng thiên lệch; ngược lại, dữ liệu hành vi thì có rất nhiều. Thời gian ở lại trang và độ sâu cuộn cho biết người ta có đọc thật hay bỏ đi ngay sau đoạn đầu. Lượt quay lại còn tốt hơn nữa — quay lại đọc một bài là lời khen mạnh hơn bất kỳ lượt bình chọn nào. Còn thoát ra nhanh là một tín hiệu tiêu cực đáng giá: nội dung đã hứa hẹn một điều mà người đọc không nhận được.</p>

<h3 class="relative group">Tín hiệu nằm sẵn trong chính nội dung
    <div id="tín-hiệu-nằm-sẵn-trong-chính-nội-dung" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#t%c3%adn-hi%e1%bb%87u-n%e1%ba%b1m-s%e1%ba%b5n-trong-ch%c3%adnh-n%e1%bb%99i-dung" aria-label="Cọc dấu">#</a>
    </span>
    
</h3>
<p>Nội dung tốt không phải lúc nào cũng gom được lượt thích ngay từ đầu, nhưng thường nó thể hiện chất lượng theo những cách khác. Tính mới là một — bài này có nói về điều gì mà nền tảng chưa từng có không? Cấu trúc là một yếu tố nữa; trình bày gọn gàng, ngữ pháp ổn và diễn đạt rõ ràng đi đôi với chất lượng nhiều hơn ta muốn thừa nhận. Lịch sử của tác giả cũng là một điểm xuất phát hợp lý, miễn là xét theo khả năng giữ chân người đọc của các bài cũ chứ không phải số lượt thích thô. Bình luận sớm cũng có ích: ba bình luận tích cực thật lòng đáng giá hơn ba mươi lượt bình chọn bấm theo phản xạ, và chỉ cần phân tích ngữ nghĩa một chút là đã có thể đánh dấu những nội dung lấp được khoảng trống mà nền tảng đang thiếu.</p>

<h3 class="relative group">Mượn tín hiệu từ bên ngoài
    <div id="mượn-tín-hiệu-từ-bên-ngoài" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#m%c6%b0%e1%bb%a3n-t%c3%adn-hi%e1%bb%87u-t%e1%bb%ab-b%c3%aan-ngo%c3%a0i" aria-label="Cọc dấu">#</a>
    </span>
    
</h3>
<p>Internet rộng lớn ngoài kia cho bạn biết cái gì đang được quan tâm ngay lúc này. Nội dung khớp với những từ khoá tìm kiếm đang lên thì đã có sẵn độ liên quan, và bài nào đăng nhanh về một chủ đề đang nóng thì xứng đáng được đẩy lên. Những gì đang rôm rả trên Twitter hay Reddit thường là bản xem trước cho những gì người dùng của bạn sẽ muốn tiếp theo — chỉ cần dự đoán một chút, bạn có thể đẩy nội dung mới phù hợp lên trước khi con sóng tới, thay vì chạy theo sau. Ô tìm kiếm ngay trên nền tảng của bạn cũng hay bị đánh giá thấp: nếu người dùng cứ tìm mãi một chủ đề, hay một bài đều đặn kéo lưu lượng truy cập (traffic) từ công cụ tìm kiếm về, thì đó là độ liên quan mà bạn chẳng cần phải đoán.</p>

<h3 class="relative group">Gộp các tín hiệu thành một điểm số
    <div id="gộp-các-tín-hiệu-thành-một-điểm-số" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#g%e1%bb%99p-c%c3%a1c-t%c3%adn-hi%e1%bb%87u-th%c3%a0nh-m%e1%bb%99t-%c4%91i%e1%bb%83m-s%e1%bb%91" aria-label="Cọc dấu">#</a>
    </span>
    
</h3>
<p>Dưới đây là ý tưởng đó viết thành vài dòng Python. Đây chỉ là ví dụ minh họa, không phải một hệ thống chạy thật trên môi trường production. Mỗi tín hiệu được chuẩn hóa (normalise) về khoảng 0 đến 1 để tín hiệu nào có con số thô lớn cũng không lấn át phần còn lại, tổng có trọng số gộp chúng thành một điểm duy nhất, và hệ số suy giảm theo thời gian (time decay) cho bài mới một cơ hội sòng phẳng để cạnh tranh với bài “hot” của tháng trước.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">WEIGHTS</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;read_depth&#34;</span><span class="p">:</span> <span class="mf">0.3</span><span class="p">,</span> <span class="s2">&#34;revisits&#34;</span><span class="p">:</span> <span class="mf">0.25</span><span class="p">,</span> <span class="s2">&#34;quality&#34;</span><span class="p">:</span> <span class="mf">0.25</span><span class="p">,</span> <span class="s2">&#34;early_comments&#34;</span><span class="p">:</span> <span class="mf">0.2</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">HALF_LIFE_HOURS</span> <span class="o">=</span> <span class="mi">48</span>  <span class="c1"># a post loses half its score every two days</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">normalise</span><span class="p">(</span><span class="n">values</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">lo</span><span class="p">,</span> <span class="n">hi</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">values</span><span class="p">),</span> <span class="nb">max</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">[(</span><span class="n">v</span> <span class="o">-</span> <span class="n">lo</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="n">hi</span> <span class="o">-</span> <span class="n">lo</span><span class="p">)</span> <span class="k">if</span> <span class="n">hi</span> <span class="o">&gt;</span> <span class="n">lo</span> <span class="k">else</span> <span class="mf">0.0</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">values</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">rank</span><span class="p">(</span><span class="n">items</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;items: dicts holding raw signal values plus &#34;age_hours&#34;.&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">norm</span> <span class="o">=</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">normalise</span><span class="p">([</span><span class="n">item</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">items</span><span class="p">])</span> <span class="k">for</span> <span class="n">name</span> <span class="ow">in</span> <span class="n">WEIGHTS</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">scores</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">items</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">base</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">weight</span> <span class="o">*</span> <span class="n">norm</span><span class="p">[</span><span class="n">name</span><span class="p">][</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">weight</span> <span class="ow">in</span> <span class="n">WEIGHTS</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">        <span class="n">scores</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">base</span> <span class="o">*</span> <span class="mf">0.5</span> <span class="o">**</span> <span class="p">(</span><span class="n">item</span><span class="p">[</span><span class="s2">&#34;age_hours&#34;</span><span class="p">]</span> <span class="o">/</span> <span class="n">HALF_LIFE_HOURS</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">order</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">items</span><span class="p">)),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">scores</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">[</span><span class="n">items</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">order</span><span class="p">]</span></span></span></code></pre></div></div>
<p>Các trọng số chỉ là phỏng đoán cho tới khi những thử nghiệm ở phần dưới chứng minh điều ngược lại. Lượt xem và lượt thích vẫn có thể đưa vào; chỉ là chúng trở thành một đầu vào trong số nhiều đầu vào, chứ không còn là toàn bộ điểm số. Chu kỳ bán rã (half-life) quyết định bài cũ chìm xuống nhanh đến đâu, và đó là cả một chủ đề riêng: tôi đã viết kỹ về nó trong bài <a href="https://jared.lynskey.co.nz/vi/posts/2023/2023-09-27-simulating-views/" >thuật toán xếp hạng bảng tin quyết định khi nào bài cũ bị dìm xuống</a>. Các hệ thống thật thường để mô hình tự học trọng số thay vì chọn bằng tay, nhưng hình dạng thì vẫn vậy: nhiều tín hiệu đi vào, một con số đi ra, rồi sắp xếp.</p>

<h3 class="relative group">Rồi kiểm thử cho sòng phẳng
    <div id="rồi-kiểm-thử-cho-sòng-phẳng" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#r%e1%bb%93i-ki%e1%bb%83m-th%e1%bb%ad-cho-s%c3%b2ng-ph%e1%ba%b3ng" aria-label="Cọc dấu">#</a>
    </span>
    
</h3>
<p>Tín hiệu có khéo đến đâu cũng phải đem đi thử nghiệm A/B (A/B test) — cho một nhóm nhỏ người dùng xem nội dung mới rồi so mức tương tác với những bài đang giữ vị trí. Và để ý xem nội dung lan ra thế nào: lượt chia sẻ, lượt nhắc đến và lượt nhúng, cả trong lẫn ngoài nền tảng, nói lên giá trị nhiều hơn hẳn cái bộ đếm lượt xem.</p>
<p>Không chỉ số đơn lẻ nào trụ nổi khi va chạm với thực tế. Những cách xếp hạng thật sự hiệu quả đều pha trộn hành vi người dùng, chất lượng nội tại, tính thời sự và những thử nghiệm sòng phẳng, và không tín hiệu nào được quyền quyết định sau cùng.</p>
]]></content:encoded>
      <media:content url="https://jared.lynskey.co.nz/en/posts/2023/2023-10-06-reinenforcement-learning/featured.jpeg" medium="image" type="image/jpeg" />
    </item>
  </channel>
</rss>
