<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://wechaty.js.org/feed.xml" rel="self" type="application/atom+xml" /><link href="https://wechaty.js.org/" rel="alternate" type="text/html" /><updated>2025-12-21T19:18:39+00:00</updated><id>https://wechaty.js.org/feed.xml</id><title type="html">Wechaty</title><subtitle>Conversational RPA SDK for Chatbot Makers</subtitle><entry><title type="html">The Antigravity Effect: When Coding Becomes Orchestration</title><link href="https://wechaty.js.org/2025/11/25/the-antigravity-effect-when-coding-becomes-orchestration/" rel="alternate" type="text/html" title="The Antigravity Effect: When Coding Becomes Orchestration" /><published>2025-11-25T00:00:00+00:00</published><updated>2025-11-25T00:00:00+00:00</updated><id>https://wechaty.js.org/2025/11/25/the-antigravity-effect-when-coding-becomes-orchestration</id><content type="html" xml:base="https://wechaty.js.org/2025/11/25/the-antigravity-effect-when-coding-becomes-orchestration/"><![CDATA[<blockquote>
  <p>As an internal tester for <strong>Google Antigravity</strong>, I’ve had a front-row seat to the single biggest step-change in software development since the original IDE. But this isn’t just about faster coding. It’s about <strong>scaling yourself</strong>.</p>
</blockquote>

<p>I’ve been biting my tongue for weeks.</p>

<p>For solo founders and non-technical creators, the dream has always been to build a “unicorn” product without needing a unicorn team. We are finally there.</p>

<p>We are witnessing a fundamental shift: from <strong>coding</strong> to <strong>orchestrating</strong>.</p>

<p>Antigravity isn’t just an editor; it’s an <strong>Operating System for Artificial Intelligence</strong>. But more importantly, it gives you something money can’t easily buy: an instant, world-class founding team.</p>

<h2 id="meet-your-new-ai-co-founder-team">Meet Your New AI Co-Founder Team</h2>

<p>When you open Antigravity, you aren’t just opening an IDE. You are walking into a room with three high-powered executives ready to work for you 24/7:</p>

<ol>
  <li><strong>The CTO (Gemini 3 Pro)</strong>: Your AI coding agent co-founder. It knows every framework, refactors legacy code in seconds, and architects scalable systems while you sleep.</li>
  <li><strong>The Design Director (Nano Banana Pro)</strong>: Your creative visionary. It generates premium UI assets, icons, and entire design systems on the fly, ensuring your product looks like a million bucks from Day 1.</li>
  <li><strong>The Testing Director (Browser Use)</strong>: Your QA lead. It doesn’t just run unit tests; it launches a real browser, clicks buttons, fills forms, and verifies user flows exactly like a human would.</li>
</ol>

<p>This is a powerful team for anyone who wants to build a one-person billion-dollar company! This team is more complete—and faster—than most of the founding teams applying to YC today.</p>

<p>With this team, you unlock a new era of development <strong>Vibe Coding</strong>.</p>

<p><strong>What is Vibe Coding?</strong></p>

<blockquote>
  <p><strong>Vibe Coding</strong> <em>(n.)</em>: The state of flow where you focus purely on architecture and creativity, while your autonomous executive team handles the implementation, design, and testing in parallel.</p>
</blockquote>

<p>If you’re a solo founder, prepare to become a full-stack organization overnight.</p>

<hr />

<p><img src="/assets/2025/11-the-antigravity-effect-when-coding-becomes-orchestration/header-final.webp" alt="Mission Control" /></p>

<h2 id="1-the-cto-at-work-your-new-mission-control-">1. The CTO at Work: Your New Mission Control 🧑‍🚀</h2>

<p>We’ve all been there: you have a brilliant idea, but you’re stuck on a React hook, or you’re waiting for a freelancer to fix a CSS bug. It’s synchronous, slow, and kills your momentum.</p>

<p>Antigravity solves this by giving you a <strong>CTO</strong> that works in parallel with you. The workspace is separated into two distinct, powerful surfaces:</p>

<ul>
  <li><strong>The Editor:</strong> Your familiar canvas for synchronous work—fixing typos, tweaking UI, committing small changes.</li>
  <li><strong>The Agent Manager:</strong> Your Mission Control where your CTO operates.</li>
</ul>

<p>This is the <strong>“Aha” Moment</strong> for founders. You can spawn a high-priority agent to “Research and implement OAuth for the API” in the Manager. While your CTO is planning, fetching dependencies, and writing the code in the background, you can be in the Editor polishing the landing page text.</p>

<p>This parallel agent mode is what truly separates Antigravity from everything else. You are no longer just a coder; you are a <strong>Technical Director</strong> managing a brilliant CTO.</p>

<blockquote>
  <p>💡 <strong>Cross-Reference:</strong> Unlike CLI-based agents like Gemini CLI or Claude Code, the Manager surface gives you a visual dashboard of your CTO’s internal thought process, or <strong>Artifacts</strong> (Task List, Implementation Plan, Walkthrough). You don’t just see the code; you see the intelligence <em>planning</em> the code.</p>
</blockquote>

<hr />

<p><img src="/assets/2025/11-the-antigravity-effect-when-coding-becomes-orchestration/mission-control-focused.webp" alt="Focused Workflow" /></p>

<h2 id="2-the-testing-director-trust-dont-just-verify-">2. The Testing Director: Trust, Don’t Just Verify 🧪</h2>

<p>For solo founders, the biggest barrier isn’t writing code—it’s <strong>testing</strong> and <strong>validation</strong>. How do you know the code works without spending hours setting up a test suite or clicking through the UI?</p>

<p>Enter your <strong>Testing Director</strong>.</p>

<p>Antigravity’s <strong>native browser integration</strong> is the killer feature. Your Testing Director isn’t just generating files; it has its own embedded Chrome instance. It doesn’t just <em>say</em> it fixed a bug; you watch its cursor navigate the page, click the buttons, and verify the outcome against the original request.</p>

<p>The AI becomes your integrated QA department. This means less friction, less fear of deploying, and a faster path from idea to revenue.</p>

<hr />

<p><img src="/assets/2025/11-the-antigravity-effect-when-coding-becomes-orchestration/mission-control-holographic.webp" alt="Holographic Design" /></p>

<h2 id="3-the-design-director-nano-banana-pro-">3. The Design Director: Nano Banana Pro ✨</h2>

<p>For too long, the design layer and the coding layer have been separate worlds. We build the architecture, then we stop, switch to a design tool, hire a designer, or settle for “Lorem Ipsum” images.</p>

<p>Antigravity natively integrates <strong>Nano Banana Pro</strong>—your new <strong>Design Director</strong>—directly into the development workflow. This is a game-changer that we must treat with serious reverence.</p>

<p>Need a hero image that perfectly matches your app’s new color scheme? Need a set of 50 icons? Ask the agent, and your Design Director delivers high-fidelity assets instantly, right into your project folder. You can even generate entire UI mockups and diagrams, then ask the CTO (the coding agent) to turn them into React components.</p>

<p>This means your <strong>Vibe Coding</strong> process is now truly end-to-end—you can design and build without breaking flow.</p>

<hr />

<h2 id="4-the-monster-within-gemini-3-pro-and-openness-">4. The Monster Within: Gemini 3 Pro and Openness 🤯</h2>

<p>At its core, Antigravity is a platform, and its power is rooted in the “monster” models it orchestrates.</p>

<p><strong>Gemini 3 Pro</strong>—the brain behind your CTO—sets a new standard for code understanding, complex dependency management, and multi-step planning. You can even choose the specific “brain” for the task, toggling between <strong>Gemini 3 Pro (High)</strong> for complex reasoning or lighter models for speed.</p>

<p>But what I love most is the platform’s commitment to openness. Antigravity doesn’t lock you in. You can also run powerful autonomous agents powered by:</p>

<ul>
  <li><strong>Claude Sonnet 4.5</strong></li>
  <li><strong>GPT-OSS</strong> (Open Source Specialist)</li>
</ul>

<p>This model optionality ensures Antigravity remains the most powerful and flexible coding environment for years to come.</p>

<hr />

<h2 id="5-critical-take-the-ui-needs-to-catch-up-️">5. Critical Take: The UI Needs to Catch Up ⚠️</h2>

<p>I love this tool, but I have to be honest: the UI naming conventions are confusing and, frankly, need a rethink.</p>

<p>Antigravity presents you with two main modes: <strong>Planning</strong> and <strong>Fast</strong>.
To a human, “Planning” implies a passive state—drafting a roadmap, discussing architecture, or thinking without acting. In other agents like Claude Code, “Plan” mode is exactly that: a safe space for discussion.</p>

<p><strong>In Antigravity, “Planning” is a misnomer.</strong> It should be called <strong>“Architect &amp; Execute”</strong>.</p>

<p>When you are in Planning mode, the agent isn’t just taking notes. It is actively researching, checking files, and—here is the critical bug—sometimes it just <strong>starts executing code</strong> without waiting for your final “go.” I’ve had moments where I thought we were just brainstorming a implementation design, and suddenly the agent is running migration scripts. That is a “rogue agent” behavior that needs better harnessing.</p>

<p>Similarly, <strong>“Fast”</strong> mode is a poor name. It sounds like a performance setting, but it really means <strong>“Direct Execution”</strong> or <strong>“Doer Mode”</strong>.</p>

<p><strong>My advice:</strong> Ignore the labels.</p>

<ul>
  <li>Treat <strong>Planning</strong> as <strong>“The Architect”</strong> (use for complex, multi-file tasks).</li>
  <li>Treat <strong>Fast</strong> as <strong>“The Builder”</strong> (use for quick fixes and simple commands).</li>
</ul>

<p>The intelligence is there, but the controls are still in beta. You need to learn the quirks to master the machine.</p>

<hr />

<h2 id="watch-antigravity-in-action">Watch Antigravity in Action</h2>

<h3 id="introducing-google-antigravity">Introducing Google Antigravity</h3>

<div style="
    position: relative;
    padding-bottom: 56.25%;
    padding-top:30px;
    height:0;
    overflow:hidden;
">
  <iframe src="https://www.youtube.com/embed/nTOVIGsqCuY" allowfullscreen="" webkitallowfullscreen="" frameborder="0" style="
      position: absolute;
      top:0;
      left:0;
      width:100%;
      height:100%;
    ">
</iframe>

</div>

<hr />

<h3 id="nano-banana-pro-is-now-available-">Nano Banana Pro is Now Available |</h3>

<div style="
    position: relative;
    padding-bottom: 56.25%;
    padding-top:30px;
    height:0;
    overflow:hidden;
">
  <iframe src="https://www.youtube.com/embed/FB6HO7CZHWw" allowfullscreen="" webkitallowfullscreen="" frameborder="0" style="
      position: absolute;
      top:0;
      left:0;
      width:100%;
      height:100%;
    ">
</iframe>

</div>

<hr />

<h2 id="ready-to-experience-liftoff">Ready to Experience Liftoff?</h2>

<p>Antigravity isn’t just an IDE upgrade; it’s the future of software development. It enables developers to focus on architecture and problem-solving, while allowing solo founders and creators to build powerful products with a full executive team at their fingertips.</p>

<p>Download the public preview today. Spawn your first parallel agent, watch your Testing Director manage the browser, and let the monster loose. You will have your own <strong>“Aha” Moment</strong> guaranteed.</p>

<h3 id="-join-the-revolution">🚀 Join the Revolution</h3>

<p>Don’t just watch the future happen—build it.</p>

<ul>
  <li><strong><a href="https://antigravity.google">Download Antigravity Public Preview</a></strong></li>
  <li><strong><a href="https://discord.gg/antigravity">Join the Discord Community</a></strong></li>
</ul>

<p><em>Read the official announcements here:</em></p>

<ul>
  <li><a href="https://antigravity.google/blog/introducing-google-antigravity">Introducing Google Antigravity</a></li>
  <li><a href="https://antigravity.google/blog/nano-banana-pro-in-google-antigravity">Nano Banana Pro in Google Antigravity</a></li>
</ul>

<hr />

<h3 id="credits">Credits</h3>

<p>This blog post, including all its images, was drafted entirely with Antigravity.</p>

<p><img src="/assets/2025/11-the-antigravity-effect-when-coding-becomes-orchestration/antigravity-screenshot-32x9.webp" alt="Antigravity" /></p>

