LangChain કૌશલ્યો મોડેલ પ્રેક્ટિસ: માંગ પર જ્ઞાન લોડ કરીને SQL સહાયકનું નિર્માણ
અગાઉના લેખમાં, અમે ચર્ચા કરી હતી કે કેવી રીતે ડીપ એજન્ટ્સ CLI દ્વારા કૌશલ્યોનો ઉપયોગ કરીને ડીપ એજન્ટનું અનુકરણ કરવું. આજે, LangChain મૂળ રીતે આ સુવિધાને સમર્થન આપે છે, જે વિકાસ પ્રક્રિયાને મોટા પ્રમાણમાં સરળ બનાવે છે. આ લેખ તમને આ કાર્યક્ષમતાનો ઊંડો અનુભવ કરાવશે અને વધુ સ્માર્ટ SQL સહાયક બનાવશે.
જટિલ AI એજન્ટો બનાવતી વખતે, વિકાસકર્તાઓ ઘણીવાર દ્વિધામાં મુકાઈ જાય છે: શું બધા સંદર્ભો (ડેટાબેઝ ટેબલ સ્ટ્રક્ચર, API દસ્તાવેજો, વ્યવસાય નિયમો) એક જ સમયે સિસ્ટમ પ્રોમ્પ્ટમાં દાખલ કરવા, જેના કારણે સંદર્ભ વિન્ડો (Context Window) ઓવરફ્લો થાય અને મોડેલનું ધ્યાન ભટકાય? અથવા વારંવાર ફાઇન-ટ્યુનિંગ (Fine-tuning) પસંદ કરવું જે ખર્ચાળ છે?
કૌશલ્યો મોડેલ (Skills Pattern) એક ભવ્ય મધ્યમ માર્ગ પ્રદાન કરે છે. તે જરૂરી જ્ઞાનને ગતિશીલ રીતે લોડ કરીને સંદર્ભનો કાર્યક્ષમ ઉપયોગ કરે છે. આ મોડેલ માટે LangChain નું મૂળ સમર્થન સૂચવે છે કે આપણે "માંગ પર શીખવાની" ક્ષમતાવાળા એજન્ટોને વધુ સરળતાથી બનાવી શકીએ છીએ.
આ લેખ સત્તાવાર દસ્તાવેજ Build a SQL assistant with on-demand skills સાથે જોડાશે અને વાચકોને શરૂઆતથી જ "માંગ પર જ્ઞાન લોડ કરવા" ને સમર્થન આપતા SQL સહાયકનું નિર્માણ કરવા માટે માર્ગદર્શન આપશે.
1. મુખ્ય ખ્યાલ: કૌશલ્યો મોડેલ શા માટે પસંદ કરવું?
પરંપરાગત SQL એજન્ટની મર્યાદાઓ
પરંપરાગત SQL એજન્ટ આર્કિટેક્ચરમાં, આપણે સામાન્ય રીતે સિસ્ટમ પ્રોમ્પ્ટમાં સંપૂર્ણ ડેટાબેઝ સ્કીમા પ્રદાન કરવાની જરૂર પડે છે. વ્યવસાયના વિકાસ સાથે, જ્યારે કોષ્ટકોની સંખ્યા સેંકડો સુધી વિસ્તરે છે, ત્યારે આ અભિગમ નોંધપાત્ર સમસ્યાઓ લાવશે:
-
ટોકનનો વપરાશ વિશાળ છે: દરેક સંવાદ મોટી સંખ્યામાં અસંબંધિત કોષ્ટક સ્ટ્રક્ચર્સ સાથે આવે છે, જેનાથી સંસાધનોનો વ્યય થાય છે.
-
ભ્રમણાનું જોખમ વધે છે: ઘણી બધી અસંબંધિત દખલગીરી મોડેલની તર્કની ચોકસાઈ ઘટાડશે.
-
જાળવણી મુશ્કેલ છે: તમામ વ્યવસાય લાઇનનું જ્ઞાન એકબીજા સાથે ગાઢ રીતે જોડાયેલું છે, જેને સ્વતંત્ર રીતે પુનરાવર્તિત કરવું મુશ્કેલ છે.
કૌશલ્યો મોડેલ: ક્રમિક જાહેરાત પર આધારિત ઉકેલ
કૌશલ્યો મોડેલ ક્રમિક જાહેરાત (Progressive Disclosure) ના સિદ્ધાંત પર આધારિત છે, જે જ્ઞાન સંપાદન પ્રક્રિયાને સ્તરોમાં વિભાજિત કરે છે:
-
એજન્ટની પ્રારંભિક સ્થિતિ: ફક્ત કઈ "કુશળતાઓ" (Skills) છે અને તેનું સંક્ષિપ્ત વર્ણન (Description) જાણે છે, જે હળવા વજનનું રહે છે.
-
રનટાઇમ લોડિંગ: જ્યારે કોઈ ચોક્કસ સમસ્યાનો સામનો કરવો પડે (જેમ કે "ઇન્વેન્ટરી પૂછપરછ"), ત્યારે એજન્ટ સક્રિયપણે સાધન (
load_skill) ને તે કુશળતાના વિગતવાર સંદર્ભ (Schema + Prompt) ને લોડ કરવા માટે બોલાવે છે. -
કાર્ય અમલ: લોડ કરેલા ચોક્કસ સંદર્ભના આધારે, ચોક્કસ કાર્યો કરો (જેમ કે SQL લખવું અને ચલાવવું).
આ મોડેલ અસરકારક રીતે અમર્યાદિત વિસ્તરણ અને ટીમ ડીકપલિંગ ને સમર્થન આપે છે, જે એજન્ટને વધુને વધુ જટિલ વ્યવસાય દૃશ્યોને અનુકૂલિત થવા દે છે.
2. સિસ્ટમ આર્કિટેક્ચર ડિઝાઇન
આ પ્રેક્ટિકલ પ્રોજેક્ટ બે મુખ્ય કૌશલ્યો ધરાવતા SQL સહાયકનું નિર્માણ કરશે, જે આ મોડેલની વાસ્તવિક એપ્લિકેશન દર્શાવે છે:
-
Sales Analytics (વેચાણ વિશ્લેષણ):
sales_dataકોષ્ટક માટે જવાબદાર, આવક આંકડા, ઓર્ડર વલણ વિશ્લેષણ વગેરેનું સંચાલન કરે છે. -
Inventory Management (ઇન્વેન્ટરી મેનેજમેન્ટ):
inventory_itemsકોષ્ટક માટે જવાબદાર, ઇન્વેન્ટરી સ્તરની દેખરેખ, સ્થાન પૂછપરછ વગેરેનું સંચાલન કરે છે.
3. વિકાસ પર્યાવરણ સેટઅપ
આ પ્રોજેક્ટ કાર્યક્ષમ અવલંબન વ્યવસ્થાપન માટે Pythonuv નો ઉપયોગ કરે છે.
મુખ્ય અવલંબન સ્થાપિત કરો
uv add langchain langchain-openai langgraph psycopg2-binary python-dotenv langchain-community
PostgreSQL પર્યાવરણ રૂપરેખાંકન
સ્થાનિક રીતે Postgres ઉદાહરણ શરૂ કરો અનેagent_platformડેટાબેઝ બનાવો. અમે કોષ્ટક સ્ટ્રક્ચર અને પરીક્ષણ ડેટાને આપમેળે શરૂ કરવા માટેsetup_db.pyસ્ક્રિપ્ટ પ્રદાન કરી છે (વિગતો માટે લેખના અંતે સ્ત્રોત કોડ જુઓ).
4. મુખ્ય અમલીકરણ પગલાંઓની વિગતવાર સમજૂતી### પગલું 1: ડોમેન કૌશલ્યોને વ્યાખ્યાયિત કરો (જ્ઞાન)
અમે કૌશલ્યોને ડિક્શનરી સ્ટ્રક્ચર તરીકે વ્યાખ્યાયિત કરીશું, જે ફાઇલ સિસ્ટમ અથવા ડેટાબેઝમાંથી લોડ કરવાની પ્રક્રિયાનું અનુકરણ કરે છે. કૃપા કરીને description (એજન્ટને નિર્ણય લેવામાં અને પસંદગી કરવામાં મદદ કરે છે) અને content (વાસ્તવિક લોડ થયેલ વિગતવાર સંદર્ભ) વચ્ચે તફાવત કરો.
SKILLS = {"sales_analytics": {"description":"વેચાણની આવક, વલણોનું વિશ્લેષણ કરવા માટે ઉપયોગી...","content":"""... Table Schema: sales_data ..."" },"inventory_management": {"description":"સ્ટોક લેવલ તપાસવા માટે ઉપયોગી...","content":"""... Table Schema: inventory_items ..."" }}
પગલું 2: મુખ્ય સાધનોનો અમલ કરો (ક્ષમતાઓ)
એજન્ટને કાર્ય પૂર્ણ કરવા માટે બે મહત્વપૂર્ણ સાધનો પર આધાર રાખે છે:
-
load_skill(skill_name): રનટાઇમ પર ઉલ્લેખિત કૌશલ્યની વિગતોને ગતિશીલ રીતે લોડ કરે છે. -
run_sql_query(query): ચોક્કસ SQL સ્ટેટમેન્ટ ચલાવે છે.
પગલું 3: એજન્ટ લોજિકનું આયોજન કરો (મગજ)
LangGraph નો ઉપયોગ કરીને ReAct એજન્ટ બનાવો. સિસ્ટમ પ્રોમ્પ્ટ અહીં મહત્વપૂર્ણ ભૂમિકા ભજવે છે, તે એજન્ટને Identify -> Load -> Query ના સ્ટાન્ડર્ડ ઓપરેટિંગ પ્રોસિજર (SOP) નું સખતપણે પાલન કરવા માટે માર્ગદર્શન આપે છે.
system_prompt ="""1. Identify the relevant skill.2. Use 'load_skill' to get schema.3. Write and execute SQL using 'run_sql_query'....Do not guess table names. Always load the skill first."""
5. રનિંગ ઇફેક્ટ વેરિફિકેશન
test_agent.py ચલાવીને, અમે વેચાણ અને ઇન્વેન્ટરીના બે અલગ-અલગ ડોમેન્સ માટે ક્વેરીનું પરીક્ષણ કર્યું. નીચે કન્સોલના વાસ્તવિક આઉટપુટ લોગ્સ છે, જે દર્શાવે છે કે એજન્ટ પ્રશ્નના આધારે ગતિશીલ રીતે કૌશલ્યોને કેવી રીતે લોડ કરે છે:
Testing Sales Query...Agent calling tools: [{'name': 'load_skill', 'args': {'skill_name': 'sales_analytics'}, 'id': 'call_f270d76b7ce4404cb5f61bf2', 'type': 'tool_call'}]Tool output:You are a Sales Analytics Expert.You have access to the 'sales_data' table.Table Schema:- id: integer...Agent calling tools: [{'name': 'run_sql_query', 'args': {'query': 'SELECT SUM(amount) as total_revenue FROM sales_data;'}, 'id': 'call_b4f3e686cc7f4f22b3bb9ea7', 'type': 'tool_call'}]Tool output: [(Decimal('730.50'),)]...Agent response: The total revenue is $730.50.Testing Inventory Query...Agent calling tools: [{'name': 'load_skill', 'args': {'skill_name': 'inventory_management'}, 'id': 'call_18c823b2d5064e95a0cfe2e3', 'type': 'tool_call'}]Tool output:You are an Inventory Management Expert.You have access to the 'inventory_items' table.Table Schema...Agent calling tools: [{'name': 'run_sql_query', 'args': {'query': "SELECT warehouse_location FROM inventory_items WHERE product_name = 'Laptop';"}, 'id': 'call_647ee3a444804bd98a045f00', 'type': 'tool_call'}]Tool output: [('Warehouse A',)]...Agent response: The Laptop is located in **Warehouse A**.## 6. સંપૂર્ણ સોર્સ કોડ સંદર્ભ
નીચે પ્રોજેક્ટનો સંપૂર્ણ સોર્સ કોડ છે, જેમાં ડેટાબેઝ ઇનિશિયલાઇઝેશન સ્ક્રિપ્ટ અને એજન્ટ મુખ્ય પ્રોગ્રામ શામેલ છે.
1. ડેટાબેઝ ઇનિશિયલાઇઝેશન (setup_db.py)
importpsycopg2frompsycopg2.extensionsimportISOLATION_LEVEL_AUTOCOMMITimportosfromdotenvimportload_dotenvload_dotenv()# કૃપા કરીને ખાતરી કરો કે .env માં ડેટાબેઝ કનેક્શન માહિતી ગોઠવેલી છેDB_HOST = os.getenv("DB_HOST","localhost")DB_PORT = os.getenv("DB_PORT","5432")DB_USER = os.getenv("DB_USER","postgres")DB_PASSWORD = os.getenv("DB_PASSWORD","your_password")# કૃપા કરીને વાસ્તવિક પાસવર્ડ સાથે બદલોDB_NAME = os.getenv("DB_NAME","agent_platform")defcreate_database():try:# નવો DB બનાવવા માટે ડિફોલ્ટ 'postgres' ડેટાબેઝ સાથે કનેક્ટ કરો conn = psycopg2.connect( host=DB_HOST, port=DB_PORT, user=DB_USER, password=DB_PASSWORD, dbname="postgres" ) conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT) cur = conn.cursor()# તપાસો કે ડેટાબેઝ અસ્તિત્વમાં છે કે નહીં cur.execute(f"SELECT 1 FROM pg_catalog.pg_database WHERE datname = '{DB_NAME}'") exists = cur.fetchone() ifnotexists: print(f"Creating database{DB_NAME}...") cur.execute(f"CREATE DATABASE{DB_NAME}") else: print(f"Database{DB_NAME}already exists.") cur.close() conn.close() exceptExceptionase: print(f"Error creating database:{e}")defcreate_tables_and_data():try: conn = psycopg2.connect( host=DB_HOST, port=DB_PORT, user=DB_USER, password=DB_PASSWORD, dbname=DB_NAME ) cur = conn.cursor()# સેલ્સ ટેબલ બનાવો print("Creating sales_data table...") cur.execute(""" CREATE TABLE IF NOT EXISTS sales_data ( id SERIAL PRIMARY KEY, transaction_date DATE, product_id VARCHAR(50), amount DECIMAL(10, 2), region VARCHAR(50) ) """)# ઇન્વેન્ટરી ટેબલ બનાવો print("Creating inventory_items table...") cur.execute(""" CREATE TABLE IF NOT EXISTS inventory_items ( id SERIAL PRIMARY KEY, product_id VARCHAR(50), product_name VARCHAR(100), stock_count INTEGER, warehouse_location VARCHAR(50) ) """)# મોક ડેટા દાખલ કરો print("Inserting mock data...") cur.execute("TRUNCATE sales_data, inventory_items") sales_data = [ ('2023-01-01','P001',100.00,'North'), ('2023-01-02','P002',150.50,'South'), ('2023-01-03','P001',120.00,'East'), ('2023-01-04','P003',200.00,'West'), ('2023-01-05','P002',160.00,'North') ] cur.executemany("INSERT INTO sales_data (transaction_date, product_id, amount, region) VALUES (%s, %s, %s, %s)", sales_data ) inventory_data = [ ('P001','Laptop',50,'Warehouse A'), ('P002','Mouse',200,'Warehouse B'), ('P003','Keyboard',150,'Warehouse A'), ('P004','Monitor',30,'Warehouse C') ] cur.executemany("INSERT INTO inventory_items (product_id, product_name, stock_count, warehouse_location) VALUES (%s, %s, %s, %s)", inventory_data ) conn.commit() cur.close() conn.close() print("Database setup complete.") exceptExceptionase: print(f"Error setting up tables:{e}")if__name__ =="__main__": create_database() create_tables_and_data()### 2. એજન્ટ મુખ્ય પ્રોગ્રામ (main.py)
`import os from typing import Annotated, Literal, TypedDict, Union, Dict from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_core.tools import tool from langchain_core.messages import SystemMessage, HumanMessage, AIMessage, ToolMessage from langchain_community.utilities import SQLDatabase from langchain_community.agent_toolkits import SQLDatabaseToolkit from langgraph.graph import StateGraph, START, END, MessagesState from langgraph.prebuilt import ToolNode, tools_condition
load_dotenv()
--- Configuration ---
BASE_URL = os.getenv("BASIC_MODEL_BASE_URL") API_KEY = os.getenv("BASIC_MODEL_API_KEY") MODEL_NAME = os.getenv("BASIC_MODEL_MODEL") DB_URI = f"postgresql://{os.getenv('DB_USER')}:{os.getenv('DB_PASSWORD')}@{os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('DB_NAME')}"
--- Database Setup ---
db = SQLDatabase.from_uri(DB_URI)
--- Skills Definition ---
SKILLS: Dict[str, Dict[str, str]] = { "sales_analytics": { "description": "Useful for analyzing sales revenue, trends, and regional performance.", "content": """You are a Sales Analytics Expert. You have access to the 'sales_data' table. Table Schema:
- id: integer (primary key)
- transaction_date: date
- product_id: varchar(50)
- amount: decimal(10, 2)
- region: varchar(50) Common queries:
- Total revenue: SUM(amount)
- Revenue by region: GROUP BY region
- Sales trend: GROUP BY transaction_date""" }, "inventory_management": { "description": "Useful for checking stock levels, product locations, and warehouse management.", "content": """You are an Inventory Management Expert. You have access to the 'inventory_item""" s' table.Table Schema:- id: integer (primary key)- product_id: varchar(50)- product_name: varchar(100)- stock_count: integer- warehouse_location: varchar(50)Common queries:- Check stock: WHERE product_name = '...'- Low stock: WHERE stock_count < threshold""" }}# --- Tools ---@tooldefload_skill(skill_name: str)-> str:""" Load the detailed prompt and schema for a specific skill. Available skills: - sales_analytics: For sales, revenue, and transaction analysis. - inventory_management: For stock, products, and warehouse queries. """ skill = SKILLS.get(skill_name)ifnotskill:returnf"Error: Skill '{skill_name}' not found. Available skills:{list(SKILLS.keys())}"returnskill["content"]@tooldefrun_sql_query(query: str)-> str:""" Execute a SQL query against the database. Only use this tool AFTER loading the appropriate skill to understand the schema. """try:returndb.run(query)exceptExceptionase:returnf"Error executing SQL:{e}"@tooldeflist_tables()-> str:"""List all available tables in the database."""returnstr(db.get_usable_table_names())tools = [load_skill, run_sql_query, list_tables]# --- Agent Setup ---llm = ChatOpenAI( base_url=BASE_URL, api_key=API_KEY, model=MODEL_NAME, temperature=0)llm_with_tools = llm.bind_tools(tools)# --- Graph Definition ---classAgentState(MessagesState):# We can add custom state if needed, but MessagesState is sufficient for simple chatpassdefagent_node(state: AgentState): messages = state["messages"] response = llm_with_tools.invoke(messages)return{"messages": [response]}workflow = StateGraph(AgentState)workflow.add_node("agent", agent_node)workflow.add_node("tools", ToolNode(tools))workflow.add_edge(START,"agent")workflow.add_conditional_edges("agent", tools_condition)workflow.add_edge("tools","agent")app = workflow.compile()# --- મુખ્ય કર્યાવહી ---if__name__ =="main": system_prompt ="""તમે મદદરૂપ SQL એસસિસ્ટન્ટ છો.તમારી પેશેવર સ્કિલ્સને એક્સેસ છે જેમાં ડેટાબેસ સ્કીમાસ અને ડોમેન જ્ઞાન શામેલ છે.એક યુજર્સના પ્રશ્નનો જવાબ આપવા માટે:1. સુસંગત સ્કિલ (સેલ્સ_એનાલીધિક્સ અથવા ઇન્વેન્ટરી_મેનેજમેંટ) ઓળખો.એસ.ડેટાબેસ સ્કીમા માટે 'લોડ_સ્કિલ' તરરીક વપરાશ કરો.તમે સ્કિલ લોડ થઇ ગયા પરધારિત, 'રન_સ્ક્યુએલ_ક્વેરી' વાપરીને SQL ક્વેરી લખો અને એક્સેક્યુટ કરો.4. ક્વેરીના પરિણામોને આધારે યુજર્સના પ્રશ્નનો જવાબ આપો.તાબલના નામોનું અનુમાન ન લળણી. હમેશા પહેલી સ્કિલ લોડ કરો.""" print("SQL એસસિસ્ટન્ટ શરૂ થયું. બાહેર થવા 'ક્વુિટ' લખો એક્સિટ થવા.") print("-"*50) messages = [SystemMessage(content=system_prompt)]# પ્રી-વોર્મ કનેક્શન ચેકtry: print(f"ડેટાબેસને કનેક્ટ કર્યું છું:{DB_URI.split('@')[-1]}")exceptExceptionase: print(f"ડેટાબેસ કનેક્શન ચેતવણી:{e}")whileTrue:try: user_input = input("User: ")ifuser_input.lower()in["quit","exit"]:break messages.append(HumanMessage(content=user_input))# એક્સેક્યુશનનું સ્ટ્રીમ કરો print("Agent: ", end="", flush=True) final_response =Noneforeventinapp.stream({"messages": messages}, stream_mode="values"):# 'values' મોડમાં, અમને પૂર્ણ સ્થિતિ મળે છે. અમે ફરસ એક નવું હોય તો જ એલ્લુ એં. last_message = event["messages"][-1]# લેટેસ્ટ સ્થિતી સાથે આપણી સંદેશ આપણા સંદેશ આપણા ઇતિહાસને અડપેટ કરોpass# સ્ટ્રીમ પૂરુ થય થય પછી, વહેલ્લી સ્થિત૮માં આખરી જવાબ છે final_state = app.invoke({"messages": messages}) last_msg = final_state["messages"][-1]ifisinstance(last_msg, AIMessage): print(last_msg.content) messages = final_state["messages"]# Update history print("-"*50)exceptExceptionase: print(f"\nError:{e}")break`





