ኩሉ ሰብ ሞዴላት ምትእትታው ጽሑፍ ይፈቱ፣ ብግቡእ ምኽንያት ድማ: ዘይተሃንጸ ጽሑፍ ኣብ ምቕራጽ ይበልጹ፣ ብትርጉም ተመሳሳሊ ትሕዝቶ ንምርካብ ዝቐለለ ይገብሩ። ብፍላይ ምስቲ ኣብዚ እዋን’ዚ ካብ ሰነዳትን ካልኦት ጽሑፋዊ ጸጋታትን ኣገዳሲ ሓበሬታ ኣብ ምቕያርን ምውሳድን ዝግበር ዘሎ ትኹረት፡ ዓንዲ ሕቖ መብዛሕትኦም ኣፕሊኬሽናት ራግ ምዃኖም ዘገርም ኣይኮነን። ይኹን እምበር፡ ሓደ ሰብ ክሓቶም ዝኽእል ሕቶታት ንጹር ኣብነታት ኣለዉ፡ እቲ ጽሑፍ ምትእትታው ኣገባብ ኣብ ኣፕሊኬሽናት ራግ ኣበይ ከም ዝሓጽርን ዘይቅኑዕ ሓበሬታ ዘቕርብን እዩ።
ከምቲ ዝተጠቕሰ ጽሑፍ ምትእትታው ንዘይተሃንጸ ጽሑፍ ኣብ ምቕራጽ ብሉጽ እዩ። ብኻልእ ወገን ድማ፡ ምስ ዝተዋደደ ሓበሬታን ስርሓት ከም ምፍታሕ ፡ ምፍራይ ፡ ወይ ምድማር ኣብ ምትሕሓዝ ክንድኡ ብሉጻት ኣይኮኑን። ከምዚ ዝኣመሰለ ቀሊል ሕቶ እሞ ሕሰብ፤
ኣብ 2024 ዝለዓለ ደረጃ ዝረኸበት ፊልም እንታይ እያ?
ነዚ ሕቶ ንምምላስ መጀመርታ ብናይ ምውጻእ ዓመት ክንፍልፍል ኣለና፡ ድሕሪኡ ድማ ብደረጃ ክንሰርዕ ኣለና። ጽሑፍ ምትእትታው ዘለዎ ገርሂ ኣገባብ ከመይ ከም ዝሰርሕ ክንምርምር ኢና፡ ድሕሪኡ ንኸምዚኦም ዝኣመሰሉ ሕቶታት ብኸመይ ከም እንገጥሞም ከነርኢ ኢና። እዚ ጽሑፍ ብሎግ፡ ምስ ከም ምፍታሕ፡ ምፍራይ ወይ ምድማር ዝኣመሰሉ ቅርጻዊ ስርሓት ዳታ ክትሰርሕ ከለኻ፡ ካልኦት ኣቃውማ ዝህቡ መሳርሒታት ከም ፍልጠት ግራፍ ክትጥቀም ከምዘለካ ዘርኢ እዩ።
እቲ ኮድ ኣብ GitHub ይርከብ።
ነዚ ጽሑፍ ብሎግ ፡ ኣብ Neo4j Sandbox ዘሎ ናይ ለበዋታት ፕሮጀክት ክንጥቀመሉ ኢና። እቲ ናይ ለበዋታት ፕሮጀክት ነቲ MovieLens dataset ይጥቀም፣ እዚ ድማ ፊልምታት፣ ተዋሳእቲ፣ ደረጃታትን ተወሳኺ ሓበሬታን ዝሓዘ እዩ።
እዚ ዝስዕብ ኮድ ምስ Neo4j Database ንምትእስሳር LangChain wrapper instantiate ክገብር እዩ፤
os.environ["NEO4J_URI"] = "bolt://44.204.178.84:7687" os.environ["NEO4J_USERNAME"] = "neo4j" os.environ["NEO4J_PASSWORD"] = "minimums-triangle-saving" graph = Neo4jGraph(refresh_schema=False)
ብተወሳኺ፡ ኣብዚ ዝስዕብ ኮድ እትሓልፎ OpenAI API key ከድልየካ እዩ።
os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")
እቲ ዳታቤዝ 10 ሽሕ ፊልምታት ዝሓዘ ኮይኑ፡ ጽሑፍ ምትእትታው ግን ገና ኣይተዓቀበን። ንኹሎም ምትእትታው ከይሕሰብ፡ ነተን 1000 ዝለዓለ ደረጃ ዝረኸባ ፊልምታት Target ዝበሃል ካልኣይ ደረጃ ምልክት ክንገብረለን ኢና :
graph.query(""" MATCH (m:Movie) WHERE m.imdbRating IS NOT NULL WITH m ORDER BY m.imdbRating DESC LIMIT 1000 SET m:Target """)
እንታይ ክትሰፍር ከም ዘለካ ምውሳን ኣገዳሲ ኣብ ግምት ዘእተወ እዩ። ብዓመት ምጽራይን ብደረጃ ምፍራይን ከነርኢ ስለዝኾንና፡ ነቶም ዝርዝራት ካብቲ ዝተሰረተ ጽሑፍ ምግላል ፍትሓዊ ኣይምኾነን። ስለዚ ድማ እየ ድማ ናይ ነፍሲ ወከፍ ፊልም ዝተዘርግሐት ዓመት፡ ደረጃ፡ ኣርእስትን መግለጺን ክሕዝ ዝመረጽኩ።
ንፊልም ዘ ዎልፍ ኦፍ ዎል ስትሪት ክንስርጾ ዝግበኣና ኣብነት ጽሑፍ ኣብዚ ኣሎ፤
plot: Based on the true story of Jordan Belfort, from his rise to a wealthy stock-broker living the high life to his fall involving crime, corruption and the federal government. title: Wolf of Wall Street, The year: 2013 imdbRating: 8.2
እዚ ጽቡቕ ኣገባብ ምትእትታው ቅርጻዊ ዳታ ኣይኮነን ክትብሉ ትኽእሉ ኢኹም፡ ኣነ ድማ ዝበለጸ ኣገባብ ስለ ዘይፈልጥ ኣይምተኻታዕኩን። ምናልባት ኣብ ክንዲ ቁልፊ ዋጋ ዘለዎም ነገራት ናብ ጽሑፍ ወይ ገለ ክንቅይሮም ይግባእ ይኸውን። እንታይ ዝሓሸ ክሰርሕ ከም ዝኽእል ገለ ሓሳባት እንተሃልዩኩም ኣፍልጡኒ።
ኣብ LangChain ዘሎ Neo4j Vector object ካብ_existing_graph ምቹእ ሜላ ኣለዎ ኣብኡ ኣየኖት ናይ ጽሑፍ ባህርያት ኢንኮድ ክኾኑ ከም ዘለዎም ክትመርጽ ትኽእል ኢኻ፤
embedding = OpenAIEmbeddings(model="text-embedding-3-small") neo4j_vector = Neo4jVector.from_existing_graph( embedding=embedding, index_name="movies", node_label="Target", text_node_properties=["plot", "title", "year", "imdbRating"], embedding_node_property="embedding", )
ኣብዚ ኣብነት ንወለዶ ምትእትታው ናይ OpenAI text-embedding-3-small ሞዴል ንጥቀም። ነቲ Neo4jVector ዝበሃል ነገር ካብ_existing_graph ዝብል ሜላ ተጠቒምና ኢና ንጅምሮ። እቲ node_label ዝብል መለክዒ ነቶም ኢንኮድ ክግበረሎም ዘለዎም ኖድታት ይፍልፍል፣ ብፍላይ ድማ ነቶም Target ዝብል ስያመ ዘለዎም። እቲ text_node_properties ዝብል መለክዒ ነቶም ክስረቱ ዘለዎም ናይ መስመር ባህርያት ይገልጽ፣ plot , title , year , ከምኡውን imdbRating ሓዊሱ። ኣብ መወዳእታ፡ embedding_node_property፡ እቶም ዝተፈጥሩ ምትእትታዋት ዝኽዘኑሉ ባህሪ ይገልጽ፡ ከም embedding .
እስከ ኣብ ዛንታኣ ወይ መግለጺኣ ተመርኲስና ፊልም ክንረክብ ብምፍታን ንጀምር፤
pretty_print( neo4j_vector.similarity_search( "What is a movie where a little boy meets his hero?" ) )
ውፅኢታት፥
plot: A young boy befriends a giant robot from outer space that a paranoid government agent wants to destroy. title: Iron Giant, The year: 1999 imdbRating: 8.0 plot: After the death of a friend, a writer recounts a boyhood journey to find the body of a missing boy. title: Stand by Me year: 1986 imdbRating: 8.1 plot: A young, naive boy sets out alone on the road to find his wayward mother. Soon he finds an unlikely protector in a crotchety man and the two have a series of unexpected adventures along the way. title: Kikujiro (Kikujirô no natsu) year: 1999 imdbRating: 7.9 plot: While home sick in bed, a young boy's grandfather reads him a story called The Princess Bride. title: Princess Bride, The year: 1987 imdbRating: 8.1
እቲ ውጽኢት ብሓፈሻ ጽቡቕ ጽኑዕ ይመስል። ኩሉ ግዜ ምስ ጅግንኡ ይራኸብ ድዩ ኣይራኸብን ርግጸኛ እኳ እንተዘይኮንኩ ብቐጻሊ ሓደ ንእሽቶ ወዲ ይሳተፍ ኣሎ። ደሓር ከኣ እቲ ዳታሴት 1000 ፊልምታት ጥራይ ስለዘጠቓልል፡ እቶም ኣማራጺታት ብመጠኑ ድሩታት እዮም።
ሕጂ ገለ መሰረታዊ ምፍታሕ ዝሓትት ሕቶ ንፈትን፤
pretty_print( neo4j_vector.similarity_search( "Which movies are from year 2016?" ) )
ውፅኢታት፥
plot: Six short stories that explore the extremities of human behavior involving people in distress. title: Wild Tales year: 2014 imdbRating: 8.1 plot: A young man who survives a disaster at sea is hurtled into an epic journey of adventure and discovery. While cast away, he forms an unexpected connection with another survivor: a fearsome Bengal tiger. title: Life of Pi year: 2012 imdbRating: 8.0 plot: Based on the true story of Jordan Belfort, from his rise to a wealthy stock-broker living the high life to his fall involving crime, corruption and the federal government. title: Wolf of Wall Street, The year: 2013 imdbRating: 8.2 plot: After young Riley is uprooted from her Midwest life and moved to San Francisco, her emotions - Joy, Fear, Anger, Disgust and Sadness - conflict on how best to navigate a new city, house, and school. title: Inside Out year: 2015 imdbRating: 8.3
መስሓቕ እዩ፡ ካብ 2016 ግን ሓንቲ ፊልም ኣይተመርጸትን። ምናልባት ንኢንኮዲንግ ብዝተፈላለየ ምድላው ጽሑፍ ዝሓሸ ውጽኢት ክንረክብ ንኽእል ንኸውን። ይኹን እምበር፡ ሰነዳት ወይ ኣብዚ ኣብነት፡ ኣብ ንብረት ሜታዳታ ዝተመርኮሰ ፊልምታት ክንፍልፍል ዘድልየና ቀሊል ቅርጻዊ ስርሒት ዳታ ስለዘለና፡ ኣብዚ ጽሑፍ ምትእትታው ተግባራዊ ኣይኮነን። ምፍታሕ ሜታዳታ መብዛሕትኡ ግዜ ልክዕነት ስርዓታት ራግ ንምዕባይ ዝውዕል ጽቡቕ ስርዓት ዘለዎ ሜላ እዩ።
እቲ ዝቕጽል ክንፍትኖ ዝግበኣና ሕቶ ቁሩብ ምፍላይ የድልዮ፤
pretty_print( neo4j_vector.similarity_search("Which movie has the highest imdb score?") )
ውፅኢታት፥
plot: A silent film production company and cast make a difficult transition to sound. title: Singin' in the Rain year: 1952 imdbRating: 8.3 plot: A film about the greatest pre-Woodstock rock music festival. title: Monterey Pop year: 1968 imdbRating: 8.1 plot: This movie documents the Apollo missions perhaps the most definitively of any movie under two hours. Al Reinert watched all the footage shot during the missions--over 6,000,000 feet of it, ... title: For All Mankind year: 1989 imdbRating: 8.2 plot: An unscrupulous movie producer uses an actress, a director and a writer to achieve success. title: Bad and the Beautiful, The year: 1952 imdbRating: 7.9
ምስ IMDb ratings ትፋለጡ እንተኾይንኩም ልዕሊ 8.3 ነጥቢ ዝረኸባ ፊልምታት ብዙሓት ከምዘለዋ ትፈልጡ ኢኹም። ኣብ ዳታቤዝና ዝለዓለ ደረጃ ዝረኸበ ኣርእስቲ ብሓቂ ተኸታታሊ ፊልም እዩ — ባንድ ኦፍ ብራዘርስ — ዝድነቕ 9.6 ደረጃ ዘለዎ። ሕጂ’ውን ውጽኢት ምፍራይ ኣብ ዝመጽእሉ እዋን፡ ጽሑፍ ምትእትታው ድኹም ኣፈጻጽማ ኣለዎ።
ገለ ዓይነት ምድማር ዝሓትት ሕቶ እውን ንመዝኖ፤
pretty_print(neo4j_vector.similarity_search("How many movies are there?"))
ውፅኢታት፥
plot: Ten television drama films, each one based on one of the Ten Commandments. title: Decalogue, The (Dekalog) year: 1989 imdbRating: 9.2 plot: A documentary which challenges former Indonesian death-squad leaders to reenact their mass-killings in whichever cinematic genres they wish, including classic Hollywood crime scenarios and lavish musical numbers. title: Act of Killing, The year: 2012 imdbRating: 8.2 plot: A meek Hobbit and eight companions set out on a journey to destroy the One Ring and the Dark Lord Sauron. title: Lord of the Rings: The Fellowship of the Ring, The year: 2001 imdbRating: 8.8 plot: While Frodo and Sam edge closer to Mordor with the help of the shifty Gollum, the divided fellowship makes a stand against Sauron's new ally, Saruman, and his hordes of Isengard. title: Lord of the Rings: The Two Towers, The year: 2002 imdbRating: 8.7
ኣብዚ ውጽኢት ብርግጽ ሓጋዚ ኣይኮነን ምኽንያቱ ኣርባዕተ ብሃንደበት ዝተሰርሑ ፊልምታት ተመሊሶም ንረክብ። ካብዘን ብሃንደበት ዝተሰርሓ ኣርባዕተ ፊልምታት ነዚ ኣብነት ዝኸውን ብድምር 1000 ፊልምታት መለለዪ ዝገበርናዮምን ዝሰረጽናዮምን ኣለዋ ዝብል መደምደምታ ምርካብ ዳርጋ ዘይከኣል እዩ።
እሞ እንታይ እዩ እቲ መፍትሒ? ቅኑዕ እዩ፦ ከም ምፍታሕ፣ ምፍላይን ምድማርን ዝኣመሰሉ ቅርጻዊ ስርሓት ዘጠቓልሉ ሕቶታት ብዝተዋደደ ዳታ ንኽሰርሑ ዝተዳለዉ መሳርሒታት የድልዮም።
ኣብዚ እዋን እዚ መብዛሕትኦም ሰባት ብዛዕባ text2query ዝብል ኣገባብ ዝሓስቡ ይመስል፣ ሓደ LLM ኣብቲ ዝተዋህበ ሕቶን ስኪማን ተመርኲሱ ምስ ዳታቤዝ ንምትእስሳር ዳታቤዝ ሕቶ የመንጩ። ንNeo4j እዚ text2cypher እዩ፣ ግን ንSQL ዳታቤዛት ዝኸውን text2sql እውን ኣሎ። ይኹን እምበር ብተግባር ዘተኣማምንን ንኣጠቓቕማ ምፍራይ ዝኣክል ድልዱልን ከምዘይኮነ ተረጋጊጹ።
ሳይፈር መግለጺ ወለዶ ገምጋም። ካብቲ ብዛዕባ ገምጋም ሳይፈር ዝገልጽ ጽሑፈይ ዝተወስደ ።
ከም ሰንሰለት ኣተሓሳስባ፡ ውሑዳት ኣብነታት ወይ ረቂቕ ምቅንጃው ዝኣመሰሉ ሜላታት ክትጥቀም ትኽእል ኢኻ፡ ኣብዚ ደረጃ እዚ ግን ልዑል ትኽክለኛነት ምርካብ ዳርጋ ዘይከኣል ኮይኑ ይቕጽል ኣሎ። እቲ text2query ኣገባብ ንቐለልቲ ሕቶታት ኣብ ቀጥታዊ ዳታቤዝ ስኪማታት ጽቡቕ ይሰርሕ፡ ግን ክውንነት ናይ ምፍራይ ከባቢታት ከምኡ ኣይኮነን። ነዚ ንምፍታሕ ድማ፡ ነቲ ናይ ዳታቤዝ ሕቶታት ምፍጣር ዝተሓላለኸ ምዃኑ ካብ LLM ኣርሒቕና ከም ናይ ኮድ ጸገም ንሕዞ፡ ኣብኡ ድማ ኣብ ፋንክሽን እታዎታት ተመርኲስና ብውሳኒ መንገዲ ንሕቶታት ዳታቤዝ ንፈጥር። እቲ ብልጫ ግን ብዋጋ ምጉዳል ተዓጻጻፍነት ዝመጽእ እንተኾነ፡ ብዓቢኡ ዝተመሓየሸ ጽንዓት እዩ። ንኹሉ ክትምልስ ካብ ምፍታን ግን ከኣ ብዘይትኽክል ምግባር፡ ስፍሓት ናይቲ ራግ ኣፕሊኬሽን ኣጽቢብካ ነቶም ሕቶታት ብትኽክል ምምላስ ይሓይሽ።
ኣብ ዳታቤዝ ሕቶታት — ኣብዚ ጉዳይ እዚ፡ Cypher statements — ኣብ ፋንክሽን እታዎታት ዝተመርኮሰ ስለዘለና፡ ናይ LLMs ናይ መሳርሒ ዓቕሚ ክንጥቀመሉ ንኽእል። ኣብዚ መስርሕ እዚ፡ እቲ LLM ኣብ ምእታው ተጠቃሚ ተመርኲሱ ነቶም ዝምልከቶም መለክዒታት ይመልእ፡ እቲ ተግባር ድማ ኣድላዪ ሓበሬታ ምውሳድ ይሕዝ። ነዚ ምርኢት፡ መጀመርታ ክልተ መሳርሒታት ክንተግብር ኢና፡ እቲ ሓደ ንፊልምታት ንምቑጻር፡ እቲ ካልኣይ ድማ ንመዝርዝር፡ ድሕሪኡ ድማ LangGraph ተጠቂምና LLM ወኪል ክንፈጥር ኢና።
ኣብ ኣቐዲሙ ዝተነጸረ ፍልትራት ዝተመርኮሰ ፊልምታት ንምቑጻር ዝሕግዝ መሳርሒ ብምትግባር ኢና ንጅምር። መጀመርታ እቶም ፍልትራት እንታይ ምዃኖም ክንገልጽን ንሓደ LLM መዓስን ብኸመይን ከም እንጥቀመሉ ክንገልጾን ኣሎና፤
class MovieCountInput(BaseModel): min_year: Optional[int] = Field( description="Minimum release year of the movies" ) max_year: Optional[int] = Field( description="Maximum release year of the movies" ) min_rating: Optional[float] = Field(description="Minimum imdb rating") grouping_key: Optional[str] = Field( description="The key to group by the aggregation", enum=["year"] )
LangChain ንናይ ፋንክሽን እታዎታት ንምግላጽ ሓያሎ መንገድታት የቕርብ፡ ኣነ ግን ነቲ Pydantic ኣገባብ እየ ዝመርጽ። ኣብዚ ኣብነት ውጽኢት ፊልም ንምጽራይ ሰለስተ ፍልትራት ኣለዉና፡ min_year, max_year, and min_rating። እዞም መጽረይቲ ኣብ ዝተዋደደ ዳታ ዝተመርኮሱ ኮይኖም፡ ተጠቃሚ ዝኾነ፡ ንኹሎም ወይ ዋላ ሓደ ካብኣቶም ከካትት ስለ ዝመርጽ፡ ኣማራጺ እዮም። ብተወሳኺ፡ ነቲ ፋንክሽን ነቲ ቁጽሪ ብፍሉይ ንብረት ክጥርንፎ ድዩ ኣይጉጅሎን ዝሕብር grouping_key input ኣተኣታትና ኣለና። ኣብዚ ጉዳይ እዚ እቲ እንኮ ዝድገፍ ምጉጅጃል ብዓመት እዩ፣ ከምቲ ኣብ enumsection ዝተገልጸ።
ሕጂ ነቲ ጭቡጥ ፋንክሽን ንገልጾ፤
@tool("movie-count", args_schema=MovieCountInput) def movie_count( min_year: Optional[int], max_year: Optional[int], min_rating: Optional[float], grouping_key: Optional[str], ) -> List[Dict]: """Calculate the count of movies based on particular filters""" filters = [ ("t.year >= $min_year", min_year), ("t.year <= $max_year", max_year), ("t.imdbRating >= $min_rating", min_rating), ] # Create the parameters dynamically from function inputs params = { extract_param_name(condition): value for condition, value in filters if value is not None } where_clause = " AND ".join( [condition for condition, value in filters if value is not None] ) cypher_statement = "MATCH (t:Target) " if where_clause: cypher_statement += f"WHERE {where_clause} " return_clause = ( f"t.`{grouping_key}`, count(t) AS movie_count" if grouping_key else "count(t) AS movie_count" ) cypher_statement += f"RETURN {return_clause}" print(cypher_statement) # Debugging output return graph.query(cypher_statement, params=params)
እቲ movie_count ተግባር ኣብ ኣማራጺ ፍልትራትን ናይ ምጉጅጃል መፍትሕን ተመርኲሱ ፊልምታት ንምቑጻር Cypher query ይፈጥር። ከም ሞጎተ ዝቐረቡ ተዛመድቲ ክብርታት ዘለዎም ዝርዝር መጽረይቲ ብምግላጽ ይጅምር። እቶም መጽረይቲ ነቲ WHERE ዓንቀጽ ብዳይናሚክ ንምህናጽ ይጥቀሙ፣ እዚ ድማ ኣብ መግለጺ ሳይፈር ንዝተገለጹ ናይ ምፍታሕ ኩነታት ንምትግባር ሓላፍነት ኣለዎ፣ እዚ ድማ ነቶም ክብርታት None ዘይኮኑ ኩነታት ጥራይ ሓዊሱ።
ብድሕሪኡ ናይ Cypher ሕቶ RETURN ዓንቀጽ ይህነጽ፣ ወይ በቲ ዝተዋህበ grouping_key ይጥርነፍ ወይ ድማ ጠቕላላ ቁጽሪ ፊልምታት ጥራይ ይቑጸር። ኣብ መወዳእታ እቲ ፋንክሽን ነቲ ሕቶ ይፍጽሞን ውጽኢት ይመልሶን።
እቲ ፋንክሽን ከም ኣድላይነቱ ብዝያዳ ሞጎታትን ዝያዳ ተሳትፎ ዘለዎ ስነ-መጐትን ክናዋሕ ይኽእል እዩ፡ እንተኾነ ግን ሓደ LLM ብትኽክልን ብትኽክልን ክጽውዖ ምእንቲ ንጹር ምዃኑ ምርግጋጽ ኣገዳሲ እዩ።
ሕጂ ውን ናይቲ ፋንክሽን ሞጎተታት ብምግላጽ ክንጅምር ኣለና፤
class MovieListInput(BaseModel): sort_by: str = Field( description="How to sort movies, can be one of either latest, rating", enum=["latest", "rating"], ) k: Optional[int] = Field(description="Number of movies to return") description: Optional[str] = Field(description="Description of the movies") min_year: Optional[int] = Field( description="Minimum release year of the movies" ) max_year: Optional[int] = Field( description="Maximum release year of the movies" ) min_rating: Optional[float] = Field(description="Minimum imdb rating")
ከምቲ ኣብ ፊልም ቆጸራ ፋንክሽን ዘሎ ሰለስተ ፍልትራት ንሕዝ ግን ናይ መግለጺ ሞጎተ ንውስኸሉ። እዚ ስነ-ሞጎት እዚ ንፊልምታት ብመሰረት ዛንታኦም ቬክተር ተመሳሳልነት ምድላይ ተጠቒምና ክንደሊን ክንዝርዝርን የኽእለና። ቅርጻዊ መሳርሕታትን ፍልትራትን ስለንጥቀም ጥራይ፡ ጽሑፍ ምትእትታውን ኣገባብ ምድላይ ቬክተርን ክንሕውስ ኣይንኽእልን ማለት ኣይኮነን። መብዛሕትኡ ግዜ ኩለን ፊልምታት ክንመልሳ ስለዘይንደሊ፡ ኣማራጺ k ምእታው ምስ ነባሪ ዋጋ ነካትት። ብተወሳኺ፡ ንምዝርዛር፡ እተን ፊልምታት እተን ኣዝየን ኣገደስቲ ጥራይ ንኽምለሳ ክንሰርዐን ንደሊ። ኣብ ከምዚ ኩነታት ብደረጃ ወይ ዓመት ምውጻእ ክንሰርዖም ንኽእል ኢና።
ነቲ ተግባር ነተግብሮ፤
@tool("movie-list", args_schema=MovieListInput) def movie_list( sort_by: str = "rating", k : int = 4, description: Optional[str] = None, min_year: Optional[int] = None, max_year: Optional[int] = None, min_rating: Optional[float] = None, ) -> List[Dict]: """List movies based on particular filters""" # Handle vector-only search when no prefiltering is applied if description and not min_year and not max_year and not min_rating: return neo4j_vector.similarity_search(description, k=k) filters = [ ("t.year >= $min_year", min_year), ("t.year <= $max_year", max_year), ("t.imdbRating >= $min_rating", min_rating), ] # Create parameters dynamically from function arguments params = { key.split("$")[1]: value for key, value in filters if value is not None } where_clause = " AND ".join( [condition for condition, value in filters if value is not None] ) cypher_statement = "MATCH (t:Target) " if where_clause: cypher_statement += f"WHERE {where_clause} " # Add the return clause with sorting cypher_statement += " RETURN t.title AS title, t.year AS year, t.imdbRating AS rating ORDER BY " # Handle sorting logic based on description or other criteria if description: cypher_statement += ( "vector.similarity.cosine(t.embedding, $embedding) DESC " ) params["embedding"] = embedding.embed_query(description) elif sort_by == "rating": cypher_statement += "t.imdbRating DESC " else: # sort by latest year cypher_statement += "t.year DESC " cypher_statement += " LIMIT toInteger($limit)" params["limit"] = k or 4 print(cypher_statement) # Debugging output data = graph.query(cypher_statement, params=params) return data
እዚ ተግባር እዚ ኣብ ብዙሓት ኣማራጺ መጽረይቲ ዝተመርኮሰ ዝርዝር ፊልምታት ይወስድ: መግለጺ: ደረጃ ዓመት: ዝተሓተ ደረጃ: ከምኡውን ምርጫታት ምድላው። ካልእ መጽረዪ ዘይብሉ መግለጺ ጥራይ እንተተዋሂቡ፡ ኣገደስቲ ፊልምታት ንምርካብ ናይ ቬክተር ኢንዴክስ ተመሳሳልነት ምድላይ ይፍጽም። ተወሳኺ መጽረይቲ ኣብ ግብሪ ክውዕሉ ከለዉ፡ እቲ ተግባር፡ ከም ዓመት ምውጻእን ደረጃ IMDbን ዝኣመሰሉ፡ ከም ዓመት ምውጻእን ደረጃ IMDbን ተመርኲሱ፡ ምስ ኣማራጺ መግለጺ መሰረት ዝገበረ ተመሳሳልነት ብምውህሃድ፡ ንፊልምታት ንምስምማዕ ዝሕግዝ ናይ ሳይፈር ሕቶ ይሃንጽ። ብድሕሪኡ እቲ ውጽኢት ወይ ብናይ ተመሳሳልነት ነጥቢ፡ IMDb ደረጃ፡ ወይ ዓመት ይስርዕ፡ ኣብ k ፊልምታት ድማ ይድረት።
LangGraph ተጠቂምና ቅኑዕ ReAct agent ክንተግብር ኢና።
እቲ ወኪል ብLLMን መሳርሒታትን ስጉምቲ ዝቖመ እዩ። ምስቲ ወኪል ኣብ እንራኸበሉ እዋን፡ መጀመርያ ናብ LLM ደዊልና መሳርሒታት ክንጥቀም እንተኾይንና ክንውስን ኢና። ድሕሪኡ ሓደ ሉፕ ክንጎዪ ኢና፤
እቲ ኮድ ኣተገባብራ ከምቲ ዝረኽቦ ቅኑዕ እዩ። መጀመርታ ነቶም መሳርሒታት ናብቲ LLM ኣሲርና ነቲ ተሓጋጋዚ ስጉምቲ ንገልጾም፤
llm = ChatOpenAI(model='gpt-4-turbo') tools = [movie_count, movie_list] llm_with_tools = llm.bind_tools(tools) # System message sys_msg = SystemMessage(content="You are a helpful assistant tasked with finding and explaining relevant information about movies.") # Node def assistant(state: MessagesState): return {"messages": [llm_with_tools.invoke([sys_msg] + state["messages"])]}
ቀጺልና ንዋሕዚ LangGraph ንገልጾ፤
# Graph builder = StateGraph(MessagesState) # Define nodes: these do the work builder.add_node("assistant", assistant) builder.add_node("tools", ToolNode(tools)) # Define edges: these determine how the control flow moves builder.add_edge(START, "assistant") builder.add_conditional_edges( "assistant", # If the latest message (result) from assistant is a tool call -> tools_condition routes to tools # If the latest message (result) from assistant is a not a tool call -> tools_condition routes to END tools_condition, ) builder.add_edge("tools", "assistant") react_graph = builder.compile()
ኣብ LangGraph ክልተ ኖድ ንገልጾምን ብኩነታዊ ወሰን ነተሓሕዞምን። ሓደ መሳርሒ እንተተጸዊዑ እቲ ዋሕዚ ናብቶም መሳርሒታት ይቐንዕ፤ እንተዘይኮይኑ እቲ ውጽኢት ናብቲ ተጠቃሚ ተመሊሱ ይለኣኽ።
ሕጂ ወኪልና ንፈትኖ፤
messages = [ HumanMessage( content="What are the some movies about a girl meeting her hero?" ) ] messages = react_graph.invoke({"messages": messages}) for m in messages["messages"]: m.pretty_print()
ውፅኢታት፥
ኣብቲ ቀዳማይ ስጉምቲ፡ እቲ ወኪል ነቲ ናይ ፊልም-ዝርዝር መሳርሒ ምስቲ ዝምጥን መግለጺ መለክዒ ክጥቀመሉ ይመርጽ። ስለምንታይ 5 kvalue ከም ዝመርጽ ንጹር ኣይኮነን፡ ግን ነዚ ቁጽሪ ዝድግፍ ይመስል። እቲ መሳርሒ ኣብ ዛንታ ተመርኲሱ ነተን ላዕለዎት ሓሙሽተ ኣገደስቲ ፊልምታት ይመልስ፣ እቲ LLM ድማ ኣብ መወዳእታ ንተጠቃሚ ብቐሊሉ የጠቓልለን።
ChatGPT ንምንታይ k value of 5 ከም ዝፈትዎ እንተሓቲትናዮ እዚ ዝስዕብ መልሲ ንረክብ።
ቀጺልና ቁሩብ ዝተሓላለኸ ሕቶ ንሓትት እዚ ድማ ምፍታሕ ሜታዳታ ዘድልዮ፤
messages = [ HumanMessage( content="What are the movies from the 90s about a girl meeting her hero?" ) ] messages = react_graph.invoke({"messages": messages}) for m in messages["messages"]: m.pretty_print()
ውፅኢታት፥
ኣብዚ ግዜ’ዚ፡ ካብ 1990ታት ዝመጹ ፊልምታት ጥራይ ንምፍታሕ ተወሳኺ ሞጎተታት ተጠቒሞም። እዚ ኣብነት እዚ ንቡር ኣብነት ናይ ሜታዳታ ምፍታሕ ቅድመ ምፍታሕ ኣገባብ ተጠቒምካ ምኾነ። እቲ ዝፍጠር ናይ ሳይፈር መግለጺ መጀመርያ ነተን ፊልምታት ኣብ ዝተዘርግሓሉ ዓመት ብምፍታሕ የጽብበን። ኣብ ዝቕጽል ክፋል፡ መግለጺ ሳይፈር፡ ብዛዕባ ሓንቲ ንእሽቶ ጓል ምስ ጅግናኣ ዝራኸብ ፊልምታት ንምርካብ፡ ጽሑፍ ምትእትታውን ቬክተር ተመሳሳልነት ምድላይን ይጥቀም።
ኣብ ዝተፈላለየ ኩነታት ተመርኲስና ፊልምታት ክንቆጽር ንፈትን፤
messages = [ HumanMessage( content="How many movies are from the 90s have the rating higher than 9.1?" ) ] messages = react_graph.invoke({"messages": messages}) for m in messages["messages"]: m.pretty_print()
ውፅኢታት፥
ንመቑጸሪ ዝኸውን ውፉይ መሳርሒ ምስ ዝህሉ፡ እቲ ዝተሓላለኸ ካብ LLM ናብቲ መሳርሒ ይሰጋገር፡ LLM ድማ ነቶም ዝምልከቶም ናይ ተግባር መለክዒታት ናይ ምምላእ ጥራይ ሓላፍነት ይገድፎ። እዚ ምፍላይ ዕማማት ነቲ ስርዓት ዝያዳ ስሉጥን ድልዱልን ይገብሮን ንዝተሓላለኸነት እታው LLM ይቕንሶን።
እቲ ወኪል ንብዙሓት መሳርሒታት ብተኸታታሊ ወይ ብተመሳሳሊ ክጽውዕ ስለ ዝኽእል፡ ብዝያዳ ዝተሓላለኸ ነገር ንፈትኖ፤
messages = [ HumanMessage( content="How many were movies released per year made after the highest rated movie?" ) ] messages = react_graph.invoke({"messages": messages}) for m in messages["messages"]: m.pretty_print()
ውፅኢታት
ከምቲ ዝተጠቕሰ እቲ ወኪል ነቲ ሕቶ ንምምላስ ኩሉ ዘድሊ ሓበሬታ ንምእካብ ብዙሓት መሳርሒታት ክጽውዕ ይኽእል። ኣብዚ ኣብነት እዚ፡ እታ ዝለዓለ ደረጃ ዝረኸበት ፊልም መዓስ ከም ዝተዘርግሐት ንምልላይ፡ ዝለዓለ ደረጃ ዝረኸባ ፊልምታት ብምዝርዛር ይጅምር። እቲ ዳታ ምስ ረኸበ፡ ከምቲ ኣብቲ ሕቶ ዝተገልጸ ናይ ምጉጅጃል መፍትሕ ብምጥቃም፡ ነቲ ናይ ፊልም ቆጸራ መሳርሒ ብምድዋል፡ ድሕሪ እቲ ዝተወሰነ ዓመት ዝተዘርግሑ ፊልምታት ይእክብ።
ጽሑፍ ምትእትታው ንዘይተሃንጸ ዳታ ንምድላይ ብሉጽ እኳ እንተኾነ፡ ኣብ ከም ምፍታሕ ፡ ምፍራይን ምድማርን ዝኣመሰሉ ቅርጻዊ ስርሓት ክመጽእ ከሎ ግን ይጎድሉ። እዞም ዕማማት እዚኦም ንዝተዋደደ ዳታ ዝተዳለዉ መሳርሒታት ዝጠልቡ ኮይኖም፡ ነዞም ስርሓት ንምሕላው ዘድሊ ትኽክለኛነትን ተዓጻጻፍነትን ይህቡ። እቲ ቁልፊ ምውሳድ፡ ኣብ ስርዓትካ ዘሎ ስብስብ መሳርሒታት ምስፋሕ፡ ንዝሰፍሐ ሕቶታት ተጠቀምቲ ክትምልስ የኽእለካ፡ እዚ ድማ ንኣፕሊኬሽናትካ ዝያዳ ድልዱላትን ብዙሕ ዕዮታት ዘለዎምን ይገብሮም። ቅርጻዊ ኣገባባት ዳታን ዘይተሃንጸ ናይ ጽሑፍ ምድላይ ሜላታትን ምውህሃድ ዝያዳ ቅኑዕን ኣገዳስን መልሲ ክህብ ይኽእል እዩ፣ ኣብ መወዳእታ ድማ ኣብ መተግበሪታት ራግ ዘሎ ተመኩሮ ተጠቃሚ ከዕቢ ይኽእል።
ከም ወትሩ እቲ ኮድ ኣብ GitHub ይርከብ።
ብዛዕባ እዚ ኣርእስቲ ዝያዳ ንምፍላጥ፡ ኣብቲ ንዕለት 7 ሕዳር ዝካየድ NODES 2024 ተጸንበሩና፡ እዚ ድማ ብዛዕባ በሊሕ ኣፕስ፡ ፍልጠት ግራፍን AIን ዝምልከት ነጻ ቨርቹዋል ዲቨሎፐር ዋዕላና እዩ። ሕጂ ተመዝገቡ!