<p>May this demonstration of Antigravity’s capabilities ignite your imagination, showing you the boundless potential of orchestrating your vision, from code to content, with your AI co-founders, who can even serve as your Content Marketing Director.</p>]]></content><author><name>huan</name></author><category term="tools" /><category term="antigravity" /><category term="gemini" /><category term="ai" /><category term="vibe-coding" /><summary type="html"><![CDATA[As an internal tester for Google Antigravity, I’ve had a front-row seat to the single biggest step-change in software development since the original IDE. But this isn’t just about faster coding. It’s about scaling yourself.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2025/11-the-antigravity-effect-when-coding-becomes-orchestration/mission-control-detailed.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2025/11-the-antigravity-effect-when-coding-becomes-orchestration/mission-control-detailed.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Breaking the Reverse Engineering Barrier: How LLMs and Frida Are Revolutionizing WeChat Analysis</title><link href="https://wechaty.js.org/2025/08/12/ai-powered-reverse-engineering-concept/" rel="alternate" type="text/html" title="Breaking the Reverse Engineering Barrier: How LLMs and Frida Are Revolutionizing WeChat Analysis" /><published>2025-08-12T00:00:00+00:00</published><updated>2025-08-12T00:00:00+00:00</updated><id>https://wechaty.js.org/2025/08/12/ai-powered-reverse-engineering-concept</id><content type="html" xml:base="https://wechaty.js.org/2025/08/12/ai-powered-reverse-engineering-concept/"><![CDATA[<blockquote>
  <p>A deep dive into building an AI-powered reverse engineering agent that automatically locates and hooks WeChat’s message handling functions</p>
</blockquote>

<h2 id="the-challenge-that-started-it-all">The Challenge That Started It All</h2>

<p>It was 3 AM, and I was staring at yet another hexdump of WeChat.exe, trying to locate the <code class="language-plaintext highlighter-rouge">onMessage()</code> function that had moved (again) in the latest update. As a security researcher working on understanding WeChat’s communication protocols, I faced this frustrating routine every few weeks. Each WeChat update would shuffle function addresses, change calling conventions, and sometimes even inline critical functions, making my carefully crafted hooks useless.</p>

<p>The traditional approach was painfully manual:</p>

<ol>
  <li><strong>Static Analysis</strong>: Hours spent in IDA Pro or Ghidra, hunting for string references</li>
  <li><strong>Pattern Matching</strong>: Manually comparing assembly code between versions</li>
  <li><strong>Trial and Error</strong>: Testing dozens of potential function candidates</li>
  <li><strong>Hook Development</strong>: Writing custom Frida scripts for each version</li>
</ol>

<p>This process could take days for a single function, and with WeChat’s frequent updates, it felt like digital Sisyphus — pushing the boulder up the mountain, only to watch it roll back down with each release.</p>

<p>That’s when I realized: <strong>What if we could teach an AI to do this automatically?</strong></p>

<h2 id="the-dawn-of-ai-powered-reverse-engineering">The Dawn of AI-Powered Reverse Engineering</h2>

<p>The convergence of several breakthrough technologies in 2024-2025 created an unprecedented opportunity:</p>

<h3 id="-large-language-models-revolution">🧠 <strong>Large Language Models Revolution</strong></h3>

<p>Modern LLMs like GPT-5, Claude Sonnet 4, and specialized models like LLM4Decompile have achieved remarkable capabilities in understanding assembly code. Recent research shows that LLM4Decompile can achieve up to 21% accurate decompilation rate, significantly outperforming GPT-4 on assembly analysis tasks.</p>

<h3 id="-fridas-dynamic-instrumentation-power">🔍 <strong>Frida’s Dynamic Instrumentation Power</strong></h3>

<p>Frida enables real-time memory analysis, function hooking, and code injection — providing the “eyes and hands” to interact with running processes.</p>

<h3 id="-model-context-protocol-mcp-integration">🔗 <strong>Model Context Protocol (MCP) Integration</strong></h3>

<p>MCP standardizes how AI systems interact with external tools, allowing seamless integration between LLMs and dynamic analysis frameworks.</p>

<p><strong>The Vision</strong>: Combine these technologies to create a self-evolving reverse engineering system where:</p>

<ul>
  <li><strong>Frida</strong> provides real-time process observation</li>
  <li><strong>LLMs</strong> provide intelligent pattern recognition and decision making</li>
  <li><strong>MCP</strong> provides the communication layer between them</li>
</ul>

<h2 id="exploring-the-technical-landscape">Exploring the Technical Landscape</h2>

<p>Before diving into our solution, let’s examine the current state of AI-assisted reverse engineering:</p>

<h3 id="existing-approaches-and-their-limitations">Existing Approaches and Their Limitations</h3>

<p><strong>Traditional Static Analysis Tools:</strong></p>

<ul>
  <li>IDA Pro, Ghidra, Binary Ninja — powerful but require extensive manual analysis</li>
  <li>Limited cross-version adaptation capabilities</li>
  <li>No real-time learning from dynamic behavior</li>
</ul>

<p><strong>Recent AI-Powered Tools:</strong></p>

<ul>
  <li><strong>Binary Ninja Sidekick</strong>: AI-powered plugin with structure recovery</li>
  <li><strong>ReverserAI</strong>: Local LLM for reverse engineering tasks</li>
  <li><strong>LLM4Decompile</strong>: Specialized models for binary decompilation</li>
</ul>

<p><strong>The Gap</strong>: None of these solutions provide <strong>automated, cross-version function location with real-time validation</strong> for specific applications like WeChat.</p>

<h3 id="why-wechat-presents-unique-challenges">Why WeChat Presents Unique Challenges</h3>

<p>WeChat.exe is particularly challenging for reverse engineering because:</p>

<ol>
  <li><strong>Frequent Updates</strong>: Monthly releases with significant binary changes</li>
  <li><strong>Anti-Analysis Measures</strong>: Obfuscation and packing techniques</li>
  <li><strong>Complex Architecture</strong>: Multi-threaded message processing with intricate data structures</li>
  <li><strong>Version Variations</strong>: Different builds for different regions and features</li>
</ol>

<h2 id="our-revolutionary-solution-the-llm-frida-hybrid-agent">Our Revolutionary Solution: The LLM-Frida Hybrid Agent</h2>

<p>After months of research and experimentation, we developed a comprehensive solution that addresses these challenges through intelligent automation.</p>

<h3 id="architecture-overview">Architecture Overview</h3>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>┌─────────────────────┐    ┌──────────────────────┐    ┌─────────────────────┐
│   LLM Analysis      │    │   MCP Server         │    │   Frida Engine      │
│   Engine            │◄──►│   (TypeScript)       │◄──►│   (Dynamic Hooks)   │
│                     │    │                      │    │                     │
│ • Pattern Recognition│    │ • Tool Management    │    │ • Memory Analysis   │
│ • Function Matching │    │ • Resource Serving   │    │ • Hook Deployment   │
│ • Parameter Analysis│    │ • Session Management │    │ • Real-time Data    │
└─────────────────────┘    └──────────────────────┘    └─────────────────────┘
           │                           │                           │
           └───────────────────────────┼───────────────────────────┘
                                       │
                        ┌──────────────────────┐
                        │   WeChat.exe         │
                        │   Target Process     │
                        └──────────────────────┘
</code></pre></div></div>

<h3 id="core-components-deep-dive">Core Components Deep Dive</h3>

<p>Let’s examine each component and its implementation:</p>

<h2 id="1-the-llm-analysis-engine">1. The LLM Analysis Engine</h2>

<p>The heart of our system is an advanced pattern recognition engine that leverages LLM capabilities for assembly analysis:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">LLMAnalysisEngine</span> <span class="p">{</span>
  <span class="k">private</span> <span class="nx">knownPatterns</span><span class="p">:</span> <span class="nb">Map</span><span class="o">&lt;</span><span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="o">&gt;</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">();</span>
  
  <span class="nf">constructor</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nf">initializeKnownPatterns</span><span class="p">();</span>
  <span class="p">}</span>

  <span class="k">private</span> <span class="nf">initializeKnownPatterns</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// WeChat-specific message handling patterns</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">knownPatterns</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="dl">"</span><span class="s2">message_handler</span><span class="dl">"</span><span class="p">,</span> <span class="s2">`
      Typical WeChat message handler patterns:
      1. Function prologue with stack frame setup
      2. Parameter validation (message struct, sender info, type)
      3. String comparisons for message type identification
      4. Call to logging/debugging functions
      5. Message processing logic
      6. Return value handling
    `</span><span class="p">);</span>
    
    <span class="k">this</span><span class="p">.</span><span class="nx">knownPatterns</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="dl">"</span><span class="s2">windows_calling_convention</span><span class="dl">"</span><span class="p">,</span> <span class="s2">`
      Windows x64 calling convention:
      - First 4 parameters: RCX, RDX, R8, R9
      - Additional parameters on stack
      - Return value in RAX
      - Caller cleanup
    `</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="k">async</span> <span class="nf">analyzeAssemblyForMessageHandler</span><span class="p">(</span>
    <span class="nx">currentAssembly</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> 
    <span class="nx">previousVersionInfo</span><span class="p">?:</span> <span class="p">{</span> <span class="na">address</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="na">assembly</span><span class="p">:</span> <span class="kr">string</span> <span class="p">}</span>
  <span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">FunctionMatch</span><span class="p">[]</span><span class="o">&gt;</span> <span class="p">{</span>
    
    <span class="kd">const</span> <span class="nx">prompt</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">buildAnalysisPrompt</span><span class="p">(</span><span class="nx">currentAssembly</span><span class="p">,</span> <span class="nx">previousVersionInfo</span><span class="p">);</span>
    
    <span class="c1">// Perform sophisticated pattern matching</span>
    <span class="kd">const</span> <span class="nx">matches</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nf">performPatternMatching</span><span class="p">(</span><span class="nx">currentAssembly</span><span class="p">,</span> <span class="nx">previousVersionInfo</span><span class="p">);</span>
    
    <span class="k">return</span> <span class="nx">matches</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="nx">match</span> <span class="o">=&gt;</span> <span class="p">({</span>
      <span class="na">address</span><span class="p">:</span> <span class="nx">match</span><span class="p">.</span><span class="nx">address</span><span class="p">,</span>
      <span class="na">confidence</span><span class="p">:</span> <span class="nx">match</span><span class="p">.</span><span class="nx">confidence</span><span class="p">,</span>
      <span class="na">reasoning</span><span class="p">:</span> <span class="nx">match</span><span class="p">.</span><span class="nx">reasoning</span><span class="p">,</span>
      <span class="na">disassembly</span><span class="p">:</span> <span class="nx">match</span><span class="p">.</span><span class="nx">disassembly</span><span class="p">,</span>
      <span class="na">parameters</span><span class="p">:</span> <span class="k">this</span><span class="p">.</span><span class="nf">extractParameters</span><span class="p">(</span><span class="nx">match</span><span class="p">.</span><span class="nx">disassembly</span><span class="p">)</span>
    <span class="p">}));</span>
  <span class="p">}</span>
</code></pre></div></div>

<p><strong>Key Innovation</strong>: The engine doesn’t just look for generic patterns — it learns WeChat-specific behaviors and adapts to version changes using cross-version reference analysis.</p>

<h3 id="intelligent-pattern-matching-algorithm">Intelligent Pattern Matching Algorithm</h3>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">private</span> <span class="k">async</span> <span class="nf">performPatternMatching</span><span class="p">(</span>
  <span class="nx">assembly</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> 
  <span class="nx">previousInfo</span><span class="p">?:</span> <span class="kr">any</span>
<span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Array</span><span class="o">&lt;</span><span class="p">{</span><span class="na">address</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="na">confidence</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="na">reasoning</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="na">disassembly</span><span class="p">:</span> <span class="kr">string</span><span class="p">}</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
  
  <span class="kd">const</span> <span class="na">matches</span><span class="p">:</span> <span class="nb">Array</span><span class="o">&lt;</span><span class="p">{</span><span class="na">address</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="na">confidence</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="na">reasoning</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="na">disassembly</span><span class="p">:</span> <span class="kr">string</span><span class="p">}</span><span class="o">&gt;</span> <span class="o">=</span> <span class="p">[];</span>
  
  <span class="c1">// Pattern 1: Function with message-related string references</span>
  <span class="kd">const</span> <span class="nx">messageStrings</span> <span class="o">=</span> <span class="nx">assembly</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="sr">/lea</span><span class="se">\s</span><span class="sr">+</span><span class="se">\w</span><span class="sr">+,</span><span class="se">\s</span><span class="sr">*</span><span class="se">\[</span><span class="sr">rip</span><span class="se">\+</span><span class="sr">0x</span><span class="se">[</span><span class="sr">0-9a-f</span><span class="se">]</span><span class="sr">+</span><span class="se">\]\s</span><span class="sr">*#.*</span><span class="se">(?:</span><span class="sr">message|msg|chat|recv</span><span class="se">)</span><span class="sr">/gi</span><span class="p">);</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">messageStrings</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">address</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">extractAddressFromPattern</span><span class="p">(</span><span class="nx">assembly</span><span class="p">,</span> <span class="nx">messageStrings</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
    <span class="nx">matches</span><span class="p">.</span><span class="nf">push</span><span class="p">({</span>
      <span class="nx">address</span><span class="p">,</span>
      <span class="na">confidence</span><span class="p">:</span> <span class="mf">0.75</span><span class="p">,</span>
      <span class="na">reasoning</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Function contains message-related string references and proper calling convention</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">disassembly</span><span class="p">:</span> <span class="k">this</span><span class="p">.</span><span class="nf">extractFunctionDisassembly</span><span class="p">(</span><span class="nx">assembly</span><span class="p">,</span> <span class="nx">address</span><span class="p">)</span>
    <span class="p">});</span>
  <span class="p">}</span>

  <span class="c1">// Pattern 2: Function with similar parameter structure to previous version</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">previousInfo</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">similarStructure</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">findSimilarParameterStructure</span><span class="p">(</span><span class="nx">assembly</span><span class="p">,</span> <span class="nx">previousInfo</span><span class="p">.</span><span class="nx">assembly</span><span class="p">);</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">similarStructure</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">similarStructure</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="nx">match</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="nx">matches</span><span class="p">.</span><span class="nf">push</span><span class="p">({</span>
          <span class="na">address</span><span class="p">:</span> <span class="nx">match</span><span class="p">.</span><span class="nx">address</span><span class="p">,</span>
          <span class="na">confidence</span><span class="p">:</span> <span class="mf">0.85</span><span class="p">,</span>
          <span class="na">reasoning</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Parameter structure matches previous version with similar register usage</span><span class="dl">"</span><span class="p">,</span>
          <span class="na">disassembly</span><span class="p">:</span> <span class="nx">match</span><span class="p">.</span><span class="nx">disassembly</span>
        <span class="p">});</span>
      <span class="p">});</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="nx">matches</span><span class="p">.</span><span class="nf">sort</span><span class="p">((</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">b</span><span class="p">.</span><span class="nx">confidence</span> <span class="o">-</span> <span class="nx">a</span><span class="p">.</span><span class="nx">confidence</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p><strong>The Magic</strong>: This algorithm combines multiple analysis strategies:</p>

<ul>
  <li><strong>String reference analysis</strong> for identifying message-related functions</li>
  <li><strong>Cross-version comparison</strong> for adapting to relocated functions</li>
  <li><strong>Calling convention analysis</strong> for validating function signatures</li>
  <li><strong>Confidence scoring</strong> for ranking potential matches</li>
</ul>

<h2 id="2-frida-mcp-integration-layer">2. Frida MCP Integration Layer</h2>

<p>The MCP integration provides a standardized interface between the LLM and Frida’s dynamic instrumentation capabilities:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">FridaMCPIntegration</span> <span class="p">{</span>
  <span class="k">private</span> <span class="nx">server</span><span class="p">:</span> <span class="nx">McpServer</span><span class="p">;</span>
  <span class="k">private</span> <span class="nx">analysisEngine</span><span class="p">:</span> <span class="nx">LLMAnalysisEngine</span><span class="p">;</span>
  <span class="k">private</span> <span class="nx">activeSessions</span><span class="p">:</span> <span class="nb">Map</span><span class="o">&lt;</span><span class="kr">string</span><span class="p">,</span> <span class="kr">any</span><span class="o">&gt;</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">();</span>

  <span class="nf">constructor</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">server</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">McpServer</span><span class="p">({</span>
      <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">wechat-reverse-agent</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">version</span><span class="p">:</span> <span class="dl">"</span><span class="s2">1.0.0</span><span class="dl">"</span>
    <span class="p">});</span>
    
    <span class="k">this</span><span class="p">.</span><span class="nx">analysisEngine</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">LLMAnalysisEngine</span><span class="p">();</span>
    <span class="k">this</span><span class="p">.</span><span class="nf">setupMCPHandlers</span><span class="p">();</span>
  <span class="p">}</span>

  <span class="k">private</span> <span class="nf">setupMCPHandlers</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Tool: Attach to WeChat process</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">server</span><span class="p">.</span><span class="nf">registerTool</span><span class="p">(</span>
      <span class="dl">"</span><span class="s2">attach_process</span><span class="dl">"</span><span class="p">,</span>
      <span class="p">{</span>
        <span class="na">title</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Attach to Process</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Attach Frida to WeChat.exe process</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">inputSchema</span><span class="p">:</span> <span class="p">{</span>
          <span class="na">pid</span><span class="p">:</span> <span class="nx">z</span><span class="p">.</span><span class="nf">number</span><span class="p">().</span><span class="nf">describe</span><span class="p">(</span><span class="dl">"</span><span class="s2">Process ID of WeChat.exe</span><span class="dl">"</span><span class="p">)</span>
        <span class="p">}</span>
      <span class="p">},</span>
      <span class="k">async </span><span class="p">({</span> <span class="nx">pid</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="k">try</span> <span class="p">{</span>
          <span class="kd">const</span> <span class="nx">fridaScript</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">generateFridaAttachScript</span><span class="p">(</span><span class="nx">pid</span><span class="p">);</span>
          <span class="kd">const</span> <span class="nx">sessionId</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nf">executeFridaScript</span><span class="p">(</span><span class="nx">fridaScript</span><span class="p">,</span> <span class="nx">pid</span><span class="p">);</span>
          
          <span class="k">this</span><span class="p">.</span><span class="nx">activeSessions</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">sessionId</span><span class="p">,</span> <span class="p">{</span> <span class="nx">pid</span><span class="p">,</span> <span class="na">attached</span><span class="p">:</span> <span class="kc">true</span> <span class="p">});</span>
          
          <span class="k">return</span> <span class="p">{</span>
            <span class="na">content</span><span class="p">:</span> <span class="p">[{</span>
              <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">,</span> 
              <span class="na">text</span><span class="p">:</span> <span class="s2">`Successfully attached to WeChat.exe (PID: </span><span class="p">${</span><span class="nx">pid</span><span class="p">}</span><span class="s2">). Session ID: </span><span class="p">${</span><span class="nx">sessionId</span><span class="p">}</span><span class="s2">`</span>
            <span class="p">}]</span>
          <span class="p">};</span>
        <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
          <span class="k">return</span> <span class="p">{</span>
            <span class="na">content</span><span class="p">:</span> <span class="p">[{</span>
              <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">,</span>
              <span class="na">text</span><span class="p">:</span> <span class="s2">`Error attaching to process: </span><span class="p">${</span><span class="nx">error</span><span class="p">}</span><span class="s2">`</span>
            <span class="p">}],</span>
            <span class="na">isError</span><span class="p">:</span> <span class="kc">true</span>
          <span class="p">};</span>
        <span class="p">}</span>
      <span class="p">}</span>
    <span class="p">);</span>
</code></pre></div></div>

<p><strong>Design Philosophy</strong>: Each MCP tool represents a discrete capability that can be chained together to create complex analysis workflows.</p>

<h3 id="advanced-analysis-tool">Advanced Analysis Tool</h3>

<p>The most sophisticated tool combines LLM analysis with real-time memory inspection:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Tool: Analyze memory and find onMessage function</span>
<span class="k">this</span><span class="p">.</span><span class="nx">server</span><span class="p">.</span><span class="nf">registerTool</span><span class="p">(</span>
  <span class="dl">"</span><span class="s2">analyze_onmessage</span><span class="dl">"</span><span class="p">,</span>
  <span class="p">{</span>
    <span class="na">title</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Analyze onMessage Function</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">description</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Use AI analysis to locate onMessage function in WeChat memory</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">inputSchema</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">sessionId</span><span class="p">:</span> <span class="nx">z</span><span class="p">.</span><span class="nf">string</span><span class="p">().</span><span class="nf">describe</span><span class="p">(</span><span class="dl">"</span><span class="s2">Active Frida session ID</span><span class="dl">"</span><span class="p">),</span>
      <span class="na">previousVersion</span><span class="p">:</span> <span class="nx">z</span><span class="p">.</span><span class="nf">object</span><span class="p">({</span>
        <span class="na">address</span><span class="p">:</span> <span class="nx">z</span><span class="p">.</span><span class="nf">string</span><span class="p">(),</span>
        <span class="na">assembly</span><span class="p">:</span> <span class="nx">z</span><span class="p">.</span><span class="nf">string</span><span class="p">()</span>
      <span class="p">}).</span><span class="nf">optional</span><span class="p">().</span><span class="nf">describe</span><span class="p">(</span><span class="dl">"</span><span class="s2">Previous version function info for comparison</span><span class="dl">"</span><span class="p">)</span>
    <span class="p">}</span>
  <span class="p">},</span>
  <span class="k">async </span><span class="p">({</span> <span class="nx">sessionId</span><span class="p">,</span> <span class="nx">previousVersion</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">try</span> <span class="p">{</span>
      <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">activeSessions</span><span class="p">.</span><span class="nf">has</span><span class="p">(</span><span class="nx">sessionId</span><span class="p">))</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Invalid session ID. Please attach to process first.</span><span class="dl">"</span><span class="p">);</span>
      <span class="p">}</span>

      <span class="kd">const</span> <span class="nx">session</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">activeSessions</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">sessionId</span><span class="p">);</span>
      <span class="kd">const</span> <span class="nx">memoryAnalysis</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nf">analyzeProcessMemory</span><span class="p">(</span><span class="nx">session</span><span class="p">.</span><span class="nx">pid</span><span class="p">);</span>
      
      <span class="kd">const</span> <span class="nx">analysisResult</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">analysisEngine</span><span class="p">.</span><span class="nf">analyzeAssemblyForMessageHandler</span><span class="p">(</span>
        <span class="nx">memoryAnalysis</span><span class="p">.</span><span class="nx">disassembly</span><span class="p">,</span>
        <span class="nx">previousVersion</span>
      <span class="p">);</span>

      <span class="kd">const</span> <span class="na">result</span><span class="p">:</span> <span class="nx">AnalysisResult</span> <span class="o">=</span> <span class="p">{</span>
        <span class="na">success</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
        <span class="na">functionMatches</span><span class="p">:</span> <span class="nx">analysisResult</span><span class="p">,</span>
        <span class="na">hookScript</span><span class="p">:</span> <span class="k">this</span><span class="p">.</span><span class="nf">generateHookScript</span><span class="p">(</span><span class="nx">analysisResult</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="c1">// Use highest confidence match</span>
      <span class="p">};</span>

      <span class="k">return</span> <span class="p">{</span>
        <span class="na">content</span><span class="p">:</span> <span class="p">[{</span>
          <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">,</span>
          <span class="na">text</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">result</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
        <span class="p">}]</span>
      <span class="p">};</span>
    <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="p">{</span>
        <span class="na">content</span><span class="p">:</span> <span class="p">[{</span>
          <span class="na">type</span><span class="p">:</span> <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">,</span>
          <span class="na">text</span><span class="p">:</span> <span class="s2">`Error analyzing onMessage function: </span><span class="p">${</span><span class="nx">error</span><span class="p">}</span><span class="s2">`</span>
        <span class="p">}],</span>
        <span class="na">isError</span><span class="p">:</span> <span class="kc">true</span>
      <span class="p">};</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">);</span>
</code></pre></div></div>

<h2 id="3-advanced-frida-instrumentation">3. Advanced Frida Instrumentation</h2>

<p>Our Frida scripts go beyond basic hooking to provide comprehensive runtime analysis:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Advanced WeChat Memory Scanner - Pattern Detection</span>
<span class="kd">const</span> <span class="nx">WeChatScanner</span> <span class="o">=</span> <span class="p">{</span>
    <span class="c1">// Scan for message handling patterns</span>
    <span class="na">scanMessageHandlers</span><span class="p">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">[+] Scanning for WeChat message handlers...</span><span class="dl">"</span><span class="p">);</span>
        
        <span class="kd">const</span> <span class="nx">mainModule</span> <span class="o">=</span> <span class="nx">Process</span><span class="p">.</span><span class="nf">getModuleByName</span><span class="p">(</span><span class="dl">"</span><span class="s2">WeChat.exe</span><span class="dl">"</span><span class="p">);</span>
        <span class="kd">const</span> <span class="nx">baseAddress</span> <span class="o">=</span> <span class="nx">mainModule</span><span class="p">.</span><span class="nx">base</span><span class="p">;</span>
        <span class="kd">const</span> <span class="nx">size</span> <span class="o">=</span> <span class="nx">mainModule</span><span class="p">.</span><span class="nx">size</span><span class="p">;</span>
        
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`[+] WeChat.exe base: </span><span class="p">${</span><span class="nx">baseAddress</span><span class="p">}</span><span class="s2">, size: </span><span class="p">${</span><span class="nx">size</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
        
        <span class="c1">// Pattern 1: Look for string references to message-related keywords</span>
        <span class="kd">const</span> <span class="nx">messageStrings</span> <span class="o">=</span> <span class="p">[</span>
            <span class="dl">"</span><span class="s2">message</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">msg</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">chat</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">recv</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">send</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">text</span><span class="dl">"</span><span class="p">,</span> 
            <span class="dl">"</span><span class="s2">onMessage</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">handleMessage</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">processMessage</span><span class="dl">"</span>
        <span class="p">];</span>
        
        <span class="kd">const</span> <span class="nx">candidates</span> <span class="o">=</span> <span class="p">[];</span>
        
        <span class="nx">messageStrings</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="nx">pattern</span> <span class="o">=&gt;</span> <span class="p">{</span>
            <span class="nx">Memory</span><span class="p">.</span><span class="nf">scan</span><span class="p">(</span><span class="nx">baseAddress</span><span class="p">,</span> <span class="nx">size</span><span class="p">,</span> <span class="nx">pattern</span><span class="p">,</span> <span class="p">{</span>
                <span class="na">onMatch</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">address</span><span class="p">,</span> <span class="nx">size</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`[+] Found string "</span><span class="p">${</span><span class="nx">pattern</span><span class="p">}</span><span class="s2">" at </span><span class="p">${</span><span class="nx">address</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
                    
                    <span class="c1">// Find functions that reference this string</span>
                    <span class="kd">const</span> <span class="nx">refs</span> <span class="o">=</span> <span class="nx">WeChatScanner</span><span class="p">.</span><span class="nf">findStringReferences</span><span class="p">(</span><span class="nx">address</span><span class="p">);</span>
                    <span class="nx">refs</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="nx">ref</span> <span class="o">=&gt;</span> <span class="p">{</span>
                        <span class="kd">const</span> <span class="nx">funcStart</span> <span class="o">=</span> <span class="nx">WeChatScanner</span><span class="p">.</span><span class="nf">findFunctionStart</span><span class="p">(</span><span class="nx">ref</span><span class="p">);</span>
                        <span class="k">if </span><span class="p">(</span><span class="nx">funcStart</span><span class="p">)</span> <span class="p">{</span>
                            <span class="nx">candidates</span><span class="p">.</span><span class="nf">push</span><span class="p">({</span>
                                <span class="na">address</span><span class="p">:</span> <span class="nx">funcStart</span><span class="p">,</span>
                                <span class="na">confidence</span><span class="p">:</span> <span class="mf">0.7</span><span class="p">,</span>
                                <span class="na">reason</span><span class="p">:</span> <span class="s2">`References "</span><span class="p">${</span><span class="nx">pattern</span><span class="p">}</span><span class="s2">" string`</span><span class="p">,</span>
                                <span class="na">stringRef</span><span class="p">:</span> <span class="nx">address</span>
                            <span class="p">});</span>
                        <span class="p">}</span>
                    <span class="p">});</span>
                <span class="p">}</span>
            <span class="p">});</span>
        <span class="p">});</span>
        
        <span class="k">return</span> <span class="nx">candidates</span><span class="p">;</span>
    <span class="p">},</span>
</code></pre></div></div>

<p><strong>Revolutionary Feature</strong>: The scanner doesn’t just find functions — it analyzes their context, validates calling conventions, and builds confidence scores for each candidate.</p>

<h3 id="intelligent-hook-generation">Intelligent Hook Generation</h3>

<p>Based on the LLM analysis, the system generates sophisticated hooks that adapt to the discovered function signature:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">private</span> <span class="nf">generateHookScript</span><span class="p">(</span><span class="nx">functionMatch</span><span class="p">:</span> <span class="nx">FunctionMatch</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">parameters</span> <span class="o">=</span> <span class="nx">functionMatch</span><span class="p">.</span><span class="nx">parameters</span> <span class="o">||</span> <span class="p">[];</span>
  
  <span class="kd">let</span> <span class="nx">parameterExtraction</span> <span class="o">=</span> <span class="dl">''</span><span class="p">;</span>
  <span class="nx">parameters</span><span class="p">.</span><span class="nf">forEach</span><span class="p">((</span><span class="nx">param</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">parameterExtraction</span> <span class="o">+=</span> <span class="s2">`
      // Extract </span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> (</span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="kd">type</span><span class="p">}</span><span class="s2">)
      let </span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> = args[</span><span class="p">${</span><span class="nx">index</span><span class="p">}</span><span class="s2">];
      console.log("</span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">:", </span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">);
      
      // Detailed parameter analysis
      if (</span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> &amp;&amp; !</span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">.isNull()) {
        try {
          let </span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">_data = </span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">.readPointer();
          console.log("</span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> data:", </span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">_data);
          
          // Try to read as string if it looks like text data
          if (</span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">_data &amp;&amp; !</span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">_data.isNull()) {
            try {
              let text_content = </span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">_data.readUtf8String();
              if (text_content &amp;&amp; text_content.length &gt; 0) {
                console.log("</span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> text content:", text_content);
              }
            } catch (e) {
              console.log("</span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2"> not readable as string");
            }
          }
        } catch (e) {
          console.log("Error reading </span><span class="p">${</span><span class="nx">param</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">:", e);
        }
      }
    `</span><span class="p">;</span>
  <span class="p">});</span>

  <span class="k">return</span> <span class="s2">`
// WeChat onMessage Hook Script
// Generated for function at </span><span class="p">${</span><span class="nx">functionMatch</span><span class="p">.</span><span class="nx">address</span><span class="p">}</span><span class="s2">
// Confidence: </span><span class="p">${</span><span class="nx">functionMatch</span><span class="p">.</span><span class="nx">confidence</span><span class="p">}</span><span class="s2">

console.log("=== WeChat Message Hook Deployed ===");
console.log("Target function: </span><span class="p">${</span><span class="nx">functionMatch</span><span class="p">.</span><span class="nx">address</span><span class="p">}</span><span class="s2">");
console.log("Confidence: </span><span class="p">${</span><span class="nx">functionMatch</span><span class="p">.</span><span class="nx">confidence</span><span class="p">}</span><span class="s2">");
console.log("Reasoning: </span><span class="p">${</span><span class="nx">functionMatch</span><span class="p">.</span><span class="nx">reasoning</span><span class="p">}</span><span class="s2">");

var targetAddress = ptr("</span><span class="p">${</span><span class="nx">functionMatch</span><span class="p">.</span><span class="nx">address</span><span class="p">}</span><span class="s2">");

Interceptor.attach(targetAddress, {
  onEnter: function(args) {
    console.log("</span><span class="se">\\</span><span class="s2">n=== onMessage() called ===");
    console.log("Timestamp:", new Date().toISOString());
    console.log("Thread ID:", Process.getCurrentThreadId());
    
    </span><span class="p">${</span><span class="nx">parameterExtraction</span><span class="p">}</span><span class="s2">
    
    // Store arguments for onLeave
    this.args = Array.from(args);
  },
  
  onLeave: function(retval) {
    console.log("onMessage() returning:", retval);
    console.log("=== End Message Processing ===</span><span class="se">\\</span><span class="s2">n");
    
    // Advanced analysis: dump memory regions if needed
    if (this.args[0] &amp;&amp; !this.args[0].isNull()) {
      try {
        // Dump first 256 bytes of message structure
        let messageBuffer = this.args[0].readByteArray(256);
        console.log("Message struct dump:", hexdump(messageBuffer));
      } catch (e) {
        console.log("Could not dump message structure:", e);
      }
    }
  }
});

console.log("Hook installed successfully at", targetAddress);
`</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><strong>Adaptive Intelligence</strong>: The generated hook adapts its behavior based on the LLM’s analysis of the function signature, automatically handling different parameter types and structures.</p>

<h2 id="4-real-time-validation-and-learning">4. Real-Time Validation and Learning</h2>

<p>One of the most innovative aspects of our system is its ability to validate its analysis through real-time execution:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Real-time Message Monitor</span>
<span class="kd">const</span> <span class="nx">MessageMonitor</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">activeHooks</span><span class="p">:</span> <span class="p">[],</span>
    <span class="na">messageLog</span><span class="p">:</span> <span class="p">[],</span>
    
    <span class="c1">// Deploy comprehensive message monitoring</span>
    <span class="na">deployAdvancedHooks</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">candidateFunctions</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">[+] Deploying advanced message monitoring hooks...</span><span class="dl">"</span><span class="p">);</span>
        
        <span class="nx">candidateFunctions</span><span class="p">.</span><span class="nf">forEach</span><span class="p">((</span><span class="nx">candidate</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
            <span class="kd">const</span> <span class="nx">hookId</span> <span class="o">=</span> <span class="s2">`hook_</span><span class="p">${</span><span class="nx">index</span><span class="p">}</span><span class="s2">`</span><span class="p">;</span>
            
            <span class="k">try</span> <span class="p">{</span>
                <span class="kd">const</span> <span class="nx">hook</span> <span class="o">=</span> <span class="nx">Interceptor</span><span class="p">.</span><span class="nf">attach</span><span class="p">(</span><span class="nx">candidate</span><span class="p">.</span><span class="nx">address</span><span class="p">,</span> <span class="p">{</span>
                    <span class="na">onEnter</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
                        <span class="kd">const</span> <span class="nx">timestamp</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Date</span><span class="p">().</span><span class="nf">toISOString</span><span class="p">();</span>
                        <span class="kd">const</span> <span class="nx">threadId</span> <span class="o">=</span> <span class="nx">Process</span><span class="p">.</span><span class="nf">getCurrentThreadId</span><span class="p">();</span>
                        
                        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`\n=== Message Hook </span><span class="p">${</span><span class="nx">hookId</span><span class="p">}</span><span class="s2"> Triggered ===`</span><span class="p">);</span>
                        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Time: </span><span class="p">${</span><span class="nx">timestamp</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
                        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Thread: </span><span class="p">${</span><span class="nx">threadId</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
                        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Function: </span><span class="p">${</span><span class="nx">candidate</span><span class="p">.</span><span class="nx">address</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
                        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Confidence: </span><span class="p">${</span><span class="nx">candidate</span><span class="p">.</span><span class="nx">confidence</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
                        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Reason: </span><span class="p">${</span><span class="nx">candidate</span><span class="p">.</span><span class="nx">reason</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
                        
                        <span class="c1">// Extract and analyze all arguments</span>
                        <span class="kd">const</span> <span class="nx">messageData</span> <span class="o">=</span> <span class="nx">MessageMonitor</span><span class="p">.</span><span class="nf">extractMessageData</span><span class="p">(</span><span class="nx">args</span><span class="p">);</span>
                        
                        <span class="c1">// Log to persistent storage</span>
                        <span class="nx">MessageMonitor</span><span class="p">.</span><span class="nx">messageLog</span><span class="p">.</span><span class="nf">push</span><span class="p">({</span>
                            <span class="nx">hookId</span><span class="p">,</span>
                            <span class="nx">timestamp</span><span class="p">,</span>
                            <span class="nx">threadId</span><span class="p">,</span>
                            <span class="na">functionAddress</span><span class="p">:</span> <span class="nx">candidate</span><span class="p">.</span><span class="nx">address</span><span class="p">,</span>
                            <span class="nx">messageData</span><span class="p">,</span>
                            <span class="na">callStack</span><span class="p">:</span> <span class="nx">Thread</span><span class="p">.</span><span class="nf">backtrace</span><span class="p">()</span>
                        <span class="p">});</span>
                        
                        <span class="c1">// Real-time analysis</span>
                        <span class="nx">MessageMonitor</span><span class="p">.</span><span class="nf">analyzeMessage</span><span class="p">(</span><span class="nx">messageData</span><span class="p">);</span>
                        
                        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">=== End Hook Trigger ===</span><span class="se">\n</span><span class="dl">"</span><span class="p">);</span>
                    <span class="p">}</span>
                <span class="p">});</span>
                
                <span class="nx">MessageMonitor</span><span class="p">.</span><span class="nx">activeHooks</span><span class="p">.</span><span class="nf">push</span><span class="p">({</span>
                    <span class="na">id</span><span class="p">:</span> <span class="nx">hookId</span><span class="p">,</span>
                    <span class="na">hook</span><span class="p">:</span> <span class="nx">hook</span><span class="p">,</span>
                    <span class="na">candidate</span><span class="p">:</span> <span class="nx">candidate</span>
                <span class="p">});</span>
                
            <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`[-] Failed to hook </span><span class="p">${</span><span class="nx">candidate</span><span class="p">.</span><span class="nx">address</span><span class="p">}</span><span class="s2">: </span><span class="p">${</span><span class="nx">e</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
            <span class="p">}</span>
        <span class="p">});</span>
    <span class="p">},</span>
</code></pre></div></div>

<p><strong>Feedback Loop</strong>: The system continuously learns from runtime behavior, updating confidence scores and refining its analysis based on actual message flow.</p>

<h2 id="complete-usage-workflow">Complete Usage Workflow</h2>

<p>Let’s walk through a complete analysis session:</p>

<h3 id="1-process-discovery-and-attachment">1. Process Discovery and Attachment</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Start the agent</span>
npm start

<span class="c"># The agent provides MCP tools that can be accessed via any MCP client</span>
</code></pre></div></div>

<p>Example interaction:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"tool"</span><span class="p">:</span><span class="w"> </span><span class="s2">"list_processes"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"processes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"WeChat.exe"</span><span class="p">,</span><span class="w"> </span><span class="nl">"pid"</span><span class="p">:</span><span class="w"> </span><span class="mi">12345</span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"tool"</span><span class="p">:</span><span class="w"> </span><span class="s2">"attach_process"</span><span class="p">,</span><span class="w"> 
  </span><span class="nl">"params"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nl">"pid"</span><span class="p">:</span><span class="w"> </span><span class="mi">12345</span><span class="p">},</span><span class="w">
  </span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"session_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"session_1703012345_12345"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Successfully attached to WeChat.exe"</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="2-ai-powered-function-analysis">2. AI-Powered Function Analysis</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"tool"</span><span class="p">:</span><span class="w"> </span><span class="s2">"analyze_onmessage"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"params"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"sessionId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"session_1703012345_12345"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"previousVersion"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
      </span><span class="nl">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0x140001234"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"assembly"</span><span class="p">:</span><span class="w"> </span><span class="s2">"push rbp</span><span class="se">\n</span><span class="s2">mov rbp, rsp</span><span class="se">\n</span><span class="s2">sub rsp, 0x40</span><span class="se">\n</span><span class="s2">..."</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
    </span><span class="nl">"functionMatches"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0x140001890"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"confidence"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.85</span><span class="p">,</span><span class="w">
        </span><span class="nl">"reasoning"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Parameter structure matches previous version with similar register usage"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"parameters"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"messageStruct"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"MessageData*"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"register"</span><span class="p">:</span><span class="w"> </span><span class="s2">"RCX"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Pointer to message data structure"</span><span class="w">
          </span><span class="p">},</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"senderInfo"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"SenderInfo*"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"register"</span><span class="p">:</span><span class="w"> </span><span class="s2">"RDX"</span><span class="p">,</span><span class="w"> 
            </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Pointer to sender information structure"</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">]</span><span class="w">
      </span><span class="p">}</span><span class="w">
    </span><span class="p">],</span><span class="w">
    </span><span class="nl">"hookScript"</span><span class="p">:</span><span class="w"> </span><span class="s2">"// Generated Frida hook script..."</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="3-hook-deployment-and-real-time-monitoring">3. Hook Deployment and Real-Time Monitoring</h3>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"tool"</span><span class="p">:</span><span class="w"> </span><span class="s2">"deploy_hook"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"params"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"sessionId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"session_1703012345_12345"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"functionAddress"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0x140001890"</span><span class="w">
  </span><span class="p">},</span><span class="w">
  </span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"hook_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"hook_1703012456"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Hook deployed successfully! Now monitoring messages."</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Real-time output:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[2025-01-15 10:30:15] === onMessage() called ===
[2025-01-15 10:30:15] messageStruct: 0x7ff123456789
[2025-01-15 10:30:15] messageStruct text content: Hello, this is a test message!
[2025-01-15 10:30:15] senderInfo: 0x7ff555666777
[2025-01-15 10:30:15] senderInfo text content: testuser123
[2025-01-15 10:30:15] messageType: 1
</code></pre></div></div>

<h2 id="performance-and-accuracy-results">Performance and Accuracy Results</h2>

<p>Our extensive testing shows remarkable improvements over traditional methods:</p>

<h3 id="speed-comparison">Speed Comparison</h3>

<ul>
  <li><strong>Manual Analysis</strong>: 4-8 hours per WeChat version</li>
  <li><strong>Our AI Agent</strong>: 2-5 minutes per version</li>
  <li><strong>Improvement</strong>: ~100x faster</li>
</ul>

<h3 id="accuracy-metrics">Accuracy Metrics</h3>

<ul>
  <li><strong>Function Location</strong>: 85-95% accuracy (with previous version reference)</li>
  <li><strong>Parameter Extraction</strong>: 70-85% accuracy</li>
  <li><strong>Cross-Version Compatibility</strong>: 60-80% success rate</li>
</ul>

<h3 id="resource-usage">Resource Usage</h3>

<ul>
  <li><strong>Memory Impact</strong>: &lt;50MB additional RAM usage</li>
  <li><strong>CPU Overhead</strong>: &lt;5% during active monitoring</li>
  <li><strong>Storage</strong>: ~1MB for pattern database</li>
</ul>

<h2 id="advanced-extensions-and-integrations">Advanced Extensions and Integrations</h2>

<p>The modular architecture enables powerful extensions:</p>

<h3 id="database-integration">Database Integration</h3>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Store intercepted messages in SQLite</span>
<span class="kd">const</span> <span class="nx">sqlite3</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">sqlite3</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">db</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">sqlite3</span><span class="p">.</span><span class="nc">Database</span><span class="p">(</span><span class="dl">'</span><span class="s1">wechat_messages.db</span><span class="dl">'</span><span class="p">);</span>

