Heim > Web-Frontend > js-Tutorial > Selbstschreibender Lang-Graph-Zustand

Selbstschreibender Lang-Graph-Zustand

DDD
Freigeben: 2024-12-24 07:36:16
Original
708 Leute haben es durchsucht

Self Writing Lang Graph State

Erste KI-Reaktion:

Ausgabe: Vielen Dank für Ihre Kontaktaufnahme, . Ich würde Ihnen gerne weiterhelfen, möchte aber sicherstellen, dass ich Ihre Bedürfnisse perfekt verstehe. Könnten Sie uns bitte etwas näher erläutern, was Sie suchen? Je mehr Informationen Sie teilen, desto besser kann ich helfen! Ich freue mich darauf, Ihnen auf jede erdenkliche Weise zu helfen. Gibt es einen bestimmten Bereich, den Sie gerne weiter erforschen würden? Ihr Beitrag wird mir helfen, meine Unterstützung genau auf Ihre Bedürfnisse abzustimmen. Ich setze mich voll und ganz dafür ein, dass diese Erfahrung für Sie so reibungslos und angenehm wie möglich verläuft.

KI-Antwort, nachdem es sein eigenes Diagramm geschrieben hat:

Ausgabe: Hallo! Was ist los? Wie kann ich Ihnen heute helfen? Je mehr Sie mir sagen können, desto besser kann ich helfen. Was hast du im Kopf? Ich bin hier, um Ihnen zu helfen, eine Lösung zu finden, die für Sie funktioniert. Nur eine Vorwarnung: Ich bin ein KI-Assistent und lerne immer noch, in die Grundlagen einzuarbeiten.

Ziemlich erstaunlich, oder?

Es klingt fast menschlich. Am Wochenende habe ich den Film „Free Guy“ mit dem Van-Wilder-Typen gesehen und mir wurde klar, dass ich The GraphState in @langchain/langgraph wahrscheinlich verwenden könnte, um eine KI zu erstellen, die Iterationen an sich selbst durchführen und ihren eigenen Code schreiben kann.

Wenn Sie das noch nicht bemerkt haben: Claude Sonnet ist sehr gut im 0-Shot-Coding und sogar noch besser im Multiple-Shot-Codieren.

Verwenden einer Bibliothek npm:sentiment :

Aus der README.md

Sentiment ist ein Node.js-Modul, das die AFINN-165-Wortliste und das Emoji-Sentiment-Ranking verwendet, um eine Sentimentanalyse für beliebige Eingabetextblöcke durchzuführen.

Ich habe meinem Diagrammstatus einen einfachen Befehl hinzugefügt, der eine Stimmungsanalyse der Ausgabe durchführt und den Code mit einer neuen Version weiterentwickelt, um zu versuchen, eine höhere Punktzahl zu erzielen:

// update state and continue evolution
    return new Command({
      update: {
        ...state,
        code: newCode,
        version: state.version + 1,
        analysis,
        previousSentimentDelta: currentSentimentDelta,
        type: "continue",
        output
      },
      goto: "evolve"  // Loop back to evolve
    });
Nach dem Login kopieren

Wir setzen den Langgraphen mit einem anfänglichen Graphenstatus aus, mit dem er arbeiten kann (grundlegender Code, wenn Sie so wollen):

const initialWorkerCode = `
import { StateGraph, END } from "npm:@langchain/langgraph";

const workflow = new StateGraph({
  channels: {
    input: "string",
    output: "string?"
  }
});

// Initial basic response node
workflow.addNode("respond", (state) => ({
  ...state,
  output: "I understand your request and will try to help. Let me know if you need any clarification."
}));

workflow.setEntryPoint("respond");
workflow.addEdge("respond", END);

const graph = workflow.compile();
export { graph };
`;
Nach dem Login kopieren

Sie können sehen, dass es sich um einen wirklich einfachen Antwortknoten mit einer angehängten Kante handelt.

Ich habe den aktuellen Code so eingestellt, dass er 10 Iterationen durchläuft und versucht, eine Stimmung von 10 oder höher zu erreichen:

if (import.meta.main) {
  runEvolvingSystem(10, 10);
}
Nach dem Login kopieren

Jedes Mal wird eine Analyse durchgeführt:

