langchain-ai / langchain

🦜🔗 Build context-aware reasoning applications
https://python.langchain.com
MIT License
88.68k stars 13.94k forks source link

crewai use langchain_community.chat_models.BedrockChat as llm get error "System message must be at beginning of message list" #18909

Closed stevensu1977 closed 2 weeks ago

stevensu1977 commented 3 months ago

Checked other resources

Example Code

I only use BedrockChat replace ChatAnthropic , get error.

my code

import boto3
from crewai import Agent, Crew
from crewai import Task
from langchain.tools import DuckDuckGoSearchRun
import os
#from langchain_anthropic import ChatAnthropic
from langchain_community.chat_models import BedrockChat

# llm = ChatAnthropic(temperature=0, model_name="anthropic.claude-3-sonnet-20240229-v1:0")

bedrock_runtime = boto3.client(
    service_name="bedrock-runtime",
    region_name="us-west-2",
)

model_id = "anthropic.claude-3-sonnet-20240229-v1:0"

model_kwargs =  { 
    "max_tokens": 2048,
    "temperature": 0.0,
    "top_k": 250,
    "top_p": 1,
    "stop_sequences": ["\n\nHuman"],
}

llm = BedrockChat(
    client=bedrock_runtime,
    model_id=model_id,
    model_kwargs=model_kwargs,
)

search_tool = DuckDuckGoSearchRun()

# Define your agents with roles and goals
researcher = Agent(
    role="Tech Research",
    goal='Uncover cutting-edge developments in AI and data science',
    backstory="""You work at a leading tech think tank.
    Your expertise lies in identifying emerging trends.
    You have a knack for dissecting complex data and presenting
    actionable insights.""",
    verbose=True,
    allow_delegation=False,
    llm=llm,
    tools=[search_tool]
)

writer = Agent(
    role='Tech Content Summarizer and Writer',
    goal='Craft compelling short-form content on AI advancements based on long-form text passed to you ',
    backstory="""You are a renowned Content Creator, known for your insightful and engaging articles.
    You transform complex concepts into compelling narratives.""",
    verbose=True,
    allow_delegation=True,
    llm=llm,

)

# Create tasks for your agents
task1 = Task(
    description=f"""Conduct a comprehensive analysis of the latest advancements in AI in 2024.
        Identify key trends, breakthrough technologies, and potential industry impacts.
        Your final answer MUST be a full analysis report""",
    agent=researcher
)

task2 = Task(
    description="""Using the text provided by the reseracher agent, develop a short and compelling
    short-form summary of the text provided to you about AI.""",
    agent=writer
)

# Instantiate your crew with a sequential process
NewsletterCrew = Crew(
    agents=[researcher, writer],
    tasks=[task1, task2],
    verbose=2,  # You can set it to 1 or 2 for different logging levels
)

result = NewsletterCrew.kickoff()

print("Welcome to newsletter writer")
print('----------------------------')

print(result)

Error Message and Stack Trace (if applicable)

"Failed to convert text into a pydantic model due to the following error: System message must be at beginning of message list"

Description

I use crewai with langchain

System Info

langchain==0.1.11 langchain-anthropic==0.1.4 langchain-community==0.0.27 langchain-core==0.1.30 langchain-openai==0.0.5 langchain-text-splitters==0.0.1

stevensu1977 commented 3 months ago

I found reason in langchain_community/chat_models/bedrock, there always raise Value error , crewai may use different messages order , I'm not sure every agent frame have same order , so I add "_move_system_to_front", always put system at first .

if need I can submit PR for this issue.

messages order check code :

for i, message in enumerate(messages): 
        if message.type == "system":
            if i != 0:
                raise ValueError("System message must be at beginning of message list.")
            if not isinstance(message.content, str):
                raise ValueError(
                    "System message must be a string, "
                    f"instead was: {type(message.content)}"
                )
            system = message.content
            continue

I add help function , now it's working.

def _move_system_to_front(messages):
    system_messages = [msg for msg in messages if msg.type== 'system']
    non_system_messages = [msg for msg in messages if msg.type != 'system']
    return system_messages + non_system_messages

......
    system: Optional[str] = None
    formatted_messages: List[Dict] = []
    messages=_move_system_to_front(messages)
    for i, message in enumerate(messages):
        if message.type == "system":
            if i != 0:
                raise ValueError("System message must be at beginning of message list.")
            if not isinstance(message.content, str):
                raise ValueError(
                    "System message must be a string, "
                    f"instead was: {type(message.content)}"
                )
            system = message.content
            continue