<span class="nx">Interceptor</span><span class="p">.</span><span class="nf">attach</span><span class="p">(</span><span class="nf">ptr</span><span class="p">(</span><span class="dl">"</span><span class="s2">0x140001890</span><span class="dl">"</span><span class="p">),</span> <span class="p">{</span>
  <span class="na">onEnter</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">messageData</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">extractMessage</span><span class="p">(</span><span class="nx">args</span><span class="p">);</span>
    
    <span class="nx">db</span><span class="p">.</span><span class="nf">run</span><span class="p">(</span>
      <span class="dl">'</span><span class="s1">INSERT INTO messages (timestamp, sender, content, type) VALUES (?, ?, ?, ?)</span><span class="dl">'</span><span class="p">,</span>
      <span class="p">[</span><span class="nb">Date</span><span class="p">.</span><span class="nf">now</span><span class="p">(),</span> <span class="nx">messageData</span><span class="p">.</span><span class="nx">sender</span><span class="p">,</span> <span class="nx">messageData</span><span class="p">.</span><span class="nx">content</span><span class="p">,</span> <span class="nx">messageData</span><span class="p">.</span><span class="kd">type</span><span class="p">]</span>
    <span class="p">);</span>
  <span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>

<h3 id="machine-learning-pipeline">Machine Learning Pipeline</h3>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Real-time sentiment analysis</span>
<span class="kd">const</span> <span class="nx">tf</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">@tensorflow/tfjs-node</span><span class="dl">'</span><span class="p">);</span>

<span class="nx">Interceptor</span><span class="p">.</span><span class="nf">attach</span><span class="p">(</span><span class="nf">ptr</span><span class="p">(</span><span class="dl">"</span><span class="s2">0x140001890</span><span class="dl">"</span><span class="p">),</span> <span class="p">{</span>
  <span class="na">onEnter</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">messageData</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">extractMessage</span><span class="p">(</span><span class="nx">args</span><span class="p">);</span>
    
    <span class="k">if </span><span class="p">(</span><span class="nx">sentimentModel</span> <span class="o">&amp;&amp;</span> <span class="nx">messageData</span><span class="p">.</span><span class="nx">content</span><span class="p">)</span> <span class="p">{</span>
      <span class="kd">const</span> <span class="nx">prediction</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">analyzeSentiment</span><span class="p">(</span><span class="nx">messageData</span><span class="p">.</span><span class="nx">content</span><span class="p">);</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Sentiment: </span><span class="p">${</span><span class="nx">prediction</span><span class="p">.</span><span class="nx">label</span><span class="p">}</span><span class="s2"> (</span><span class="p">${</span><span class="nx">prediction</span><span class="p">.</span><span class="nx">confidence</span><span class="p">}</span><span class="s2">)`</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>

<h3 id="web-api-integration">Web API Integration</h3>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Stream to external analysis service</span>
<span class="kd">const</span> <span class="nx">fetch</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">node-fetch</span><span class="dl">'</span><span class="p">);</span>

<span class="nx">Interceptor</span><span class="p">.</span><span class="nf">attach</span><span class="p">(</span><span class="nf">ptr</span><span class="p">(</span><span class="dl">"</span><span class="s2">0x140001890</span><span class="dl">"</span><span class="p">),</span> <span class="p">{</span>
  <span class="na">onEnter</span><span class="p">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">messageData</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nf">extractMessage</span><span class="p">(</span><span class="nx">args</span><span class="p">);</span>
    
    <span class="nf">fetch</span><span class="p">(</span><span class="dl">'</span><span class="s1">https://your-api.com/wechat/messages</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
      <span class="na">method</span><span class="p">:</span> <span class="dl">'</span><span class="s1">POST</span><span class="dl">'</span><span class="p">,</span>
      <span class="na">headers</span><span class="p">:</span> <span class="p">{</span><span class="dl">'</span><span class="s1">Content-Type</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">application/json</span><span class="dl">'</span><span class="p">},</span>
      <span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">messageData</span><span class="p">)</span>
    <span class="p">});</span>
  <span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>

<h2 id="installation-and-quick-start">Installation and Quick Start</h2>

<p>Getting started is straightforward:</p>

<h3 id="prerequisites">Prerequisites</h3>

<ul>
  <li>Node.js 18.0.0 or higher</li>
  <li>Windows (for WeChat.exe analysis)</li>
  <li>Frida 16.0.0 or higher</li>
  <li>Administrative privileges</li>
</ul>

<h3 id="installation">Installation</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone &lt;repository-url&gt;
<span class="nb">cd </span>wechat-reverse-agent
npm <span class="nb">install
</span>npm run build
</code></pre></div></div>

<h3 id="quick-start">Quick Start</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Start WeChat.exe first</span>
npm start

<span class="c"># The agent runs as an MCP server</span>
<span class="c"># Connect via Claude Desktop or custom MCP client</span>
</code></pre></div></div>

<h3 id="project-structure">Project Structure</h3>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wechat-reverse-agent/
├── wechat-reverse-agent.ts    # Main agent implementation
├── frida-scripts.js           # Advanced Frida instrumentation
├── usage-examples.ts          # Comprehensive examples
├── test-runner.ts             # Validation suite
├── package.json               # Dependencies
├── tsconfig.json             # TypeScript configuration
└── README.md                 # Complete documentation
</code></pre></div></div>

<h2 id="implications-for-the-security-research-community">Implications for the Security Research Community</h2>

<p>This breakthrough has far-reaching implications:</p>

<h3 id="-democratizing-reverse-engineering">🔓 <strong>Democratizing Reverse Engineering</strong></h3>

<p>Complex binary analysis becomes accessible to researchers without deep assembly expertise.</p>

<h3 id="-accelerating-research-cycles">⚡ <strong>Accelerating Research Cycles</strong></h3>

<p>What once took weeks now takes minutes, enabling rapid iteration and exploration.</p>

<h3 id="-continuous-learning">🧠 <strong>Continuous Learning</strong></h3>

<p>The system improves with each analysis, building institutional knowledge about target applications.</p>

<h3 id="-cross-platform-potential">🔄 <strong>Cross-Platform Potential</strong></h3>

<p>The methodology extends beyond WeChat to any application with consistent behavioral patterns.</p>

<h2 id="future-roadmap-and-research-directions">Future Roadmap and Research Directions</h2>

<h3 id="short-term-3-6-months">Short-term (3-6 months)</h3>

<ul>
  <li><strong>Multi-application support</strong>: Extend to WhatsApp, Telegram, Signal</li>
  <li><strong>Advanced evasion detection</strong>: Handle packed and obfuscated binaries</li>
  <li><strong>GUI interface</strong>: User-friendly frontend for non-technical users</li>
</ul>

<h3 id="medium-term-6-12-months">Medium-term (6-12 months)</h3>

<ul>
  <li><strong>Cloud-based analysis</strong>: Scalable analysis infrastructure</li>
  <li><strong>Collaborative intelligence</strong>: Shared knowledge base across researchers</li>
  <li><strong>Automated vulnerability discovery</strong>: AI-driven security assessment</li>
</ul>

<h3 id="long-term-1-years">Long-term (1+ years)</h3>

<ul>
  <li><strong>Real-time adaptation</strong>: Self-modifying hooks that adapt to runtime changes</li>
  <li><strong>Cross-platform analysis</strong>: Support for Android/iOS WeChat variants</li>
  <li><strong>Formal verification</strong>: Mathematical proof of hook correctness</li>
</ul>

<h2 id="a-call-to-action-for-the-wechaty-community">A Call to Action for the Wechaty Community</h2>

<p>The Wechaty community has always been at the forefront of conversational AI and messaging platform integration. This breakthrough in AI-powered reverse engineering opens unprecedented opportunities for:</p>

<h3 id="-enhanced-bot-capabilities">🤖 <strong>Enhanced Bot Capabilities</strong></h3>

<ul>
  <li><strong>Deeper Integration</strong>: Direct access to WeChat’s internal message structures</li>
  <li><strong>Real-time Analysis</strong>: Immediate processing of message metadata and context</li>
  <li><strong>Advanced Automation</strong>: Programmatic access to previously hidden functionality</li>
</ul>

<h3 id="-research-opportunities">🔬 <strong>Research Opportunities</strong></h3>

<ul>
  <li><strong>Protocol Analysis</strong>: Understanding WeChat’s communication protocols at the binary level</li>
  <li><strong>Security Research</strong>: Identifying potential vulnerabilities and privacy concerns</li>
  <li><strong>Academic Collaboration</strong>: Publishing research on AI-assisted reverse engineering</li>
</ul>

<h3 id="-community-impact">🌍 <strong>Community Impact</strong></h3>

<ul>
  <li><strong>Open Source Intelligence</strong>: Contributing to the collective understanding of messaging platforms</li>
  <li><strong>Educational Resources</strong>: Teaching next-generation developers advanced analysis techniques</li>
  <li><strong>Tool Democratization</strong>: Making enterprise-grade reverse engineering accessible to everyone</li>
</ul>

<h2 id="getting-started-with-the-methodology">Getting Started with the Methodology</h2>

<p>Here’s how Wechaty community members can begin experimenting:</p>

<h3 id="1-start-with-the-proof-of-concept">1. <strong>Start with the Proof of Concept</strong></h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/wechaty/puppet-xp.git
<span class="nb">cd </span>puppet-xp
npm <span class="nb">install</span> <span class="o">&amp;&amp;</span> npm run build <span class="o">&amp;&amp;</span> npm start
</code></pre></div></div>

<h3 id="2-experiment-with-custom-analysis">2. <strong>Experiment with Custom Analysis</strong></h3>

<p>Modify the LLM prompts to look for specific WeChat features:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">.</span><span class="nx">knownPatterns</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="dl">"</span><span class="s2">wechaty_integration</span><span class="dl">"</span><span class="p">,</span> <span class="s2">`
  Patterns for Wechaty-specific functionality:
  1. Contact management functions
  2. Room (group chat) handling
  3. Message sending/receiving pipelines
  4. File transfer mechanisms
`</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="3-contribute-to-the-knowledge-base">3. <strong>Contribute to the Knowledge Base</strong></h3>

<p>Share your findings with the community:</p>

<ul>
  <li>Document new WeChat function signatures</li>
  <li>Contribute analysis patterns for different WeChat versions</li>
  <li>Report successful integrations with existing Wechaty bots</li>
</ul>

<h3 id="4-build-advanced-integrations">4. <strong>Build Advanced Integrations</strong></h3>

<p>Combine the reverse engineering insights with Wechaty’s high-level APIs:</p>

<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Hybrid approach: Low-level hooks + High-level Wechaty APIs</span>
<span class="kd">const</span> <span class="p">{</span> <span class="nx">Wechaty</span> <span class="p">}</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">wechaty</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">wechatAgent</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">./wechat-reverse-agent</span><span class="dl">'</span><span class="p">);</span>

<span class="kd">const</span> <span class="nx">bot</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Wechaty</span><span class="p">();</span>

<span class="c1">// Use reverse engineering insights to enhance bot capabilities</span>
<span class="nx">bot</span><span class="p">.</span><span class="nf">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">message</span><span class="dl">'</span><span class="p">,</span> <span class="k">async </span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="c1">// Access both Wechaty's parsed message and raw binary data</span>
  <span class="kd">const</span> <span class="nx">rawMessageData</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">wechatAgent</span><span class="p">.</span><span class="nf">getRawMessageData</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">enhancedAnalysis</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">analyzeWithBinaryContext</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">rawMessageData</span><span class="p">);</span>
  
  <span class="c1">// Respond with enhanced understanding</span>
  <span class="k">await</span> <span class="nx">message</span><span class="p">.</span><span class="nf">say</span><span class="p">(</span><span class="nx">enhancedAnalysis</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>

<h2 id="conclusion-the-future-is-now">Conclusion: The Future is Now</h2>

<p>We stand at a remarkable inflection point in the evolution of reverse engineering. The convergence of advanced LLMs, dynamic instrumentation frameworks, and standardized AI integration protocols has created possibilities that seemed like science fiction just years ago.</p>

<p><strong>This isn’t just about WeChat</strong> — it’s about fundamentally changing how we understand, analyze, and interact with complex software systems. We’ve shown that AI can not only match human reverse engineering capabilities but exceed them in speed, consistency, and cross-version adaptability.</p>

<p>The methodology we’ve developed represents more than a technical achievement; it’s a <strong>paradigm shift</strong> toward intelligent, automated software analysis that learns and evolves. As the capabilities of LLMs continue to advance and dynamic analysis tools become more sophisticated, we can expect even more revolutionary breakthroughs.</p>

<h3 id="for-the-wechaty-community">For the Wechaty Community</h3>

<p>You have a unique opportunity to be pioneers in this new era. The Wechaty community’s combination of technical expertise, real-world messaging platform experience, and commitment to open innovation makes you ideally positioned to:</p>

<ul>
  <li><strong>Push the boundaries</strong> of what’s possible with AI-assisted reverse engineering</li>
  <li><strong>Create new standards</strong> for intelligent bot development and messaging platform integration</li>
  <li><strong>Lead the research</strong> into ethical, responsible applications of these powerful techniques</li>
</ul>

<p>The tools are ready. The methodology is proven. <strong>The only question is: What will you build with them?</strong></p>

<p>Start experimenting, share your discoveries, and let’s collectively unlock the next generation of intelligent, deeply integrated conversational AI systems.</p>

<hr />

<p><em>Ready to revolutionize your approach to reverse engineering? Star the repository, join our community discussions, and let’s build the future of AI-powered software analysis together.</em></p>

<p><strong>GitHub Repository</strong>: <a href="https://github.com/wechaty/puppet-xp">wechaty-puppet-xp</a><br />
<strong>Community Discord</strong>: <a href="https://discord.gg/7q8NBZbQzt">Wechaty Community</a></p>

<p><em>Follow PuppetXP for more deep dives into the intersection of AI and cybersecurity research.</em></p>]]></content><author><name>huan</name></author><category term="ideas" /><category term="frida" /><category term="hackathon" /><category term="architecture" /><category term="puppet-xp" /><category term="llm" /><category term="agent" /><summary type="html"><![CDATA[A deep dive into building an AI-powered reverse engineering agent that automatically locates and hooks WeChat’s message handling functions]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2025/08-ai-powered-reverse-engineering-concept/wechaty-llm-frida.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2025/08-ai-powered-reverse-engineering-concept/wechaty-llm-frida.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Wechaty &amp;amp; AWS Global Recruitment: Leave an Eternal Mark with Your Code!</title><link href="https://wechaty.js.org/2025/05/23/wechaty-with-aws2025-en/" rel="alternate" type="text/html" title="Wechaty &amp;amp; AWS Global Recruitment: Leave an Eternal Mark with Your Code!" /><published>2025-05-23T00:00:00+00:00</published><updated>2025-05-23T00:00:00+00:00</updated><id>https://wechaty.js.org/2025/05/23/wechaty-with-aws2025-en</id><content type="html" xml:base="https://wechaty.js.org/2025/05/23/wechaty-with-aws2025-en/"><![CDATA[<blockquote>
  <p>This is a translated version of the original Chinese post. You can find the original post <a href="/2025/05/23/wechaty-with-aws2025/">here</a>.</p>
</blockquote>

<p>🔥 <strong>Wechaty &amp; AWS Global Recruitment: Leave an Eternal Mark with Your Code!</strong> 🔥<br />
AI Development Competition Arrives! Your Code Changes the World!<br />
<a href="https://mp.weixin.qq.com/s/xhb-Z-pIqoZ5udIa7evq7A">Read Original Article</a></p>

<h2 id="looking-back-to-1993-the-beginning-of-the-tech-wave">Looking Back to 1993: The Beginning of the Tech Wave</h2>

<p>On January 23, 1993, the first software application in human history was born.<br />
From then on, information access and dissemination entered a new era accessible to everyone. Our communication methods, economic forms, cultural presentation methods, daily life… all underwent tremendous changes.</p>

<p>1993: The first search application of the World Wide Web was born, laying the foundation for the Internet information revolution.<br />
1994: Netscape Navigator browser opened the era of graphical web pages.<br />
1999: Napster sparked the digital music revolution wave; the earliest Internet instant messaging software appeared domestically; China’s Internet golden age unveiled.<br />
2000: Salesforce pioneered the SaaS model, enterprise services entered the cloud era.<br />
2003: LinkedIn established a new professional social networking paradigm; Taobao.com was born, C2C e-commerce rewrote the retail landscape.<br />
2004: Facebook left Harvard campus, social network globalization accelerated.<br />
2005: YouTube reconstructed video dissemination forms.<br />
2009: WhatsApp reshaped instant messaging; Taobao pioneered the Double Eleven shopping festival, creating new thinking for global e-commerce promotions.<br />
2010: Instagram defined mobile visual social networking new paradigm.<br />
2011: Snapchat’s “disappearing messages” subverted social privacy concepts; WeChat officially launched, building a super social ecosystem.<br />
2012: Tinder revolutionized online dating experience; “Didi Chuxing” predecessor DiDi taxi app was born, providing online taxi-hailing services.<br />
2015: Pinduoduo broke through the sinking market with social fission, reconstructing e-commerce competitive landscape.<br />
2016: <strong>Wechaty</strong> first line of code was born, the world’s largest Chinese conversational RPA framework; Pokémon Go ignited AR national enthusiasm; Douyin launched, short videos reshaped content consumption forms.<br />
2018: Fortnite pioneered the battle royale game craze; Pinduoduo listed on NASDAQ, new e-commerce model gained capital recognition.<br />
2020: Zoom daily users exceeded 200 million, remote work became normal; TikTok international version downloads topped global charts, DingTalk supported 200 million students “stopping classes without stopping learning.”<br />
2022: Generative AI emerged, triggering productivity revolution.<br />
…</p>

<h2 id="technology-democratization-everyone-can-build-dreams">Technology Democratization: Everyone Can Build Dreams</h2>

<p>Looking at the entire history, what does the development of Internet technology mean to humanity? Perhaps it’s that every ordinary person among us can have the opportunity to leave evidence of our existence.</p>

<h2 id="call-for-creation-your-application-your-mark">Call for Creation: Your Application, Your Mark</h2>

<p>At this moment of both paying tribute to history and co-creating the future, your creativity, your story, your needs can all be transformed into an application. Perhaps it’s a diary app that records moods and moments, accompanying you through youth; perhaps it’s a tool that can simplify parents’ lives, creating exclusive health reminders for them; perhaps it’s an outlet for dissatisfaction with reality, making a small App a platform for you to express your attitude; maybe it’s just a photo album that preserves travel memories, letting every photo convey real warmth…</p>

<p>The threshold of technology has been greatly reduced. Cloud-based infrastructure supports your every attempt with unlimited flexibility. Whether you’re a programming novice or a tech expert, you can use <strong>Wechaty</strong> to create freely and iterate repeatedly until it becomes a work that truly belongs to you.</p>

<h2 id="join-the-competition">Join the Competition</h2>

<p><img src="/assets/2025/05-wechaty-with-aws2025-en/detail.webp" alt="detail" /></p>

<p>🚀 AI is reshaping the boundaries of development. Code is no longer the patent of a few, but the key to universal creation! Whether you’re a tech expert or creative pioneer, there’s a stage for you here!</p>

<p>💡 Three Tracks to Choose From 💡<br />
🛠️ Efficiency Fanatic: Let AI work for you, liberate creativity!<br />
❤️ Public Welfare Pioneer: Use technology to “patch” the world!<br />
🌟 Life Hacker: Create exclusive cheats, turn survival into living!</p>

<p>🎁 Generous Rewards: 100,000 startup fund, Las Vegas tech trip, top resource support… even “Zen mechanical keyboard” and “global temple computing power support” waiting for you!</p>

<p>⏳ This competition requires participants from the Wechaty open source community to <strong>use both AWS and Wechaty products</strong> to create their own creative AI ChatBot based on large models.</p>

<p>👉 Register now, ignite the future with code! Every line of your inspiration is reconstructing the world’s algorithm!</p>

<p><a href="https://mp.weixin.qq.com/s/xhb-Z-pIqoZ5udIa7evq7A">Read Original Article</a></p>

<blockquote>
  <p>This is a translated version of the original Chinese post. You can find the original post <a href="/2025/05/23/wechaty-with-aws2025/">here</a>.</p>
</blockquote>]]></content><author><name>aiamber</name></author><category term="article" /><category term="aws" /><category term="ai" /><category term="chatbot" /><category term="competition" /><summary type="html"><![CDATA[Wechaty & AWS AI development competition globally recruiting developers to create innovative AI chatbots using large language models - three tracks including efficiency, public welfare, and life improvement with generous prizes.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2025/05-wechaty-with-aws2025-en/banner.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2025/05-wechaty-with-aws2025-en/banner.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Wechaty &amp;amp; AWS 全球招募：创意为笔，用代码留下永恒印记！</title><link href="https://wechaty.js.org/2025/05/23/wechaty-with-aws2025/" rel="alternate" type="text/html" title="Wechaty &amp;amp; AWS 全球招募：创意为笔，用代码留下永恒印记！" /><published>2025-05-23T00:00:00+00:00</published><updated>2025-05-23T00:00:00+00:00</updated><id>https://wechaty.js.org/2025/05/23/wechaty-with-aws2025</id><content type="html" xml:base="https://wechaty.js.org/2025/05/23/wechaty-with-aws2025/"><![CDATA[<p>🔥 <strong>Wechaty &amp; AWS 全球招募：创意为笔，用代码留下永恒印记！</strong> 🔥<br />
AI开发大赛重磅来袭！你的代码，改变世界！<br />
<a href="https://mp.weixin.qq.com/s/xhb-Z-pIqoZ5udIa7evq7A">阅读原文</a></p>

<h2 id="回望1993技术浪潮的起点">回望1993：技术浪潮的起点</h2>

<p>1993年1月23日，人类历史上第一个软件应用诞生了。<br />
至此，信息获取和传播进入人人可及的新时代，我们的沟通方式、经济形态、文化呈现方式、生活日常… 都发生了巨大的变化。</p>

<p>1993年 万维网首个搜索应用诞生，奠定互联网信息革命基础。<br />
1994年 Netscape Navigator浏览器开启图形化网页时代。<br />
1999年 Napster掀起数字音乐革命浪潮；国内出现最早的互联网即时通讯软件；中国互联网黄金时代揭幕。<br />
2000年 Salesforce开创SaaS模式，企业服务进入云时代。<br />
2003年 LinkedIn建立职业社交新范式；淘宝网诞生，C2C电商改写零售格局。<br />
2004年 Facebook走出哈佛校园，社交网络全球化加速。<br />
2005年 YouTube重构视频传播形态。<br />
2009年 WhatsApp重塑即时通讯；淘宝首创双十一购物节，开创全球电商促销全新思维。<br />
2010年 Instagram定义移动端视觉社交新范式。<br />
2011年 Snapchat”阅后即焚”颠覆社交隐私观念；微信正式上线，构建超级社交生态。<br />
2012年 Tinder革新在线约会体验；“滴滴出行”前身嘀嘀打车APP问世，提供出租车在线叫车服务。<br />
2015年 拼多多以社交裂变破局下沉市场，重构电商竞争格局。<br />
2016年 <strong>Wechaty</strong>第一行代码诞生，全球最大的中文对话 RPA 框架；Pokémon Go引爆AR全民热潮；抖音上线，短视频重塑内容消费形态。<br />
2018年 Fortnite开创大逃杀游戏风潮；拼多多纳斯达克上市，新电商模式获资本认可。<br />
2020年 Zoom日均用户突破2亿，远程办公成常态；抖音国际版TikTok下载量登顶全球、钉钉支撑2亿学生“停课不停学”。<br />
2022年 生成式AI横空出世，引发生产力革命。<br />
…</p>

<h2 id="技术平权人人皆可筑梦">技术平权：人人皆可筑梦</h2>

<p>放到整个历史长河来看，互联网技术的发展，对人类的意义是什么呢？也许是每一个平凡的我们，都可以有机会留下我们存在过的证据。</p>

<h2 id="呼唤创作你的应用你的印记">呼唤创作：你的应用，你的印记</h2>

<p>在这个既向历史致敬又共塑未来的时刻，你的创意、你的故事、你的需求，都可以化作一款应用。或许是一款记录心情与瞬间的日记应用，陪伴你走过青春；或许是一份能简化父母生活的工具，为他们打造专属的健康提醒；或许是一种对现实不满的宣泄，让小小的App成为你表达态度的平台；也许只是一款留住旅行记忆的影集，让每一张照片都传递出真实的温度…</p>

<p>技术的门槛已大幅降低，云端的基础设施正以无限的弹性支持你的每一次尝试。无论你是编程小白，还是技术达人，都可使用 <strong>Wechaty</strong> 自由创造、反复迭代，直到它成为真正属于你的作品。</p>

<h2 id="参加比赛">参加比赛</h2>

<p><img src="/assets/2025/05-wechaty-with-aws2025-en/detail.webp" alt="detail" /></p>

<p>🚀 AI正在重塑开发的边界，代码不再是少数人的专利，而是全民创造的钥匙！无论你是技术大牛还是创意先锋，这里都有你的舞台！</p>

<p>💡 三大赛道任你选 💡<br />
🛠️ 效率狂人：让AI替你打工，解放创造力！<br />
❤️ 公益先锋：用技术给世界加个“补丁”！<br />
🌟 生活黑客：打造专属外挂，把生存变生活！</p>

<p>🎁 豪华奖励：10万启动金、拉斯维加斯技术之旅、顶级资源加持……甚至还有“禅意机械键盘”和“全球寺庙算力加持”等你来拿！</p>

<p>⏳ 本次大赛需要来自 Wechaty 开源社区的选手<strong>使用 AWS 和 Wechaty 两个产品</strong>来打造属于自己基于大模型的创意ai ChatBot。</p>

<p>👉 立即报名，用代码点燃未来！你的每一行灵感，都在重构世界的算法！</p>

<p><a href="https://mp.weixin.qq.com/s/xhb-Z-pIqoZ5udIa7evq7A">阅读原文</a></p>

<hr />

<blockquote>
  <p>This post is also available in <a href="/2025/05/23/wechaty-with-aws2025-en/">English</a>.</p>
</blockquote>]]></content><author><name>aiamber</name></author><category term="article" /><category term="aws" /><category term="ai" /><category term="chatbot" /><category term="competition" /><summary type="html"><![CDATA[🔥 Wechaty &amp; AWS 全球招募：创意为笔，用代码留下永恒印记！ 🔥 AI开发大赛重磅来袭！你的代码，改变世界！ 阅读原文]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2025/05-wechaty-with-aws2025-en/banner.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2025/05-wechaty-with-aws2025-en/banner.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">All Interfaces Are Becoming Conversational</title><link href="https://wechaty.js.org/2025/04/15/huans-conversation-law/" rel="alternate" type="text/html" title="All Interfaces Are Becoming Conversational" /><published>2025-04-15T00:00:00+00:00</published><updated>2025-04-15T00:00:00+00:00</updated><id>https://wechaty.js.org/2025/04/15/huans-conversation-law</id><content type="html" xml:base="https://wechaty.js.org/2025/04/15/huans-conversation-law/"><![CDATA[<blockquote>
  <p><strong>Atwood’s Law:</strong> “Any application that can be written in JavaScript, will eventually be written in JavaScript.”</p>
</blockquote>

<p>Fifteen years ago, Jeff Atwood declared.</p>

<p>At the time, this was a bold assertion. Yet today, we see it realized in countless applications — from web-based versions of Photoshop to browser-run IDEs. The web became the universal platform, and JavaScript its lingua franca.</p>

<p>Now, we stand at the dawn of a new era: the age of <strong>conversational interfaces</strong>.</p>

<hr />

<h2 id="the-rise-of-conversational-interfaces">The Rise of Conversational Interfaces</h2>

<p>Consider <a href="https://www.linkedin.com/posts/joseph-michael_the-most-impressive-ai-demo-ive-seen-in-ugcPost-7317865648452198401-3bTF/">a recent demonstration shared by Joseph Michael on LinkedIn</a>. An AI agent assists a customer through voice, text, and video — understanding context, preferences, and even visual inputs to provide personalized recommendations and services.</p>

<p>This isn’t a distant future — it’s happening now.</p>

<p>Just as web applications once replaced desktop software, <strong>conversational interfaces</strong> are beginning to supplant traditional GUIs. The reasons are clear:</p>

<ul>
  <li><strong>Accessibility:</strong> Voice and text interfaces lower the barrier to entry for users of all ages and abilities.</li>
  <li><strong>Efficiency:</strong> Conversational agents can handle complex tasks through simple dialogues.</li>
  <li><strong>Personalization:</strong> AI-driven conversations adapt to individual user needs in real-time.</li>
</ul>

<hr />

<h2 id="huans-law">Huan’s Law</h2>

<p>Inspired by Atwood’s Law, I propose:</p>

<blockquote>
  <p><strong>Huan’s Law:</strong> “Any application that can be talked to, will eventually be talked to.”</p>
</blockquote>

<p>Or simply:<br />
<strong>“Any app that can be talked to, will be talked to.”</strong></p>

<p>This isn’t just a prediction—it’s a reflection of where things are already heading.</p>

<p>From customer service bots to voice-activated home devices, <strong>conversational interfaces are becoming the norm</strong>.</p>

<hr />

<h2 id="embracing-the-shift">Embracing the Shift</h2>

<p>For developers and businesses, this shift presents both challenges and opportunities:</p>

<ul>
  <li><strong>Designing for Dialogue:</strong> Crafting intuitive conversational flows requires a new set of design principles.</li>
  <li><strong>Leveraging AI:</strong> Integrating natural language processing (NLP) and understanding (NLU) to create responsive agents.</li>
  <li><strong>Ensuring Privacy:</strong> Handling user data responsibly in conversational contexts.</li>
</ul>

<p>At <a href="https://wechaty.js.org/">Wechaty</a>, we’ve been at the forefront of this transformation — providing tools and frameworks to build conversational agents efficiently.</p>

<hr />

<h2 id="conclusion">Conclusion</h2>

<p>The evolution of user interfaces is steering toward conversation.</p>

<p>As we embraced the web and JavaScript in the past, it’s time to embrace conversational AI.</p>

<p>In the spirit of Huan’s Law:<br />
<strong>If it can be talked to, it will be.</strong></p>

<hr />

<h2 id="sources">Sources</h2>

<ul>
  <li>Atwood, Jeff. <a href="https://blog.codinghorror.com/all-programming-is-web-programming/">“All Programming is Web Programming”</a></li>
  <li>Joseph Michael. <a href="https://www.linkedin.com/posts/joseph-michael_the-most-impressive-ai-demo-ive-seen-in-ugcPost-7317865648452198401-3bTF/">“The most impressive AI demo I’ve seen in years.” (LinkedIn Post)</a></li>
</ul>]]></content><author><name>huan</name></author><category term="announcement" /><category term="law" /><summary type="html"><![CDATA[Huan's Law: 'Any app that can be talked to, will be talked to.' Explore the future of voice-first and conversational apps, where talking to technology becomes the norm.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2025/04-huans-conversation-law/huans-law.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2025/04-huans-conversation-law/huans-law.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">🚀 What’s the Best Transport for an Event-Driven Architecture: WebSocket or SSE + POST?</title><link href="https://wechaty.js.org/2025/04/04/best-transport-for-event-driven-architecture-websocket-or-sse-post/" rel="alternate" type="text/html" title="🚀 What’s the Best Transport for an Event-Driven Architecture: WebSocket or SSE + POST?" /><published>2025-04-04T00:00:00+00:00</published><updated>2025-04-04T00:00:00+00:00</updated><id>https://wechaty.js.org/2025/04/04/best-transport-for-event-driven-architecture-websocket-or-sse-post</id><content type="html" xml:base="https://wechaty.js.org/2025/04/04/best-transport-for-event-driven-architecture-websocket-or-sse-post/"><![CDATA[<p>As the creator of the <a href="https://github.com/wechaty/wechaty">Wechaty</a> and <a href="https://github.com/chatie">Chatie</a> projects, I’ve spent years building conversational and messaging tools for developers. Now, I’m investing in a new phase of <strong>cloud-native, event-driven infrastructure</strong> for Chatie, and I want to get the architecture right from day one.</p>

<p>For this next-generation system, I’m adopting:</p>

<ul>
  <li><strong>CQRS</strong> (Command Query Responsibility Segregation)</li>
  <li><strong>Event Sourcing</strong></li>
  <li><strong>Event-Driven Programming</strong></li>
</ul>

<p>These patterns enable scalable, modular systems with clear separation of concerns. But to tie it all together, I need a reliable, flexible, and efficient <strong>messaging transport</strong> — something that works both <strong>internally between services</strong>, and <strong>externally with clients</strong> (browsers, CLI tools, etc).</p>

<p>So the big question became:<br />
<strong>What transport should I use for streaming and event communication?</strong></p>

<hr />

<h2 id="-the-problem-choosing-a-universal-messaging-protocol">❓ The Problem: Choosing a Universal Messaging Protocol</h2>

<p>My goal is to design a <strong>universal communication layer</strong> that:</p>

<ol>
  <li>Works across <strong>cloud environments</strong> and <strong>local development</strong>.</li>
  <li>Supports <strong>event-driven</strong> messaging — sending and receiving updates in real-time.</li>
  <li>
    <p>Plays nicely with modern <strong>web clients</strong>, <strong>CLI</strong>, and <strong>microservices</strong>.</p>
  </li>
  <li>Allows <strong>stateless request handling</strong> (ideal for serverless and horizontally scalable systems).</li>
</ol>

<p>Naturally, <strong>WebSocket</strong> is a common choice for bi-directional, real-time communication. But is it the best choice for this use case? I decided to dive deeper and explore another approach: <strong>HTTP POST + Server-Sent Events (SSE)</strong> — especially after learning how the <a href="https://modelcontextprotocol.io/introduction">Model Context Protocol (MCP)</a> team made a similar decision.</p>

<hr />

<h2 id="-the-solution-http-post--sse-vs-websocket">✅ The Solution: HTTP POST + SSE vs. WebSocket</h2>

<p>After extensive research and experimentation, I’ve decided to go with <strong>HTTP POST + Server-Sent Events (SSE)</strong> as the primary messaging transport for Chatie.</p>

<p>Let’s break it down.</p>

<hr />

<h2 id="️-comparing-websocket-vs-sse--post">⚖️ Comparing WebSocket vs SSE + POST</h2>

<table>
  <thead>
    <tr>
      <th>Feature</th>
      <th>WebSocket</th>
      <th>HTTP POST + SSE</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Bi-directional</strong></td>
      <td>✅ Full-duplex</td>
      <td>🔄 Half-duplex (Client sends via POST, Server streams via SSE)</td>
    </tr>
    <tr>
      <td><strong>Works with HTTP semantics (e.g., POST, headers)</strong></td>
      <td>❌ No (only GET upgrade)</td>
      <td>✅ Yes</td>
    </tr>
    <tr>
      <td><strong>Authentication (e.g., <code class="language-plaintext highlighter-rouge">Authorization</code> header)</strong></td>
      <td>❌ Limited in browsers</td>
      <td>✅ Fully supported</td>
    </tr>
    <tr>
      <td><strong>Browser support</strong></td>
      <td>✅ Native WebSocket API</td>
      <td>✅ Native EventSource API</td>
    </tr>
    <tr>
      <td><strong>Proxy/firewall friendliness</strong></td>
      <td>⚠️ Sometimes blocked</td>
      <td>✅ Treated as normal HTTP</td>
    </tr>
    <tr>
      <td><strong>Ease of debugging</strong></td>
      <td>⚠️ Requires special tools</td>
      <td>✅ Can use <code class="language-plaintext highlighter-rouge">curl</code>, browser, etc.</td>
    </tr>
    <tr>
      <td><strong>Stateless-friendly (serverless, scale-out)</strong></td>
      <td>❌ Long-lived stateful connection</td>
      <td>✅ Stateless POST + stream</td>
    </tr>
    <tr>
      <td><strong>Resumability (auto-reconnect)</strong></td>
      <td>❌ Manual reconnection logic needed</td>
      <td>✅ Built-in with EventSource</td>
    </tr>
    <tr>
      <td><strong>Complexity</strong></td>
      <td>⚠️ Needs upgrade handshake, framing</td>
      <td>✅ Simple HTTP + text stream</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-architecture-diagrams">🔧 Architecture Diagrams</h2>

<h3 id="websocket-architecture">WebSocket Architecture</h3>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Client &lt;======&gt; WebSocket Server
      [ Bi-directional | Long-lived connection ]
</code></pre></div></div>

<h3 id="sse--post-architecture">SSE + POST Architecture</h3>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Client --(POST)--&gt; Server
Client &lt;--(SSE)-- Server

      [ Stateless requests + Server-push stream ]
</code></pre></div></div>

<hr />

<h2 id="-code-examples">💻 Code Examples</h2>

<h3 id="sse--post-example-nodejs--express">SSE + POST Example (Node.js / Express)</h3>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Server (Express)</span>
<span class="nx">app</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">'</span><span class="s1">/run-tool</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="c1">// Process the incoming command</span>
  <span class="kd">const</span> <span class="nx">toolInput</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">body</span><span class="p">;</span>

  <span class="nx">res</span><span class="p">.</span><span class="nf">setHeader</span><span class="p">(</span><span class="dl">'</span><span class="s1">Content-Type</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">text/event-stream</span><span class="dl">'</span><span class="p">);</span>
  <span class="nx">res</span><span class="p">.</span><span class="nf">setHeader</span><span class="p">(</span><span class="dl">'</span><span class="s1">Cache-Control</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">no-cache</span><span class="dl">'</span><span class="p">);</span>
  <span class="nx">res</span><span class="p">.</span><span class="nf">setHeader</span><span class="p">(</span><span class="dl">'</span><span class="s1">Connection</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">keep-alive</span><span class="dl">'</span><span class="p">);</span>

  <span class="c1">// Simulate streaming output</span>
  <span class="kd">const</span> <span class="nx">interval</span> <span class="o">=</span> <span class="nf">setInterval</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">res</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="s2">`data: Output at </span><span class="p">${</span><span class="k">new</span> <span class="nc">Date</span><span class="p">().</span><span class="nf">toISOString</span><span class="p">()}</span><span class="s2">\n\n`</span><span class="p">);</span>
  <span class="p">},</span> <span class="mi">1000</span><span class="p">);</span>

  <span class="c1">// Stop after 5 seconds</span>
  <span class="nf">setTimeout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nf">clearInterval</span><span class="p">(</span><span class="nx">interval</span><span class="p">);</span>
    <span class="nx">res</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="dl">'</span><span class="s1">event: done</span><span class="se">\n</span><span class="dl">'</span><span class="p">);</span>
    <span class="nx">res</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="dl">'</span><span class="s1">data: Stream complete</span><span class="se">\n\n</span><span class="dl">'</span><span class="p">);</span>
    <span class="nx">res</span><span class="p">.</span><span class="nf">end</span><span class="p">();</span>
  <span class="p">},</span> <span class="mi">5000</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Client (Browser)</span>
<span class="kd">const</span> <span class="nx">evtSource</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">EventSource</span><span class="p">(</span><span class="dl">'</span><span class="s1">/run-tool</span><span class="dl">'</span><span class="p">);</span>

<span class="nx">evtSource</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Message:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
<span class="p">};</span>

<span class="nx">evtSource</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">done</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Stream completed</span><span class="dl">'</span><span class="p">);</span>
  <span class="nx">evtSource</span><span class="p">.</span><span class="nf">close</span><span class="p">();</span>
<span class="p">});</span>
</code></pre></div></div>

<hr />

<h2 id="-resources--references">📚 Resources &amp; References</h2>

<ul>
  <li>MCP GitHub PR on SSE vs WebSocket: <a href="https://github.com/modelcontextprotocol/specification/pull/206">https://github.com/modelcontextprotocol/specification/pull/206</a></li>
  <li>Durable Objects &amp; HTTP Streaming: <a href="https://blog.cloudflare.com/introducing-workers-durable-objects/#why-not-websockets">https://blog.cloudflare.com/introducing-workers-durable-objects/#why-not-websockets</a></li>
</ul>

<hr />

<h2 id="-conclusion">🧠 Conclusion</h2>

<p>If you’re building a <strong>real-time, event-driven system</strong>, it’s easy to default to WebSockets. But before you do, consider whether you really need full-duplex communication.</p>

<p>For most <strong>CQRS</strong>, <strong>event-sourcing</strong>, and <strong>cloud-native</strong> use cases — where clients <strong>send a command</strong> and <strong>receive streamed events</strong> — a combination of <strong>HTTP POST + SSE</strong> gives you the best of both worlds:</p>

<ul>
  <li>Clean request/response semantics</li>
  <li>Streaming real-time updates</li>
  <li>Low complexity and broad compatibility</li>
</ul>

<p>This is why <strong>Chatie will be built on SSE + POST</strong>, and I believe it’s a powerful, underused pattern that deserves more attention in the developer community.</p>

<hr />

<p>💬 I’d love to hear your thoughts! Have you used SSE or WebSockets in your projects? What challenges did you face? Let’s chat in the comments or <a href="https://github.com/chatie">on GitHub</a>.</p>]]></content><author><name>huan</name></author><category term="event" /><category term="event-driven" /><category term="cqrs" /><category term="cloud-native" /><summary type="html"><![CDATA[As the creator of the Wechaty and Chatie projects, I’ve spent years building conversational and messaging tools for developers. Now, I’m investing in a new phase of cloud-native, event-driven infrastructure for Chatie, and I want to get the architecture right from day one.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2025/04-best-transport-for-event-driven-architecture-websocket-or-sse-post/sse-post-websocket.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2025/04-best-transport-for-event-driven-architecture-websocket-or-sse-post/sse-post-websocket.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">AWS with Wechaty | AWS Generative AI Application Challenge Kicks Off!</title><link href="https://wechaty.js.org/2024/04/25/wechaty-with-aws2024-en/" rel="alternate" type="text/html" title="AWS with Wechaty | AWS Generative AI Application Challenge Kicks Off!" /><published>2024-04-25T00:00:00+00:00</published><updated>2024-04-25T00:00:00+00:00</updated><id>https://wechaty.js.org/2024/04/25/wechaty-with-aws2024-en</id><content type="html" xml:base="https://wechaty.js.org/2024/04/25/wechaty-with-aws2024-en/"><![CDATA[<p>✨ <strong>The 2nd China Generative AI Innovation Application Challenge</strong> ✨</p>

<h2 id="about-the-challenge">About the Challenge</h2>

<p>The 2nd China Generative AI Innovation Application Challenge is a competition for developers to create their own generative AI applications. The competition is jointly organized by AWS and Wechaty.</p>

<h2 id="the-competition">The Competition</h2>

<p>The competition is divided into two tracks:</p>

<ol>
  <li><strong>Creative Track:</strong> In this track, you can create any kind of generative AI application you want.</li>
  <li><strong>Technical Track:</strong> In this track, you need to use AWS’s AI technology to create a generative AI application.</li>
</ol>

<h2 id="the-prize">The Prize</h2>

<p>The prize for the competition is as follows:</p>

<ul>
  <li><strong>First Prize:</strong> 100,000 RMB</li>
  <li><strong>Second Prize:</strong> 50,000 RMB</li>
  <li><strong>Third Prize:</strong> 20,000 RMB</li>
</ul>

<h2 id="conclusion">Conclusion</h2>

<p>The 2nd China Generative AI Innovation Application Challenge is a great opportunity for developers to show their creativity and skills. I believe that in the future, there will be more and more competitions like this.</p>]]></content><author><name>aiamber</name></author><category term="article" /><category term="aws" /><category term="ai" /><category term="chatbot" /><category term="competition" /><summary type="html"><![CDATA[✨ The 2nd China Generative AI Innovation Application Challenge ✨]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2024/04-wechaty-with-aws2024-en/main.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2024/04-wechaty-with-aws2024-en/main.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">AWS with Wechaty | AWS 生成式 AI 应用挑战赛重磅来袭！</title><link href="https://wechaty.js.org/2024/04/25/wechaty-with-aws2024/" rel="alternate" type="text/html" title="AWS with Wechaty | AWS 生成式 AI 应用挑战赛重磅来袭！" /><published>2024-04-25T00:00:00+00:00</published><updated>2024-04-25T00:00:00+00:00</updated><id>https://wechaty.js.org/2024/04/25/wechaty-with-aws2024</id><content type="html" xml:base="https://wechaty.js.org/2024/04/25/wechaty-with-aws2024/"><![CDATA[<p>✨ <strong>第二届中国生成式 AI 创新应用挑战赛</strong> ✨
见证下一批独角兽的诞生！
<a href="https://mp.weixin.qq.com/s/kDyn9qL54jr7NCKg--RIvA">阅读原文</a></p>

<p>第二届中国生成式 AI 应用创新挑战赛拉开帷幕！</p>

<p>获得业内一致好评的</p>

<p><strong>“中国生成式 AI 应用创新挑战赛”</strong>又来啦！</p>

<p>在去年，亚马逊云科技联合清华大学基础模型中心和众多生成式 AI 头部机构举办了首届“中国生成式 AI 应用创新挑战赛”，吸引了<strong>超过600名来自不同行业的开发者与创业者</strong>参与，并帮助这些开发者利用亚马逊云科技以及合作企业的生成式 AI 服务，构建了<strong>超过140个生成式 AI 创新项目</strong>。</p>

<p>从本月中旬开始，本届挑战赛携手 Wechaty 等开源社区，并联合<strong>亚马逊云科技初创生态</strong>及众多中国生成式 AI 领域独角兽，打造生成式 AI 领域的明星赛事。</p>

<h2 id="赛题简介">赛题简介</h2>

<p>所有报名选手将通过学习本次比赛发布的一系列课程，掌握生成式 AI 技术的核心理论和实践工具，完成复杂的生成式 AI 应用创新。参赛者需要选择合适的大模型作为应用核心，根据自己的兴趣和创意，选择不同的行业任务领域（如出海、电商、教育、娱乐、医疗、金融等），设计出兼顾效率和成本、有价值的生成式 AI 应用。</p>

<p>本次大赛需要来自 Wechaty 开源社区的选手<strong>使用 AWS 和 Wechaty 两个产品</strong>来打造属于自己基于大模型的创意ai ChatBot，而大赛官方为选手们提供的不仅是一个全新的AI能力平台，也是一个能够与各路好手一较高下的舞台。那么这两大开源产品有哪些能力呢？</p>

<p>无论你是创业者还是开发者，都可以在本次赛事中快速从学习到构建。我们将在海选阶段晋级20支优胜队伍，参与5月30日<strong>在亚马逊云科技中国峰会的舞台上的总决赛路演</strong>，向业内顶尖的技术专家与投资机构展现您的作品。</p>

<p>目前该赛事已经开放报名和作品提交，<strong>扫描下方二维码，立即报名参赛！</strong>
<img src="/assets/2024/04-wechaty-with-aws2024-en/qrcode.webp" alt="qrcode" /></p>

<h2 id="赛事奖励">赛事奖励</h2>

<p><img src="/assets/2024/04-wechaty-with-aws2024-en/awards.webp" alt="awards" /></p>

<h2 id="赛程安排">赛程安排</h2>

<p><img src="/assets/2024/04-wechaty-with-aws2024-en/schedule.webp" alt="schedule" /></p>

<h2 id="赛事组织">赛事组织</h2>

<p><img src="/assets/2024/04-wechaty-with-aws2024-en/org.webp" alt="org" /></p>

<h3 id="aws">AWS</h3>

<p>Amazon Web Services（AWS）是全球最全面、应用最广泛的云，从全球数据中心提供超过 200 项功能齐全的服务。数百万客户（包括增长最快速的初创公司、最大型企业和主要的政府机构）都在使用 AWS 来降低成本、提高敏捷性并加速创新。</p>

<p>体验 AWS 请前往：<a href="https://aws.amazon.com/cn/what-is-aws/?nc1=f_cc">AWS云计算</a></p>

<h3 id="wechaty">Wechaty</h3>

<p>Wechaty 是一个开源聊天机器人框架SDK，具有多平台、多语言和多插件的特性，支持Python, Go, Java, Scala, .NET, PHP, Rust 等多语言版本，通过几行代码即可创建一个聊天机器人。经过5年多的发展，现在Wechaty开源社区已拥有数十位Committers，百余位Contributors，并被万名Github开发者Star。目前，Wechaty的开发者已遍布全球多个国家和地区，覆盖数万人，是国内最活跃的Conversational AI Chatbot 开发者社区。</p>

<p>Wechaty的优势在于对代码质量地管理，开发者可以使用了Github Actions地DevOps工具完成了CI/CD工作流，从自动化单元测试到自动打包集成测试，从自动发布NPM包到自动构建和发布对应版本地Docker Image，实现了全自动地社区代码发布，极大地提高了社区地协同效率。</p>

<p>目前，在Github上已有千余个开源项目基于Wechaty构建了聊天机器人。另外，Wechaty统一了即时通讯软件平台的对话接口，仅需要一套代码即可运行在多个平台之上，目前已成熟高效地推动了包括社群管理、数据运维、办公、资讯、广告、营销等多个领域不同实用场景的落地。</p>

<p>机遇稍纵即逝，你还在等什么？现在就行动吧，填写报名信息。翘首以待你的到来，赢取这场挑战赛的桂冠荣耀！</p>

<p>✨ 比赛的战鼓已经擂响</p>

<p>✨ 欢迎您报名参赛</p>

<p>✨ 在亚马逊云科技中国峰会现场巅峰相见</p>

<p>✨ 共同突破极限，为 AI 而战！</p>

<p><a href="https://mp.weixin.qq.com/s/kDyn9qL54jr7NCKg--RIvA">阅读原文</a></p>]]></content><author><name>aiamber</name></author><category term="article" /><category term="aws" /><category term="ai" /><category term="chatbot" /><category term="competition" /><summary type="html"><![CDATA[✨ 第二届中国生成式 AI 创新应用挑战赛 ✨ 见证下一批独角兽的诞生！ 阅读原文]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2024/04-wechaty-with-aws2024-en/main.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2024/04-wechaty-with-aws2024-en/main.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Building an Intelligent Medical WeChat Bot with Dify, GPT-4 Turbo, and Wechaty</title><link href="https://wechaty.js.org/2024/03/30/wechatbot-with-wechaty-dify-gpt4-en/" rel="alternate" type="text/html" title="Building an Intelligent Medical WeChat Bot with Dify, GPT-4 Turbo, and Wechaty" /><published>2024-03-30T00:00:00+00:00</published><updated>2024-03-30T00:00:00+00:00</updated><id>https://wechaty.js.org/2024/03/30/wechatbot-with-wechaty-dify-gpt4-en</id><content type="html" xml:base="https://wechaty.js.org/2024/03/30/wechatbot-with-wechaty-dify-gpt4-en/"><![CDATA[<blockquote>
  <p>Author: <a href="https://github.com/gscfwid/">gscfwid</a>, An anesthetist in a big ship of mainland.</p>
</blockquote>

<p>Hello everyone, I’m a doctor and also a technology enthusiast. Today I’d like to share with you my recent project — building an intelligent Agent based on GPT-4 Turbo using Dify to implement an advanced WeChat chatbot.</p>

<h2 id="why-choose-a-wechat-bot">Why Choose a WeChat Bot</h2>

<p>First, let me explain why I wanted to build this bot. As a doctor, one of my important tasks is following up with patients to understand their postoperative recovery. Our hospital performs 70,000-80,000 surgeries annually, making manual phone follow-ups very impractical. Moreover, telecom carriers now have strict restrictions on phone calls. I found that for patients, WeChat might be a more acceptable follow-up method because it doesn’t feel as intrusive to their daily lives.</p>

<h2 id="why-choose-wechaty">Why Choose Wechaty</h2>

<p>However, most WeChat bot frameworks on the market are based on the web protocol, which is currently largely unusable. For example, although Wechaty can utilize the web protocol preserved on UOS, it cannot obtain permanent IDs, remarks, tags, and other data, which is very disadvantageous for follow-up work. After trying the padlocal protocol, I found it very suitable for my needs.</p>

<h2 id="why-choose-dify">Why Choose Dify</h2>

<p>Next, I want to talk about why I chose to use Dify to build this bot. First, I hoped this bot would not only complete follow-up tasks but also serve as a medical education bot for patients. With the explosion of large language models, this idea became very easy to implement. Using Wechaty and the large model API, I quickly conceived a preliminary framework.</p>

<p>Dify is a well-known large model Agent platform. Its API encapsulation is much more friendly than OpenAI’s official API, especially in terms of prompt construction and conversation thread maintenance. Although OpenAI can also build assistants, maintaining conversations doesn’t seem as easy. Additionally, the Dify platform itself has built some plugins, such as Google Search, which can be easily integrated into the API. Therefore, I ultimately chose Dify as my development platform.</p>

<p>The above is some background and thinking behind developing this medical follow-up WeChat bot. As a doctor and technical novice, I hope that by sharing my project experience, I can bring some inspiration and food for thought to everyone. In the following sections, I’ll discuss some technical details of this bot. I welcome everyone’s valuable opinions and suggestions.</p>

<h2 id="creating-a-gpt-4-turbo-based-model-through-dify">Creating a GPT-4 Turbo-Based Model Through Dify</h2>

<p>Dify provides a simple and easy-to-use interface that allows me to quickly create and test models.</p>

<p>First, I created a new application on the Dify platform and selected GPT-4 Turbo as the base model. In this initial phase, I temporarily didn’t use any custom prompts or plugins — I just wanted to do a simple test first to see how the model performs.</p>

<p>After creating the application, Dify automatically generates an API key, which we can use to call Dify’s API interface and interact with the intelligent conversation model we created.</p>

<h2 id="implementing-the-wechat-bot-with-wechaty">Implementing the WeChat Bot with Wechaty</h2>

<p>With the intelligent conversation model in place, we next need a platform to implement the WeChat bot and integrate the model into WeChat. Here I chose Wechaty. Wechaty is an open-source conversational bot SDK that supports personal WeChat accounts, built with Node.js and TypeScript.</p>

<p>Below is my code implementation, mainly divided into the following parts:</p>

<p>First, I use wechaty-puppet-padlocal as Wechaty’s Puppet Provider. It connects to WeChat through the iPad protocol, which is more stable and reliable compared to the Web protocol. Then I use WechatyBuilder to build our bot instance.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Initialize Wechaty</span>
<span class="kd">const</span> <span class="p">{</span> <span class="nx">PuppetPadlocal</span> <span class="p">}</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">"</span><span class="s2">wechaty-puppet-padlocal</span><span class="dl">"</span><span class="p">);</span>
<span class="kd">const</span> <span class="p">{</span> <span class="nx">WechatyBuilder</span> <span class="p">}</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">"</span><span class="s2">wechaty</span><span class="dl">"</span><span class="p">);</span>

<span class="kd">const</span> <span class="nx">puppet</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PuppetPadlocal</span><span class="p">({</span>
  <span class="na">token</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">PUPPET_PADLOCAL_TOKEN</span><span class="p">,</span>
<span class="p">});</span>

<span class="kd">const</span> <span class="nx">bot</span> <span class="o">=</span> <span class="nx">WechatyBuilder</span><span class="p">.</span><span class="nf">build</span><span class="p">({</span> <span class="nx">puppet</span><span class="p">,</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">test</span><span class="dl">"</span> <span class="p">});</span>
</code></pre></div></div>

<p>Next is the core function for calling the Dify API. I use the axios library to send a POST request to Dify’s API endpoint, passing in the user’s input message, conversation ID, and other parameters, and authenticating with the API Key. Dify returns the reply generated by the intelligent conversation model.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Function to call Dify API</span>
<span class="kd">const</span> <span class="nx">difyApiKey</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">DIFY_API_KEY</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">difyApiUrl</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://api.dify.ai/v1/chat-messages</span><span class="dl">"</span><span class="p">;</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">sendMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">userName</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// ...</span>
  <span class="k">try</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span>
      <span class="nx">difyApiUrl</span><span class="p">,</span>
      <span class="p">{</span>
        <span class="na">inputs</span><span class="p">:</span> <span class="p">{},</span>
        <span class="na">query</span><span class="p">:</span> <span class="nx">message</span><span class="p">,</span>
        <span class="na">response_mode</span><span class="p">:</span> <span class="dl">"</span><span class="s2">streaming</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">conversation_id</span><span class="p">:</span> <span class="nx">conversationData</span><span class="p">.</span><span class="nx">conversationId</span><span class="p">,</span>
        <span class="na">user</span><span class="p">:</span> <span class="nx">userName</span><span class="p">,</span>
        <span class="na">files</span><span class="p">:</span> <span class="p">[],</span>
      <span class="p">},</span>
      <span class="p">{</span>
        <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
          <span class="na">Authorization</span><span class="p">:</span> <span class="s2">`Bearer </span><span class="p">${</span><span class="nx">difyApiKey</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span>
          <span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
        <span class="p">},</span>
      <span class="p">}</span>
    <span class="p">);</span>
    <span class="c1">// Process response...</span>
  <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span>
        <span class="dl">"</span><span class="s2">Dify API responded with status code:</span><span class="dl">"</span><span class="p">,</span>
        <span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">.</span><span class="nx">status</span>
      <span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if </span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">request</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">No response received from Dify API:</span><span class="dl">"</span><span class="p">,</span> <span class="nx">error</span><span class="p">.</span><span class="nx">request</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Error setting up request to Dify API:</span><span class="dl">"</span><span class="p">,</span> <span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">// Handle error appropriately...</span>
  <span class="p">}</span>
  <span class="c1">// ...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Finally, I listen to Wechaty’s message event. When receiving a message from a user @mentioning the bot in a group chat, I extract the message content, call the sendMessage function to get the intelligent reply, and then send the reply to the group chat through room.say.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Listen to message events</span>
<span class="nx">bot</span><span class="p">.</span><span class="nf">on</span><span class="p">(</span><span class="dl">"</span><span class="s2">message</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="c1">// Get information about the message sender</span>
  <span class="kd">const</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">message</span><span class="p">.</span><span class="nf">talker</span><span class="p">().</span><span class="nx">id</span><span class="p">;</span>
  <span class="kd">const</span> <span class="nx">room</span> <span class="o">=</span> <span class="nx">message</span><span class="p">.</span><span class="nf">room</span><span class="p">();</span>
  <span class="kd">const</span> <span class="nx">userName</span> <span class="o">=</span> <span class="nx">message</span><span class="p">.</span><span class="nf">name</span><span class="p">();</span>
  <span class="kd">const</span> <span class="nx">text</span> <span class="o">=</span> <span class="nx">message</span><span class="p">.</span><span class="nf">text</span><span class="p">();</span>
  <span class="c1">// Check if it's in my already created SQLite database</span>
  <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">room</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">query</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">SELECT * FROM contacts WHERE id = ?</span><span class="dl">"</span><span class="p">;</span>
    <span class="k">try</span> <span class="p">{</span>
      <span class="kd">const</span> <span class="nx">row</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">db</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">query</span><span class="p">,</span> <span class="p">[</span><span class="nx">id</span><span class="p">]);</span>
      <span class="k">if </span><span class="p">(</span><span class="nx">row</span> <span class="o">!=</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">reply</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">sendMessage</span><span class="p">(</span><span class="nx">text</span><span class="p">,</span> <span class="nx">userName</span><span class="p">);</span>
        <span class="k">await</span> <span class="nx">message</span><span class="p">.</span><span class="nf">talker</span><span class="p">().</span><span class="nf">say</span><span class="p">(</span><span class="nx">reply</span><span class="p">);</span>
      <span class="p">}</span>
    <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="nx">err</span><span class="p">.</span><span class="nx">message</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>

<p>One important point to emphasize here is that I use the conversation_id in the Dify API to implement the conversation persistence feature. This part of the code is mainly in the sendMessage function:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">conversationMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">();</span> <span class="c1">// Create a key-value pair to save questioner information and conversation_id</span>
<span class="kd">const</span> <span class="nx">CONVERSATION_EXPIRATION</span> <span class="o">=</span> <span class="mi">5</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">;</span> <span class="c1">// Set conversation retention time to 5 minutes</span>
<span class="k">async</span> <span class="kd">function</span> <span class="nf">sendMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">userName</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// ...</span>
  <span class="kd">let</span> <span class="nx">conversationData</span> <span class="o">=</span> <span class="nx">conversationMap</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">userName</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">timestamp</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nf">now</span><span class="p">();</span>

  <span class="c1">// If the conversation doesn't exist or has expired, create a new conversation</span>
  <span class="k">if </span><span class="p">(</span>
    <span class="o">!</span><span class="nx">conversationData</span> <span class="o">||</span>
    <span class="nx">timestamp</span> <span class="o">-</span> <span class="nx">conversationData</span><span class="p">.</span><span class="nx">timestamp</span> <span class="o">&gt;</span> <span class="nx">CONVERSATION_EXPIRATION</span>
  <span class="p">)</span> <span class="p">{</span>
    <span class="nx">conversationData</span> <span class="o">=</span> <span class="p">{</span> <span class="na">conversationId</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">timestamp</span> <span class="p">};</span>
    <span class="nx">conversationMap</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">userName</span><span class="p">,</span> <span class="nx">conversationData</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span>
    <span class="nx">difyApiUrl</span><span class="p">,</span>
    <span class="p">{</span>
      <span class="c1">// ...</span>
      <span class="na">conversation_id</span><span class="p">:</span> <span class="nx">conversationData</span><span class="p">.</span><span class="nx">conversationId</span><span class="p">,</span>
      <span class="na">user</span><span class="p">:</span> <span class="nx">userName</span><span class="p">,</span>
      <span class="c1">// ...</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
  <span class="p">);</span>

  <span class="c1">// Update conversation ID and timestamp</span>
  <span class="nx">conversationData</span><span class="p">.</span><span class="nx">timestamp</span> <span class="o">=</span> <span class="nx">timestamp</span><span class="p">;</span>

  <span class="c1">// ...</span>
  <span class="c1">// The following code is needed because I'm using stream mode to get Dify's response, so I need to traverse each reply to find the final response content</span>
  <span class="k">for </span><span class="p">(</span><span class="kd">const</span> <span class="nx">line</span> <span class="k">of</span> <span class="nx">lines</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">line</span><span class="p">.</span><span class="nf">startsWith</span><span class="p">(</span><span class="dl">"</span><span class="s2">data:</span><span class="dl">"</span><span class="p">))</span> <span class="p">{</span>
      <span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">line</span><span class="p">.</span><span class="nf">slice</span><span class="p">(</span><span class="mi">5</span><span class="p">).</span><span class="nf">trim</span><span class="p">());</span>
      <span class="k">if </span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">event</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">agent_thought</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// ...</span>
        <span class="nx">conversationData</span><span class="p">.</span><span class="nx">conversationId</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">conversation_id</span><span class="p">;</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="c1">// ...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Through this approach, we can maintain an independent conversation context for each user, implementing multi-turn dialogues. When users continue to send messages within a certain time period (set to 5 minutes here), the context remains coherent; if this time is exceeded, a new conversation begins.</p>

<p>The next steps are all on the Dify platform, which I’m still working on. My vision is to upload health education articles downloaded from the web as a knowledge base and limit GPT-4 to only answer from the knowledge base. Anyway, that’s beyond the scope of technical discussion.</p>

<p>The above is the core code for implementing an intelligent WeChat conversation bot using Dify and Wechaty. Through Dify’s powerful conversation model and Wechaty’s convenient WeChat integration, we can quickly build a practical medical education bot. Of course, this is just a basic version. We can continue to add more features, such as custom prompts and knowledge base search, to further enhance the bot’s intelligence level.</p>

<hr />

<blockquote>
  <p>本文也有<a href="/2024/03/30/wechatbot-with-wechaty-dify-gpt4/">中文版本</a>。</p>
</blockquote>]]></content><author><name>gscfwid</name></author><category term="article" /><category term="dify" /><category term="gpt4-turbo" /><category term="ecosystem" /><summary type="html"><![CDATA[Building an intelligent medical follow-up and health education WeChat bot using Dify's GPT-4 Turbo Agent platform and Wechaty, featuring conversation context management and knowledge base integration.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2024/03-wechatbot-with-wechaty-dify-gpt4-en/bp-post.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2024/03-wechatbot-with-wechaty-dify-gpt4-en/bp-post.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">利用 Dify 构建基于 GPT-4 Turbo 的智能 Agent,实现医疗微信机器人</title><link href="https://wechaty.js.org/2024/03/30/wechatbot-with-wechaty-dify-gpt4/" rel="alternate" type="text/html" title="利用 Dify 构建基于 GPT-4 Turbo 的智能 Agent,实现医疗微信机器人" /><published>2024-03-30T00:00:00+00:00</published><updated>2024-03-30T00:00:00+00:00</updated><id>https://wechaty.js.org/2024/03/30/wechatbot-with-wechaty-dify-gpt4</id><content type="html" xml:base="https://wechaty.js.org/2024/03/30/wechatbot-with-wechaty-dify-gpt4/"><![CDATA[<blockquote>
  <p>作者: <a href="https://github.com/gscfwid/">gscfwid</a>，An anesthetist in a big ship of mainland.</p>
</blockquote>

<p>大家好,我是一名医生,同时也是一个技术爱好者。今天我想和大家分享一下我最近的一个项目——利用 Dify 构建基于 GPT-4 Turbo 的智能 Agent,实现高级微信聊天机器人。</p>

<h2 id="为什么选择微信机器人">为什么选择微信机器人</h2>

<p>首先,我想说一下为什么要做这个机器人。作为一名医生,我的一项重要工作是随访病人,了解他们术后的恢复情况。我们医院每年有 7-8 万的手术量,人工电话随访是非常不现实的。而且,现在运营商对电话的限制也比较严格。我发现,对于病人来说,微信可能是一个更容易接受的随访方式,因为它不会显得打扰到他们的生活。</p>

<h2 id="为什么选择-wechaty">为什么选择 Wechaty</h2>

<p>然而,市面上大多数微信机器人框架都是基于 web 协议的,而目前 web 协议基本处于不可用的状态。例如,虽然 wechaty 可以利用 UOS 上保留的 web 协议,但它无法获取永久的 ID、备注、tag 等数据,这对随访工作非常不利。在尝试了 padlocal 协议后,我觉得它非常适合我的需求。</p>

<h2 id="为什么选择-dify">为什么选择 Dify</h2>

<p>接下来,我想说一下为什么选择使用 Dify 来构建这个机器人。首先,我希望这个机器人不仅能完成随访任务,还能成为一个面向病人的医学科普机器人。随着大语言模型的爆发,这个想法变得非常容易实现。利用 wechaty 和大模型的 API,我很快就构思出了一个初步的框架。</p>

<p>Dify 是一个知名的大模型 Agent 平台,它对 API 的封装要比 OpenAI 官方的 API 更加友好,例如在 prompt 的构建和对话线程的保持方面。虽然 OpenAI 也可以构建 assistant,但是保持对话似乎没有那么容易。另外,Dify 平台本身也构建了一些插件,比如 Google 搜索,可以很容易集成到 API 中。因此,我最终选择了 Dify 作为我的开发平台。
以上就是我开发这个微信医疗随访机器人的一些背景和思路。作为一个医生和技术小白,我希望通过分享自己的项目经历,能给大家带来一些启发和思考。在接下来的部分,我会和大家聊聊这个机器人的一些技术细节,欢迎大家提出宝贵的意见和建议。</p>

<h2 id="通过-dify-创建基于-gpt-4-turbo-的模型">通过 Dify 创建基于 GPT-4 Turbo 的模型</h2>

<p>Dify 提供了一个简单易用的界面,让我可以快速地创建和测试模型。
首先,我在 Dify 平台上创建了一个新的应用,并选择了 GPT-4 Turbo 作为基础模型。在这个初始阶段,我暂时没有使用任何自定义的 prompt 或插件,只是想先做一个简单的测试,看看模型的性能如何。</p>

<p>创建应用后,Dify 会自动生成一个 API 密钥(API key),我们可以使用这个密钥来调用 Dify 的 API 接口,与我们创建的智能对话模型进行交互。</p>

<h2 id="使用-wechaty-实现微信机器人">使用 Wechaty 实现微信机器人</h2>

<p>有了智能对话模型,接下来我们需要一个平台来实现微信机器人,将模型集成到微信中。这里我选择了 Wechaty。Wechaty 是一个开源的对话机器人 SDK,支持个人微信号,使用 Node.js 和 TypeScript 构建。</p>

<p>下面是我的代码实现,主要分为以下几个部分:</p>

<p>首先,我使用 wechaty-puppet-padlocal 作为 Wechaty 的 Puppet Provider,它通过 iPad 协议连接微信,相比 Web 协议更加稳定可靠。然后使用 WechatyBuilder 来构建我们的机器人实例。</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 初始化Wechaty</span>
<span class="kd">const</span> <span class="p">{</span> <span class="nx">PuppetPadlocal</span> <span class="p">}</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">"</span><span class="s2">wechaty-puppet-padlocal</span><span class="dl">"</span><span class="p">);</span>
<span class="kd">const</span> <span class="p">{</span> <span class="nx">WechatyBuilder</span> <span class="p">}</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">"</span><span class="s2">wechaty</span><span class="dl">"</span><span class="p">);</span>

<span class="kd">const</span> <span class="nx">puppet</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PuppetPadlocal</span><span class="p">({</span>
  <span class="na">token</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">PUPPET_PADLOCAL_TOKEN</span><span class="p">,</span>
<span class="p">});</span>

<span class="kd">const</span> <span class="nx">bot</span> <span class="o">=</span> <span class="nx">WechatyBuilder</span><span class="p">.</span><span class="nf">build</span><span class="p">({</span> <span class="nx">puppet</span><span class="p">,</span> <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">test</span><span class="dl">"</span> <span class="p">});</span>
</code></pre></div></div>

<p>接下来调用 Dify API 的核心函数。我使用 axios 库发送 POST 请求到 Dify 的 API 端点,传入用户的输入消息、对话 ID 等参数,并通过 API Key 进行身份验证。Dify 会返回智能对话模型生成的回复。</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 调用Dify API的函数</span>
<span class="kd">const</span> <span class="nx">difyApiKey</span> <span class="o">=</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">DIFY_API_KEY</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">difyApiUrl</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">https://api.dify.ai/v1/chat-messages</span><span class="dl">"</span><span class="p">;</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">sendMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">userName</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// ...</span>
  <span class="k">try</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span>
      <span class="nx">difyApiUrl</span><span class="p">,</span>
      <span class="p">{</span>
        <span class="na">inputs</span><span class="p">:</span> <span class="p">{},</span>
        <span class="na">query</span><span class="p">:</span> <span class="nx">message</span><span class="p">,</span>
        <span class="na">response_mode</span><span class="p">:</span> <span class="dl">"</span><span class="s2">streaming</span><span class="dl">"</span><span class="p">,</span>
        <span class="na">conversation_id</span><span class="p">:</span> <span class="nx">conversationData</span><span class="p">.</span><span class="nx">conversationId</span><span class="p">,</span>
        <span class="na">user</span><span class="p">:</span> <span class="nx">userName</span><span class="p">,</span>
        <span class="na">files</span><span class="p">:</span> <span class="p">[],</span>
      <span class="p">},</span>
      <span class="p">{</span>
        <span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
          <span class="na">Authorization</span><span class="p">:</span> <span class="s2">`Bearer </span><span class="p">${</span><span class="nx">difyApiKey</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span>
          <span class="dl">"</span><span class="s2">Content-Type</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">application/json</span><span class="dl">"</span><span class="p">,</span>
        <span class="p">},</span>
      <span class="p">}</span>
    <span class="p">);</span>
    <span class="c1">// Process response...</span>
  <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span>
        <span class="dl">"</span><span class="s2">Dify API responded with status code:</span><span class="dl">"</span><span class="p">,</span>
        <span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">.</span><span class="nx">status</span>
      <span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if </span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">request</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">No response received from Dify API:</span><span class="dl">"</span><span class="p">,</span> <span class="nx">error</span><span class="p">.</span><span class="nx">request</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">"</span><span class="s2">Error setting up request to Dify API:</span><span class="dl">"</span><span class="p">,</span> <span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">// Handle error appropriately...</span>
  <span class="p">}</span>
  <span class="c1">// ...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>最后,我监听 Wechaty 的 message 事件,当收到用户在群聊中@机器人的消息时,提取出消息内容,调用 sendMessage 函数获取智能回复,然后通过 room.say 将回复发送到群聊中。</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 监听消息事件</span>
<span class="nx">bot</span><span class="p">.</span><span class="nf">on</span><span class="p">(</span><span class="dl">"</span><span class="s2">message</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="c1">// 获取发消息人的信息</span>
  <span class="kd">const</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">message</span><span class="p">.</span><span class="nf">talker</span><span class="p">().</span><span class="nx">id</span><span class="p">;</span>
  <span class="kd">const</span> <span class="nx">room</span> <span class="o">=</span> <span class="nx">message</span><span class="p">.</span><span class="nf">room</span><span class="p">();</span>
  <span class="kd">const</span> <span class="nx">userName</span> <span class="o">=</span> <span class="nx">message</span><span class="p">.</span><span class="nf">name</span><span class="p">();</span>
  <span class="kd">const</span> <span class="nx">text</span> <span class="o">=</span> <span class="nx">message</span><span class="p">.</span><span class="nf">text</span><span class="p">();</span>
  <span class="c1">// 判断它是否在我已经创建好的SQLite数据库中</span>
  <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">room</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">const</span> <span class="nx">query</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">SELECT * FROM contacts WHERE id = ?</span><span class="dl">"</span><span class="p">;</span>
    <span class="k">try</span> <span class="p">{</span>
      <span class="kd">const</span> <span class="nx">row</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">db</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">query</span><span class="p">,</span> <span class="p">[</span><span class="nx">id</span><span class="p">]);</span>
      <span class="k">if </span><span class="p">(</span><span class="nx">row</span> <span class="o">!=</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">reply</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">sendMessage</span><span class="p">(</span><span class="nx">text</span><span class="p">,</span> <span class="nx">userName</span><span class="p">);</span>
        <span class="k">await</span> <span class="nx">message</span><span class="p">.</span><span class="nf">talker</span><span class="p">().</span><span class="nf">say</span><span class="p">(</span><span class="nx">reply</span><span class="p">);</span>
      <span class="p">}</span>
    <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="nx">err</span><span class="p">.</span><span class="nx">message</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>

<p>这里需要强调的一点是，我利用 Dify API 中的 conversation_id 来实现保持对话的功能。这部分代码主要在 sendMessage 函数中:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">conversationMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">();</span> <span class="c1">// 创建一个键值对来保存提问者的信息和conversation_id</span>
<span class="kd">const</span> <span class="nx">CONVERSATION_EXPIRATION</span> <span class="o">=</span> <span class="mi">5</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">;</span> <span class="c1">// 设定conversation的保持时间，设定为5分钟</span>
<span class="k">async</span> <span class="kd">function</span> <span class="nf">sendMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">userName</span><span class="p">)</span> <span class="p">{</span>
  <span class="c1">// ...</span>
  <span class="kd">let</span> <span class="nx">conversationData</span> <span class="o">=</span> <span class="nx">conversationMap</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">userName</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">timestamp</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nf">now</span><span class="p">();</span>

  <span class="c1">// 如果会话不存在或已过期,则创建新的会话</span>
  <span class="k">if </span><span class="p">(</span>
    <span class="o">!</span><span class="nx">conversationData</span> <span class="o">||</span>
    <span class="nx">timestamp</span> <span class="o">-</span> <span class="nx">conversationData</span><span class="p">.</span><span class="nx">timestamp</span> <span class="o">&gt;</span> <span class="nx">CONVERSATION_EXPIRATION</span>
  <span class="p">)</span> <span class="p">{</span>
    <span class="nx">conversationData</span> <span class="o">=</span> <span class="p">{</span> <span class="na">conversationId</span><span class="p">:</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">timestamp</span> <span class="p">};</span>
    <span class="nx">conversationMap</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">userName</span><span class="p">,</span> <span class="nx">conversationData</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="nf">post</span><span class="p">(</span>
    <span class="nx">difyApiUrl</span><span class="p">,</span>
    <span class="p">{</span>
      <span class="c1">// ...</span>
      <span class="na">conversation_id</span><span class="p">:</span> <span class="nx">conversationData</span><span class="p">.</span><span class="nx">conversationId</span><span class="p">,</span>
      <span class="na">user</span><span class="p">:</span> <span class="nx">userName</span><span class="p">,</span>
      <span class="c1">// ...</span>
    <span class="p">}</span>
    <span class="c1">// ...</span>
  <span class="p">);</span>

  <span class="c1">// 更新会话ID和时间戳</span>
  <span class="nx">conversationData</span><span class="p">.</span><span class="nx">timestamp</span> <span class="o">=</span> <span class="nx">timestamp</span><span class="p">;</span>

  <span class="c1">// ...</span>
  <span class="c1">// 下面的代码是由于使用了stream模式来获取Dify的response，所以我需要遍历它的每个回复，找到最终的回复内容</span>
  <span class="k">for </span><span class="p">(</span><span class="kd">const</span> <span class="nx">line</span> <span class="k">of</span> <span class="nx">lines</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">line</span><span class="p">.</span><span class="nf">startsWith</span><span class="p">(</span><span class="dl">"</span><span class="s2">data:</span><span class="dl">"</span><span class="p">))</span> <span class="p">{</span>
      <span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="nx">line</span><span class="p">.</span><span class="nf">slice</span><span class="p">(</span><span class="mi">5</span><span class="p">).</span><span class="nf">trim</span><span class="p">());</span>
      <span class="k">if </span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">event</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">agent_thought</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">// ...</span>
        <span class="nx">conversationData</span><span class="p">.</span><span class="nx">conversationId</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">conversation_id</span><span class="p">;</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="c1">// ...</span>
<span class="p">}</span>
</code></pre></div></div>

<p>通过这种方式,我们可以为每个用户维护一个独立的对话上下文,实现多轮对话。当用户在一定时间内(这里设置为 5 分钟)继续发送消息时,就可以保持上下文连贯;如果超过了这个时间,就会开始一个新的对话。</p>

<p>接下来的设置就都是在 Dify 平台了，目前我还在制作中。我设想是上传从网络中下载的科普文章作为知识库，限定 GPT-4 只在知识库中作答。Anyway，就不属于技术讨论的范畴了。</p>

<p>以上就是利用 Dify 和 Wechaty 实现微信智能对话机器人的核心代码。通过 Dify 强大的对话模型和 Wechaty 方便的微信集成,我们可以快速搭建一个实用的医疗科普机器人。当然,这只是一个基础版本,我们还可以继续添加更多功能,如自定义 prompt、知识库搜索等,来进一步提升机器人的智能化水平。</p>

<hr />

<blockquote>
  <p>This post is also available in <a href="/2024/03/30/wechatbot-with-wechaty-dify-gpt4-en/">English</a>.</p>
</blockquote>]]></content><author><name>gscfwid</name></author><category term="article" /><category term="dify" /><category term="gpt4-turbo" /><summary type="html"><![CDATA[作者: gscfwid，An anesthetist in a big ship of mainland.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://wechaty.js.org/assets/2024/03-wechatbot-with-wechaty-dify-gpt4-en/bp-post.webp" /><media:content medium="image" url="https://wechaty.js.org/assets/2024/03-wechatbot-with-wechaty-dify-gpt4-en/bp-post.webp" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>