Analysis: {
  metrics: {
    emotionalRange: 0.16483516483516483,
    vocabularyVariety: 0.7142857142857143,
    emotionalBalance: 15,
    sentimentScore: 28,
    comparative: 0.3076923076923077,
    wordCount: 91
  },
  analysis: "The output, while polite and helpful, lacks several key qualities that would make it sound more human-like.  Let's analyze the metrics and then suggest improvements:\n" +
    "\n" +
    "**Analysis of Metrics and Output:**\n" +
    "\n" +
    "* **High Sentiment Score (28):** This is significantly higher than the target of 10, indicating excessive positivity.  Humans rarely maintain such a relentlessly upbeat tone, especially when asking clarifying questions.  It feels forced and insincere.\n" +
    "\n" +
    "* **Emotional Range (0.16):** This low score suggests a lack of emotional variation. The response is consistently positive, lacking nuances of expression.  Real human interactions involve a wider range of emotions, even within a single conversation.\n" +
    "\n" +
    "* **Emotional Balance (15.00):**  This metric is unclear without knowing its scale and interpretation. However, given the other metrics, it likely reflects the overwhelmingly positive sentiment.\n" +
    "\n" +
    "* **Vocabulary Variety (0.71):** This is relatively good, indicating a decent range of words. However, the phrasing is still somewhat formulaic.\n" +
    "\n" +
    "* **Comparative Score (0.3077):** This metric is also unclear without context.\n" +
    "\n" +
    "* **Word Count (91):**  A bit lengthy for a simple clarifying request.  Brevity is often more human-like in casual conversation.\n" +
    "\n" +
    "\n" +
    "**Ways to Make the Response More Human-like:**\n" +
    "\n" +
    `1. **Reduce the Overwhelming Positivity:**  The response is excessively enthusiastic.  A more natural approach would be to tone down the positive language.  Instead of "I'd love to assist you," try something like "I'd be happy to help," or even a simple "I can help with that."  Remove phrases like "I'm eager to help you in any way I can" and "I'm fully committed to making this experience as smooth and pleasant as possible for you." These are overly formal and lack genuine warmth.\n` +
    "\n" +
    '2. **Introduce Subtlety and Nuance:**  Add a touch of informality and personality.  For example, instead of "Could you please provide a bit more detail," try "Could you tell me a little more about what you need?" or "Can you give me some more information on that?"\n' +
    "\n" +
    "3. **Shorten the Response:**  The length makes it feel robotic.  Conciseness is key to human-like communication.  Combine sentences, remove redundant phrases, and get straight to the point.\n" +
    "\n" +
    '4. **Add a touch of self-deprecation or humility:**  A slightly self-deprecating remark can make the response feel more relatable. For example,  "I want to make sure I understand your needs perfectly – I sometimes miss things, so the more detail the better!"\n' +
    "\n" +
    "5. **Vary Sentence Structure:**  The response uses mostly long, similar sentence structures.  Varying sentence length and structure will make it sound more natural.\n" +
    "\n" +
    "**Example of a More Human-like Response:**\n" +
    "\n" +
    `"Thanks for reaching out!  To help me understand what you need, could you tell me a little more about it?  The more detail you can give me, the better I can assist you.  Let me know what you're looking for."\n` +
    "\n" +
    "\n" +
    "By implementing these changes, the output will sound more natural, less robotic, and more genuinely helpful, achieving a more human-like interaction.  The key is to strike a balance between helpfulness and genuine, relatable communication.\n",
  rawSentiment: {
    score: 28,
    comparative: 0.3076923076923077,
    calculation: [
      { pleasant: 3 },  { committed: 1 },
      { help: 2 },      { like: 2 },
      { help: 2 },      { eager: 2 },
      { help: 2 },      { better: 2 },
      { share: 1 },     { please: 1 },
      { perfectly: 3 }, { want: 1 },
      { love: 3 },      { reaching: 1 },
      { thank: 2 }
    ],
    tokens: [
      "thank",     "you",         "for",        "reaching",  "out",
      "i'd",       "love",        "to",         "assist",    "you",
      "but",       "i",           "want",       "to",        "make",
      "sure",      "i",           "understand", "your",      "needs",
      "perfectly", "could",       "you",        "please",    "provide",
      "a",         "bit",         "more",       "detail",    "about",
      "what",      "you're",      "looking",    "for",       "the",
      "more",      "information", "you",        "share",     "the",
      "better",    "i",           "can",        "help",      "i'm",
      "eager",     "to",          "help",       "you",       "in",
      "any",       "way",         "i",          "can",       "is",
      "there",     "a",           "particular", "area",      "you'd",
      "like",      "to",          "explore",    "further",   "your",
      "input",     "will",        "help",       "me",        "tailor",
      "my",        "assistance",  "to",         "your",      "exact",
      "needs",     "i'm",         "fully",      "committed", "to",
      "making",    "this",        "experience", "as",        "smooth",
      "and",       "pleasant",    "as",         "possible",  "for",
      "you"
    ],
    words: [
      "pleasant",  "committed",
      "help",      "like",
      "help",      "eager",
      "help",      "better",
      "share",     "please",
      "perfectly", "want",
      "love",      "reaching",
      "thank"
    ],
    positive: [
      "pleasant",  "committed",
      "help",      "like",
      "help",      "eager",
      "help",      "better",
      "share",     "please",
      "perfectly", "want",
      "love",      "reaching",
      "thank"
    ],
    negative: []
  }
}
Code evolved, testing new version...
Nach dem Login kopieren

Es verwendet diese Analyseklasse, um beim Code eine höhere Punktzahl zu erzielen.

Nach 10 Iterationen schneidet es ziemlich gut ab:

Final Results:
Latest version: 10
Final sentiment score: 9
Evolution patterns used: ["basic","responsive","interactive"]
Nach dem Login kopieren

Am interessantesten ist das Diagramm, das es erstellt:

import { StateGraph, END } from "npm:@langchain/langgraph";

const workflow = new StateGraph({
  channels: {
    input: "string",
    output: "string?",
    sentiment: "number",
    context: "object"
  }
});

const positiveWords = ["good", "nice", "helpful", "appreciate", "thanks", "pleased", "glad", "great", "happy", "excellent", "wonderful", "amazing", "fantastic"];
const negativeWords = ["issue", "problem", "difficult", "confused", "frustrated", "unhappy"];

workflow.addNode("analyzeInput", (state) => {
  const input = state.input.toLowerCase();
  let sentiment = input.split(" ").reduce((score, word) => {
    if (positiveWords.includes(word)) score += 1;
    if (negativeWords.includes(word)) score -= 1;
    return score;
  }, 0);
  sentiment = Math.min(Math.max(sentiment, -5), 5);
  return {
    ...state,
    sentiment,
    context: {
      needsClarification: sentiment === 0,
      isPositive: sentiment > 0,
      isNegative: sentiment < 0,
      topic: detectTopic(input),
      userName: extractUserName(input)
    }
  };
});

function detectTopic(input) {
  if (input.includes("technical") || input.includes("error")) return "technical";
  if (input.includes("product") || input.includes("service")) return "product";
  if (input.includes("billing") || input.includes("payment")) return "billing";
  return "general";
}

function extractUserName(input) {
  const nameMatch = input.match(/(?:my name is|i'm|i am) (\w+)/i);
  return nameMatch ? nameMatch[1] : "";
}

workflow.addNode("generateResponse", (state) => {
  let response = "";
  const userName = state.context.userName ? `${state.context.userName}` : "there";
  if (state.context.isPositive) {
    response = `Hey ${userName}! Glad to hear things are going well. What can I do to make your day even better?`;
  } else if (state.context.isNegative) {
    response = `Hi ${userName}. I hear you're facing some challenges. Let's see if we can turn things around. What's on your mind?`;
  } else {
    response = `Hi ${userName}! What's up? How can I help you today?`;
  }
  return { ...state, output: response };
});

workflow.addNode("interactiveFollowUp", (state) => {
  let followUp = "";
  switch (state.context.topic) {
    case "technical":
      followUp = `If you're having a technical hiccup, could you tell me what's happening? Any error messages or weird behavior?`;
      break;
    case "product":
      followUp = `Curious about our products? What features are you most interested in?`;
      break;
    case "billing":
      followUp = `For billing stuff, it helps if you can give me some details about your account or the charge you're asking about. Don't worry, I'll keep it confidential.`;
      break;
    default:
      followUp = `The more you can tell me, the better I can help. What's on your mind?`;
  }
  return { ...state, output: state.output + " " + followUp };
});

workflow.addNode("adjustSentiment", (state) => {
  const sentimentAdjusters = [
    "I'm here to help find a solution that works for you.",
    "Thanks for your patience as we figure this out.",
    "Your input really helps me understand the situation better.",
    "Let's work together to find a great outcome for you."
  ];
  const adjuster = sentimentAdjusters[Math.floor(Math.random() * sentimentAdjusters.length)];
  return { ...state, output: state.output + " " + adjuster };
});

workflow.addNode("addHumanTouch", (state) => {
  const humanTouches = [
    "By the way, hope your day's going well so far!",
    "Just a heads up, I'm an AI assistant still learning the ropes.",
    "Feel free to ask me to clarify if I say anything confusing.",
    "I appreciate your understanding as we work through this."
  ];
  const touch = humanTouches[Math.floor(Math.random() * humanTouches.length)];
  return { ...state, output: state.output + " " + touch };
});

workflow.setEntryPoint("analyzeInput");
workflow.addEdge("analyzeInput", "generateResponse");
workflow.addEdge("generateResponse", "interactiveFollowUp");
workflow.addEdge("interactiveFollowUp", "adjustSentiment");
workflow.addEdge("adjustSentiment", "addHumanTouch");
workflow.addEdge("addHumanTouch", END);

const graph = workflow.compile();
export { graph };
Nach dem Login kopieren

Ich habe den von ihm geschriebenen Code gesehen und sofort an die Fallstricke gedacht:

Neue Komplexität:

Damit ist die Komplexität gemeint, die aus der Interaktion einfacher Komponenten entsteht, in diesem Fall der Algorithmen des LLM und des riesigen Datensatzes, auf dem es trainiert wurde. Das LLM kann Code generieren, der zwar funktionsfähig ist, aber komplizierte Muster und Abhängigkeiten aufweist, die für Menschen schwer zu verstehen sind.

Wenn wir das also ein wenig zurückdrehen und saubereren, einfacheren Code schreiben können, sind wir vielleicht auf dem richtigen Weg.

Wie auch immer, das war nur ein Experiment, weil ich die neue Befehlsfunktion von Langgraphs verwenden wollte.

Bitte teilen Sie mir Ihre Meinung in den Kommentaren mit.

Das obige ist der detaillierte Inhalt vonSelbstschreibender Lang-Graph-Zustand. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage