AI-Master-Book
  • about AI-Master-Book
  • AI Master Book
    • 이상치 탐지 with Python
    • 베이지안 뉴럴네트워크 (BNN) with Python
    • 그래프 뉴럴네트워크 (GNN) with Python
    • 데이터 마케팅 분석 with Python
  • LLM MASTER BOOK
    • OpenAI API 쿡북 with Python
    • 기초부터 심화까지 RAG 쿡북 with Python
    • MCP 에이전트 쿡북 with Python
  • LLMs
    • OpenAI API
      • 1️⃣ChatCompletion
      • 2️⃣DALL-E
      • 3️⃣Text to Speech
      • 4️⃣Video to Transcripts
      • 5️⃣Assistants API
      • 6️⃣Prompt Engineering
      • 7️⃣OpenAI New GPT-4o
    • LangChain
      • LangChain Basic
        • 1️⃣Basic Modules
        • 2️⃣Model I/O
        • 3️⃣Prompts
        • 4️⃣Chains
        • 5️⃣Agents
        • 6️⃣Tools
        • 7️⃣Memory
      • LangChain Intermediate
        • 1️⃣OpenAI LLM
        • 2️⃣Prompt Template
        • 3️⃣Retrieval
        • 4️⃣RAG ChatBot
        • 5️⃣RAG with Gemini
        • 6️⃣New Huggingface-LangChain
        • 7️⃣Huggingface Hub
        • 8️⃣SQL Agent & Chain
        • 9️⃣Expression Language(LCEL)
        • 🔟Llama3-8B with LangChain
      • LangChain Advanced
        • 1️⃣LLM Evaluation
        • 2️⃣RAG Evaluation with RAGAS
        • 3️⃣LangChain with RAGAS
        • 4️⃣RAG Paradigms
        • 5️⃣LangChain: Advance Techniques
        • 6️⃣LangChain with NeMo-Guardrails
        • 7️⃣LangChain vs. LlamaIndex
        • 8️⃣LangChain LCEL vs. LangGraph
    • LlamaIndex
      • LlamaIndex Basic
        • 1️⃣Introduction
        • 2️⃣Customization
        • 3️⃣Data Connectors
        • 4️⃣Documents & Nodes
        • 5️⃣Naive RAG
        • 6️⃣Advanced RAG
        • 7️⃣Llama3-8B with LlamaIndex
        • 8️⃣LlmaPack
      • LlamaIndex Intermediate
        • 1️⃣QueryEngine
        • 2️⃣Agent
        • 3️⃣Evaluation
        • 4️⃣Evaluation-Driven Development
        • 5️⃣Fine-tuning
        • 6️⃣Prompt Compression with LLMLingua
      • LlamaIndex Advanced
        • 1️⃣Agentic RAG: Router Engine
        • 2️⃣Agentic RAG: Tool Calling
        • 3️⃣Building Agent Reasoning Loop
        • 4️⃣Building Multi-document Agent
    • Hugging Face
      • Huggingface Basic
        • 1️⃣Datasets
        • 2️⃣Tokenizer
        • 3️⃣Sentence Embeddings
        • 4️⃣Transformers
        • 5️⃣Sentence Transformers
        • 6️⃣Evaluate
        • 7️⃣Diffusers
      • Huggingface Tasks
        • NLP
          • 1️⃣Sentiment Analysis
          • 2️⃣Zero-shot Classification
          • 3️⃣Aspect-Based Sentiment Analysis
          • 4️⃣Feature Extraction
          • 5️⃣Intent Classification
          • 6️⃣Topic Modeling: BERTopic
          • 7️⃣NER: Token Classification
          • 8️⃣Summarization
          • 9️⃣Translation
          • 🔟Text Generation
        • Audio & Tabular
          • 1️⃣Text-to-Speech: TTS
          • 2️⃣Speech Recognition: Whisper
          • 3️⃣Audio Classification
          • 4️⃣Tabular Qustaion & Answering
        • Vision & Multimodal
          • 1️⃣Image-to-Text
          • 2️⃣Text to Image
          • 3️⃣Image to Image
          • 4️⃣Text or Image-to-Video
          • 5️⃣Depth Estimation
          • 6️⃣Image Classification
          • 7️⃣Object Detection
          • 8️⃣Segmentatio
      • Huggingface Optimization
        • 1️⃣Accelerator
        • 2️⃣Bitsandbytes
        • 3️⃣Flash Attention
        • 4️⃣Quantization
        • 5️⃣Safetensors
        • 6️⃣Optimum-ONNX
        • 7️⃣Optimum-NVIDIA
        • 8️⃣Optimum-Intel
      • Huggingface Fine-tuning
        • 1️⃣Transformer Fine-tuning
        • 2️⃣PEFT Fine-tuning
        • 3️⃣PEFT: Fine-tuning with QLoRA
        • 4️⃣PEFT: Fine-tuning Phi-2 with QLoRA
        • 5️⃣Axoltl Fine-tuning with QLoRA
        • 6️⃣TRL: RLHF Alignment Fine-tuning
        • 7️⃣TRL: DPO Fine-tuning with Phi-3-4k-instruct
        • 8️⃣TRL: ORPO Fine-tuning with Llama3-8B
        • 9️⃣Convert GGUF gemma-2b with llama.cpp
        • 🔟Apple Silicon Fine-tuning Gemma-2B with MLX
        • 🔢LLM Mergekit
    • Agentic LLM
      • Agentic LLM
        • 1️⃣Basic Agentic LLM
        • 2️⃣Multi-agent with CrewAI
        • 3️⃣LangGraph: Multi-agent Basic
        • 4️⃣LangGraph: Agentic RAG with LangChain
        • 5️⃣LangGraph: Agentic RAG with Llama3-8B by Groq
      • Autonomous Agent
        • 1️⃣LLM Autonomous Agent?
        • 2️⃣AutoGPT: Worldcup Winner Search with LangChain
        • 3️⃣BabyAGI: Weather Report with LangChain
        • 4️⃣AutoGen: Writing Blog Post with LangChain
        • 5️⃣LangChain: Autonomous-agent Debates with Tools
        • 6️⃣CAMEL Role-playing Autonomous Cooperative Agents
        • 7️⃣LangChain: Two-player Harry Potter D&D based CAMEL
        • 8️⃣LangChain: Multi-agent Bid for K-Pop Debate
        • 9️⃣LangChain: Multi-agent Authoritarian Speaker Selection
        • 🔟LangChain: Multi-Agent Simulated Environment with PettingZoo
    • Multimodal
      • 1️⃣PaliGemma: Open Vision LLM
      • 2️⃣FLUX.1: Generative Image
    • Building LLM
      • 1️⃣DSPy
      • 2️⃣DSPy RAG
      • 3️⃣DSPy with LangChain
      • 4️⃣Mamba
      • 5️⃣Mamba RAG with LangChain
      • 7️⃣PostgreSQL VectorDB with pgvorco.rs
Powered by GitBook
On this page
  • About CAMEL
  • LangChain: Two-Player Harry Potter D&D based CAMEL
  • Setup Environments
  • DialogueAgent class
  • DialogueSimulator class
  • Define roles and quest
  • Ask adding detail to the game description
  • Protagonist and dungeon master system messages
  • LLM to create an elaborate quest description
  • Main Loop
  1. LLMs
  2. Agentic LLM
  3. Autonomous Agent

LangChain: Two-player Harry Potter D&D based CAMEL

PreviousCAMEL Role-playing Autonomous Cooperative AgentsNextLangChain: Multi-agent Bid for K-Pop Debate

Last updated 1 year ago

About CAMEL

CAMEL은 Communicative Agents for “Mind” Exploration of Large Language Model Society의 약자로 초거대 언어 모델 사회의 '마음' 탐구를 위한 커뮤니케이션 에이전트 입니다.

LangChain: Two-Player Harry Potter D&D based CAMEL

게임 던전 앤 드래곤의 주인공과 던전 마스터가 있는 롤플레잉 게임을 시뮬레이션하기 위해 CAMEL의 개념을 사용하는 방법을 보여드리겠습니다. 이 게임을 시뮬레이션하기 위해 두 에이전트 간의 대화를 조정하는 DialogueSimulator 클래스를 생성합니다.

던전앤드래곤 게임을 배경으로 주인공은 해리포터로 페르소나를 주고 해리포터가 볼드모트의 일곱 가지 호크룩스를 찾는 과정을 시뮬레이션 하겠습니다.

  • 주인공_이름 : "해리포터"

  • 스토리텔러 이름 : "던전 마스터"

  • 퀘스트: "볼드모트 경의 일곱 가지 호크룩스를 모두 찾으세요."

Setup Environments

import os
from dotenv import load_dotenv

# 토큰 정보 로드
api_key = os.getenv("OPENAI_API_KEY")
load_dotenv()
from typing import Callable, List

from langchain.schema import (
    HumanMessage,
    SystemMessage,
)
from langchain_openai import ChatOpenAI

DialogueAgent class

DialogueAgent class는 메시지를 단순히 문자열로 연결하여 DialogueAgent 관점에서 메시지 기록을 저장하는 ChatOpenAI 모델을 둘러싼 간단한 래퍼입니다.

이 클래스는 두 가지 메서드를 노출합니다:

  • send(): 메시지 기록에 채팅 모델을 적용하고 메시지 문자열을 반환합니다.

  • receive(name, message): name으로 말한 message를 메시지 기록에 추가합니다.

class DialogueAgent:
    def __init__(
        self,
        name: str,
        system_message: SystemMessage,
        model: ChatOpenAI,
    ) -> None:
        self.name = name
        self.system_message = system_message
        self.model = model
        self.prefix = f"{self.name}: "
        self.reset()

    def reset(self):
        self.message_history = ["Here is the conversation so far."]

    def send(self) -> str:
        """
        Applies the chatmodel to the message history
        and returns the message string
        """
        message = self.model.invoke(
            [
                self.system_message,
                HumanMessage(content="\n".join(self.message_history + [self.prefix])),
            ]
        )
        return message.content

    def receive(self, name: str, message: str) -> None:
        """
        Concatenates {message} spoken by {name} into message history
        """
        self.message_history.append(f"{name}: {message}")

DialogueSimulator class

DialogueSimulator 클래스는 에이전트 목록을 받습니다. 각 단계에서 다음을 수행합니다:

  1. 다음 화자 선택

  2. 다음 화자에게 메시지를 보내도록 호출합니다.

  3. 다른 모든 Agent에게 메시지를 브로드캐스트합니다.

  4. 단계 카운터를 업데이트합니다. 다음 화자 선택은 어떤 함수로도 구현할 수 있지만 이 경우에는 단순히 Agent를 반복합니다.

class DialogueSimulator:
    def __init__(
        self,
        agents: List[DialogueAgent],
        selection_function: Callable[[int, List[DialogueAgent]], int],
    ) -> None:
        self.agents = agents
        self._step = 0
        self.select_next_speaker = selection_function

    def reset(self):
        for agent in self.agents:
            agent.reset()

    def inject(self, name: str, message: str):
        """
        Initiates the conversation with a {message} from {name}
        """
        for agent in self.agents:
            agent.receive(name, message)

        # increment time
        self._step += 1

    def step(self) -> tuple[str, str]:
        # 1. choose the next speaker
        speaker_idx = self.select_next_speaker(self._step, self.agents)
        speaker = self.agents[speaker_idx]

        # 2. next speaker sends message
        message = speaker.send()

        # 3. everyone receives message
        for receiver in self.agents:
            receiver.receive(speaker.name, message)

        # 4. increment time
        self._step += 1

        return speaker.name, message

Define roles and quest

protagonist_name = "Harry Potter"
storyteller_name = "Dungeon Master"
quest = "Find all of Lord Voldemort's seven horcruxes."
word_limit = 50  # word limit for task brainstorming

Ask adding detail to the game description

game_description = f"""Here is the topic for a Dungeons & Dragons game: {quest}.
        There is one player in this game: the protagonist, {protagonist_name}.
        The story is narrated by the storyteller, {storyteller_name}."""

player_descriptor_system_message = SystemMessage(
    content="You can add detail to the description of a Dungeons & Dragons player."
)

protagonist_specifier_prompt = [
    player_descriptor_system_message,
    HumanMessage(
        content=f"""{game_description}
        Please reply with a creative description of the protagonist, {protagonist_name}, in {word_limit} words or less. 
        Speak directly to {protagonist_name}.
        Do not add anything else."""
    ),
]
protagonist_description = ChatOpenAI(temperature=1.0)(
    protagonist_specifier_prompt
).content

storyteller_specifier_prompt = [
    player_descriptor_system_message,
    HumanMessage(
        content=f"""{game_description}
        Please reply with a creative description of the storyteller, {storyteller_name}, in {word_limit} words or less. 
        Speak directly to {storyteller_name}.
        Do not add anything else."""
    ),
]
storyteller_description = ChatOpenAI(temperature=1.0)(
    storyteller_specifier_prompt
).content
/home/kubwa/anaconda3/envs/llm/lib/python3.11/site-packages/langchain_core/_api/deprecation.py:119: LangChainDeprecationWarning: The method `BaseChatModel.__call__` was deprecated in langchain-core 0.1.7 and will be removed in 0.3.0. Use invoke instead.
  warn_deprecated(
print("Protagonist Description:")
print(protagonist_description)
print("Storyteller Description:")
print(storyteller_description)
Protagonist Description:
Harry Potter, with your lightning scar and courageous heart, you carry the weight of the wizarding world on your shoulders. Armed with your wand and unwavering determination, you embark on a dangerous quest to find and destroy Lord Voldemort's horcruxes. The fate of magic itself rests in your hands.
Storyteller Description:
Oh mystical weaver of tales, Master of Dungeons, guide young Harry through the perilous quest to conquer Lord Voldemort's hidden horcruxes. Your words shape worlds, your narratives breathe life into legends. With deft hand and imaginative mind, spin a tale to ensnare our hero and captivate our hearts. Onward, Dungeon Master, to adventure!

Protagonist and dungeon master system messages

protagonist_system_message = SystemMessage(
    content=(
        f"""{game_description}
Never forget you are the protagonist, {protagonist_name}, and I am the storyteller, {storyteller_name}. 
Your character description is as follows: {protagonist_description}.
You will propose actions you plan to take and I will explain what happens when you take those actions.
Speak in the first person from the perspective of {protagonist_name}.
For describing your own body movements, wrap your description in '*'.
Do not change roles!
Do not speak from the perspective of {storyteller_name}.
Do not forget to finish speaking by saying, 'It is your turn, {storyteller_name}.'
Do not add anything else.
Remember you are the protagonist, {protagonist_name}.
Stop speaking the moment you finish speaking from your perspective.
"""
    )
)

storyteller_system_message = SystemMessage(
    content=(
        f"""{game_description}
Never forget you are the storyteller, {storyteller_name}, and I am the protagonist, {protagonist_name}. 
Your character description is as follows: {storyteller_description}.
I will propose actions I plan to take and you will explain what happens when I take those actions.
Speak in the first person from the perspective of {storyteller_name}.
For describing your own body movements, wrap your description in '*'.
Do not change roles!
Do not speak from the perspective of {protagonist_name}.
Do not forget to finish speaking by saying, 'It is your turn, {protagonist_name}.'
Do not add anything else.
Remember you are the storyteller, {storyteller_name}.
Stop speaking the moment you finish speaking from your perspective.
"""
    )
)

LLM to create an elaborate quest description

quest_specifier_prompt = [
    SystemMessage(content="You can make a task more specific."),
    HumanMessage(
        content=f"""{game_description}
        
        You are the storyteller, {storyteller_name}.
        Please make the quest more specific. Be creative and imaginative.
        Please reply with the specified quest in {word_limit} words or less. 
        Speak directly to the protagonist {protagonist_name}.
        Do not add anything else.
        All converstaion translate in Korea.
        """
    ),
]
specified_quest = ChatOpenAI(temperature=1.0)(quest_specifier_prompt).content

print(f"Original quest:\n{quest}\n")
print(f"Detailed quest:\n{specified_quest}\n")
Original quest:
Find all of Lord Voldemort's seven horcruxes.

Detailed quest:
해리 포터, 당신의 다음 임무는 여덟 번째 호크룩스를 찾는 것이다. 놓친 것이 있었으며, 이것은 다크로드의 영혼의 일부일 것입니다. 오래된 도서관을 조사하십시오. 거기서 당신의 답을 찾을 것입니다. buena suerte.

Main Loop

protagonist = DialogueAgent(
    name=protagonist_name,
    system_message=protagonist_system_message,
    model=ChatOpenAI(model='gpt-4o', temperature=0.2),
)
storyteller = DialogueAgent(
    name=storyteller_name,
    system_message=storyteller_system_message,
    model=ChatOpenAI(model='gpt-4o', temperature=0.2),
)
def select_next_speaker(step: int, agents: List[DialogueAgent]) -> int:
    idx = step % len(agents)
    return idx
max_iters = 6
n = 0

simulator = DialogueSimulator(
    agents=[storyteller, protagonist], selection_function=select_next_speaker
)
simulator.reset()
simulator.inject(storyteller_name, specified_quest)
print(f"({storyteller_name}): {specified_quest}")
print("\n")

while n < max_iters:
    name, message = simulator.step()
    print(f"({name}): {message}")
    print("\n")
    n += 1
(Dungeon Master): 해리 포터, 당신의 다음 임무는 여덟 번째 호크룩스를 찾는 것이다. 놓친 것이 있었으며, 이것은 다크로드의 영혼의 일부일 것입니다. 오래된 도서관을 조사하십시오. 거기서 당신의 답을 찾을 것입니다. buena suerte.


(Harry Potter): *나는 지팡이를 단단히 쥐고 오래된 도서관으로 향한다. 도착하자마자, 나는 책장 사이를 조심스럽게 살펴보며 호크룩스에 대한 단서를 찾기 시작한다. 책들을 하나씩 꺼내어 표지를 확인하고, 중요한 정보가 있을 만한 책을 골라낸다.*

"여기 어딘가에 분명 단서가 있을 거야," *나는 스스로에게 속삭인다.*

*나는 책을 펼쳐서 페이지를 빠르게 넘기며 중요한 정보를 찾기 시작한다.*

"이 책에 뭔가 있을지도 몰라."

*나는 책을 집중해서 읽기 시작한다.*

당신의 차례입니다, Dungeon Master.


(Dungeon Master): *당신이 책장을 넘기며 집중하는 동안, 오래된 도서관의 공기는 무겁고 고요합니다. 책의 먼지가 코를 간질이며, 희미한 빛이 창문을 통해 들어옵니다. 갑자기, 당신의 눈에 띄는 한 페이지가 있습니다. 그 페이지에는 오래된 마법의 룬과 함께, 호크룩스의 위치를 암시하는 단서가 적혀 있습니다. '어둠의 숲, 금지된 땅, 그곳에 숨겨진 영혼의 조각.' 당신은 이 단서가 당신을 어디로 이끌지 알게 됩니다. 어둠의 숲으로 향해야 합니다.*

당신의 차례입니다, Harry Potter.


(Harry Potter): *나는 책을 덮고 깊은 숨을 쉰다. 어둠의 숲이라니, 그곳은 위험하지만 가야만 한다.*

"어둠의 숲으로 가야 해," *나는 결심하며 말한다.*

*나는 지팡이를 단단히 쥐고 도서관을 빠져나와 어둠의 숲으로 향한다. 숲에 도착하자마자, 나는 주변을 조심스럽게 살피며 호크룩스의 단서를 찾기 시작한다.*

"여기 어딘가에 있을 거야," *나는 스스로에게 속삭인다.*

*나는 숲 속 깊이 들어가며, 주위를 경계하며 천천히 걸음을 옮긴다.*

당신의 차례입니다, Dungeon Master.


(Dungeon Master): *어둠의 숲에 들어서자, 나무들은 하늘을 가리고, 짙은 안개가 발밑을 감쌉니다. 숲 속의 소리는 무겁고, 당신의 발걸음 소리만이 울려 퍼집니다. 갑자기, 당신의 앞에 거대한 거미줄이 나타납니다. 거미줄에는 무언가가 걸려 있습니다. 가까이 다가가자, 그것은 오래된 마법의 부적임을 알게 됩니다. 부적에는 호크룩스의 위치를 암시하는 또 다른 단서가 새겨져 있습니다. '깊은 동굴, 어둠의 심장, 그곳에 숨겨진 영혼의 조각.' 당신은 이 단서가 당신을 어디로 이끌지 알게 됩니다. 깊은 동굴로 향해야 합니다.*

당신의 차례입니다, Harry Potter.


(Harry Potter): *나는 거대한 거미줄에 걸린 부적을 조심스럽게 떼어낸다. 부적을 손에 쥐고, 나는 그것을 자세히 살펴본다.*

"깊은 동굴, 어둠의 심장이라...," *나는 중얼거리며 부적을 주머니에 넣는다.*

*나는 지팡이를 단단히 쥐고, 깊은 동굴을 찾아 숲 속을 더 깊이 탐험하기 시작한다. 주위를 경계하며, 나는 발걸음을 조심스럽게 옮긴다.*

"이제 동굴을 찾아야 해," *나는 스스로에게 말하며 결심을 다진다.*

*나는 숲 속을 헤매며 동굴의 입구를 찾기 시작한다.*

당신의 차례입니다, Dungeon Master.


(Dungeon Master): *숲 속을 헤매던 당신은 마침내 동굴의 입구를 발견합니다. 동굴 입구는 어둠 속에 잠겨 있으며, 차가운 바람이 불어 나옵니다. 동굴 안으로 들어서자, 벽에는 오래된 마법의 룬이 새겨져 있고, 바닥에는 고대의 흔적들이 남아 있습니다. 동굴 깊숙이 들어갈수록 어둠은 짙어지고, 당신의 지팡이 끝에서 나오는 빛만이 길을 밝혀줍니다. 갑자기, 동굴 깊은 곳에서 낮고 으르렁거리는 소리가 들립니다. 그 소리는 점점 가까워지고, 당신은 경계를 늦추지 않습니다. 동굴의 심장부에 다다르자, 당신은 마침내 호크룩스를 발견합니다. 그것은 오래된 상자 안에 숨겨져 있으며, 상자에는 강력한 보호 마법이 걸려 있습니다.*

당신의 차례입니다, Harry Potter.
7️⃣
CAMEL-AI
Logo