ಹಿಂದಿನ ಲೇಖನದಲ್ಲಿ, ಡೀಪ್ ಏಜೆಂಟ್ CLI ಮೂಲಕ ಡೀಪ್ ಏಜೆಂಟ್ ಕೌಶಲ್ಯಗಳನ್ನು ಬಳಸುವ ಮಾದರಿಯನ್ನು ಹೇಗೆ ಅನುಕರಿಸುವುದು ಎಂಬುದನ್ನು ನಾವು ಅನ್ವೇಷಿಸಿದ್ದೇವೆ. ಇಂದು, LangChain ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಸ್ಥಳೀಯವಾಗಿ ಬೆಂಬಲಿಸುತ್ತದೆ, ಇದು ಅಭಿವೃದ್ಧಿ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಹೆಚ್ಚು ಸರಳಗೊಳಿಸುತ್ತದೆ. ಈ ಲೇಖನವು ಈ ಕಾರ್ಯವನ್ನು ಆಳವಾಗಿ ಅನುಭವಿಸಲು ಮತ್ತು ಹೆಚ್ಚು ಬುದ್ಧಿವಂತ SQL ಸಹಾಯಕವನ್ನು ನಿರ್ಮಿಸಲು ನಿಮ್ಮನ್ನು ಕರೆದೊಯ್ಯುತ್ತದೆ.
ಸಂಕೀರ್ಣ AI ಏಜೆಂಟ್ ಅನ್ನು ನಿರ್ಮಿಸುವಾಗ, ಡೆವಲಪರ್ಗಳು ಸಾಮಾನ್ಯವಾಗಿ ಒಂದು ಸಮಸ್ಯೆಯನ್ನು ಎದುರಿಸುತ್ತಾರೆ: ಎಲ್ಲಾ ಸನ್ನಿವೇಶಗಳನ್ನು (ಡೇಟಾಬೇಸ್ ಟೇಬಲ್ ರಚನೆ, API ದಾಖಲೆಗಳು, ವ್ಯಾಪಾರ ನಿಯಮಗಳು) ಸಿಸ್ಟಮ್ ಪ್ರಾಂಪ್ಟ್ಗೆ ಒಂದು ಬಾರಿಗೆ ಸೇರಿಸುವುದು, ಇದು ಸನ್ನಿವೇಶ ವಿಂಡೋ (Context Window) ಉಕ್ಕಿ ಹರಿಯಲು ಮತ್ತು ಮಾದರಿಯ ಗಮನವನ್ನು ಬೇರೆಡೆಗೆ ಸೆಳೆಯಲು ಕಾರಣವಾಗುತ್ತದೆಯೇ? ಅಥವಾ ದುಬಾರಿ ಆಗಾಗ್ಗೆ ಸೂಕ್ಷ್ಮ-ಶ್ರುತಿ (Fine-tuning) ಆಯ್ಕೆ ಮಾಡಿಕೊಳ್ಳುವುದೇ?
ಕೌಶಲ್ಯಗಳ ಮಾದರಿ (Skills Pattern) ಒಂದು ಸೊಗಸಾದ ಮಧ್ಯಂತರ ಮಾರ್ಗವನ್ನು ಒದಗಿಸುತ್ತದೆ. ಅಗತ್ಯವಿರುವ ಜ್ಞಾನವನ್ನು ಕ್ರಿಯಾತ್ಮಕವಾಗಿ ಲೋಡ್ ಮಾಡುವ ಮೂಲಕ, ಇದು ಸನ್ನಿವೇಶದ ಪರಿಣಾಮಕಾರಿ ಬಳಕೆಯನ್ನು ಸಾಧಿಸುತ್ತದೆ. ಈ ಮಾದರಿಗೆ LangChain ನ ಸ್ಥಳೀಯ ಬೆಂಬಲ ಎಂದರೆ "ಬೇಡಿಕೆಯ ಮೇರೆಗೆ ಕಲಿಯುವ" ಸಾಮರ್ಥ್ಯವನ್ನು ಹೊಂದಿರುವ ಏಜೆಂಟ್ ಅನ್ನು ನಾವು ಸುಲಭವಾಗಿ ನಿರ್ಮಿಸಬಹುದು.
ಈ ಲೇಖನವು ಅಧಿಕೃತ ದಾಖಲೆಗಳೊಂದಿಗೆ ಸಂಯೋಜಿಸಲ್ಪಟ್ಟಿದೆ ಬೇಡಿಕೆಯ ಮೇರೆಗೆ ಕೌಶಲ್ಯಗಳೊಂದಿಗೆ SQL ಸಹಾಯಕವನ್ನು ನಿರ್ಮಿಸಿ, ಓದುಗರನ್ನು ಮೊದಲಿನಿಂದಲೂ ಮಾರ್ಗದರ್ಶಿಸುತ್ತದೆ, "ಬೇಡಿಕೆಯ ಮೇರೆಗೆ ಜ್ಞಾನವನ್ನು ಲೋಡ್ ಮಾಡಲು" ಬೆಂಬಲಿಸುವ SQL ಸಹಾಯಕವನ್ನು ನಿರ್ಮಿಸುತ್ತದೆ.
1. ಪ್ರಮುಖ ಪರಿಕಲ್ಪನೆ: ಕೌಶಲ್ಯಗಳ ಮಾದರಿಯನ್ನು ಏಕೆ ಆರಿಸಬೇಕು?
ಸಾಂಪ್ರದಾಯಿಕ SQL ಏಜೆಂಟ್ನ ಮಿತಿಗಳು
ಸಾಂಪ್ರದಾಯಿಕ SQL ಏಜೆಂಟ್ ಆರ್ಕಿಟೆಕ್ಚರ್ನಲ್ಲಿ, ನಾವು ಸಾಮಾನ್ಯವಾಗಿ ಸಿಸ್ಟಮ್ ಪ್ರಾಂಪ್ಟ್ನಲ್ಲಿ ಸಂಪೂರ್ಣ ಡೇಟಾಬೇಸ್ ಸ್ಕೀಮಾವನ್ನು ಒದಗಿಸಬೇಕಾಗುತ್ತದೆ. ವ್ಯಾಪಾರ ಅಭಿವೃದ್ಧಿಯೊಂದಿಗೆ, ಟೇಬಲ್ಗಳ ಸಂಖ್ಯೆ ನೂರಾರು ವರೆಗೆ ವಿಸ್ತರಿಸಿದಾಗ, ಈ ವಿಧಾನವು ಗಮನಾರ್ಹ ಸಮಸ್ಯೆಗಳನ್ನು ತರುತ್ತದೆ:
- ಟೋಕನ್ ಬಳಕೆ ದೊಡ್ಡದಾಗಿದೆ: ಪ್ರತಿ ಸಂವಾದವು ಬಹಳಷ್ಟು ಸಂಬಂಧವಿಲ್ಲದ ಟೇಬಲ್ ರಚನೆಗಳನ್ನು ಒಯ್ಯುತ್ತದೆ, ಇದು ಸಂಪನ್ಮೂಲಗಳ ವ್ಯರ್ಥಕ್ಕೆ ಕಾರಣವಾಗುತ್ತದೆ.
- ಭ್ರಮೆಯ ಅಪಾಯ ಹೆಚ್ಚಾಗುತ್ತದೆ: ಅತಿಯಾದ ಸಂಬಂಧವಿಲ್ಲದ ಹಸ್ತಕ್ಷೇಪ ಮಾಹಿತಿಯು ಮಾದರಿಯ ತಾರ್ಕಿಕ ನಿಖರತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ.
- ನಿರ್ವಹಣೆ ಕಷ್ಟ: ಎಲ್ಲಾ ವ್ಯಾಪಾರ ಮಾರ್ಗಗಳ ಜ್ಞಾನವು ನಿಕಟವಾಗಿ ಜೋಡಿಸಲ್ಪಟ್ಟಿರುತ್ತದೆ, ಸ್ವತಂತ್ರವಾಗಿ ಪುನರಾವರ್ತಿಸಲು ಕಷ್ಟವಾಗುತ್ತದೆ.
ಕೌಶಲ್ಯಗಳ ಮಾದರಿ: ಪ್ರಗತಿಶೀಲ ಬಹಿರಂಗಪಡಿಸುವಿಕೆಯ ಆಧಾರದ ಮೇಲೆ ಪರಿಹಾರ
ಕೌಶಲ್ಯಗಳ ಮಾದರಿಯು ಪ್ರಗತಿಶೀಲ ಬಹಿರಂಗಪಡಿಸುವಿಕೆ (Progressive Disclosure) ತತ್ವವನ್ನು ಆಧರಿಸಿದೆ ಮತ್ತು ಜ್ಞಾನ ಸ್ವಾಧೀನ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಶ್ರೇಣೀಕೃತವಾಗಿ ನಿರ್ವಹಿಸುತ್ತದೆ:
- ಏಜೆಂಟ್ನ ಆರಂಭಿಕ ಸ್ಥಿತಿ: ಯಾವ "ಕೌಶಲ್ಯಗಳು" (Skills) ಇವೆ ಮತ್ತು ಅವುಗಳ ಸಂಕ್ಷಿಪ್ತ ವಿವರಣೆ (Description) ಮಾತ್ರ ತಿಳಿದಿದೆ, ಹಗುರವಾಗಿ ಉಳಿಯುತ್ತದೆ.
- ರನ್ಟೈಮ್ ಲೋಡಿಂಗ್: ನಿರ್ದಿಷ್ಟ ಸಮಸ್ಯೆಯನ್ನು ಎದುರಿಸಿದಾಗ (ಉದಾಹರಣೆಗೆ "ಸ್ಟಾಕ್ ಅನ್ನು ಪ್ರಶ್ನಿಸುವುದು"), ಏಜೆಂಟ್ ಉಪಕರಣವನ್ನು ಸಕ್ರಿಯವಾಗಿ ಕರೆಯುತ್ತದೆ (
load_skill) ಆ ಕೌಶಲ್ಯದ ವಿವರವಾದ ಸನ್ನಿವೇಶವನ್ನು ಲೋಡ್ ಮಾಡಲು (Schema + Prompt).
- ಕಾರ್ಯವನ್ನು ನಿರ್ವಹಿಸಿ: ಲೋಡ್ ಮಾಡಲಾದ ನಿಖರವಾದ ಸನ್ನಿವೇಶದ ಆಧಾರದ ಮೇಲೆ, ನಿರ್ದಿಷ್ಟ ಕಾರ್ಯವನ್ನು ನಿರ್ವಹಿಸಿ (SQL ಅನ್ನು ಬರೆಯುವುದು ಮತ್ತು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು).
ಈ ಮಾದರಿಯು ಅನಂತ ವಿಸ್ತರಣೆ ಮತ್ತು ತಂಡದ ಬೇರ್ಪಡುವಿಕೆಯನ್ನು ಪರಿಣಾಮಕಾರಿಯಾಗಿ ಬೆಂಬಲಿಸುತ್ತದೆ, ಏಜೆಂಟ್ ಹೆಚ್ಚುತ್ತಿರುವ ಸಂಕೀರ್ಣ ವ್ಯಾಪಾರ ಸನ್ನಿವೇಶಗಳಿಗೆ ಹೊಂದಿಕೊಳ್ಳಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ.
2. ಸಿಸ್ಟಮ್ ಆರ್ಕಿಟೆಕ್ಚರ್ ವಿನ್ಯಾಸ
ಈ ಪ್ರಾಯೋಗಿಕ ಯೋಜನೆಯು ಎರಡು ಪ್ರಮುಖ ಕೌಶಲ್ಯಗಳನ್ನು ಒಳಗೊಂಡಿರುವ SQL ಸಹಾಯಕವನ್ನು ನಿರ್ಮಿಸುತ್ತದೆ, ಈ ಮಾದರಿಯ ಪ್ರಾಯೋಗಿಕ ಅನ್ವಯವನ್ನು ಪ್ರದರ್ಶಿಸಲು:
- ಮಾರಾಟ ವಿಶ್ಲೇಷಣೆ (Sales Analytics):
sales_data ಟೇಬಲ್ಗೆ ಜವಾಬ್ದಾರರು, ಆದಾಯ ಅಂಕಿಅಂಶಗಳು, ಆರ್ಡರ್ ಟ್ರೆಂಡ್ ವಿಶ್ಲೇಷಣೆ ಇತ್ಯಾದಿಗಳನ್ನು ನಿರ್ವಹಿಸುತ್ತಾರೆ.
- ದಾಸ್ತಾನು ನಿರ್ವಹಣೆ (Inventory Management):
inventory_items ಟೇಬಲ್ಗೆ ಜವಾಬ್ದಾರರು, ದಾಸ್ತಾನು ಮಟ್ಟದ ಮೇಲ್ವಿಚಾರಣೆ, ಸ್ಥಳ ಪ್ರಶ್ನೆ ಇತ್ಯಾದಿಗಳನ್ನು ನಿರ್ವಹಿಸುತ್ತಾರೆ.
3. ಅಭಿವೃದ್ಧಿ ಪರಿಸರ ಸೆಟಪ್
ಈ ಯೋಜನೆಯು ಪರಿಣಾಮಕಾರಿ ಅವಲಂಬನೆ ನಿರ್ವಹಣೆಗಾಗಿ Python uv ಅನ್ನು ಬಳಸುತ್ತದೆ.
ಪ್ರಮುಖ ಅವಲಂಬನೆ ಸ್ಥಾಪನೆ
uv add langchain langchain-openai langgraph psycopg2-binary python-dotenv langchain-community
PostgreSQL ಪರಿಸರ ಸಂರಚನೆ
ಸ್ಥಳೀಯವಾಗಿ Postgres ನಿದರ್ಶನವನ್ನು ಪ್ರಾರಂಭಿಸಿ ಮತ್ತು agent_platform ಡೇಟಾಬೇಸ್ ಅನ್ನು ರಚಿಸಿ. ಟೇಬಲ್ ರಚನೆ ಮತ್ತು ಪರೀಕ್ಷಾ ಡೇಟಾವನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಪ್ರಾರಂಭಿಸಲು ನಾವು setup_db.py ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಒದಗಿಸಿದ್ದೇವೆ (ವಿವರಗಳಿಗಾಗಿ ಲೇಖನದ ಕೊನೆಯಲ್ಲಿರುವ ಮೂಲ ಕೋಡ್ ನೋಡಿ).
4. ಪ್ರಮುಖ ಅನುಷ್ಠಾನ ಹಂತಗಳ ವಿವರಣೆ
### **ಹಂತ 1: ಡೊಮೇನ್ ಕೌಶಲ್ಯಗಳನ್ನು ವ್ಯಾಖ್ಯಾನಿಸಿ (ಜ್ಞಾನ)**
ನಾವು ಕೌಶಲ್ಯಗಳನ್ನು ನಿಘಂಟು ರಚನೆಯಾಗಿ ವ್ಯಾಖ್ಯಾನಿಸುತ್ತೇವೆ, ಫೈಲ್ ಸಿಸ್ಟಮ್ ಅಥವಾ ಡೇಟಾಬೇಸ್ನಿಂದ ಲೋಡ್ ಮಾಡುವ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಅನುಕರಿಸುತ್ತೇವೆ. `ವಿವರಣೆ` (ಏಜೆಂಟ್ ನಿರ್ಧಾರ ತೆಗೆದುಕೊಳ್ಳಲು ಬಳಸಲಾಗುತ್ತದೆ) ಮತ್ತು `ವಿಷಯ` (ಲೋಡ್ ಮಾಡಲಾದ ವಿವರವಾದ ಸನ್ನಿವೇಶ) ನಡುವೆ ವ್ಯತ್ಯಾಸವನ್ನು ಗುರುತಿಸಲು ದಯವಿಟ್ಟು ಗಮನಿಸಿ.
`SKILLS = {"sales_analytics": {"description":"ಮಾರಾಟ ಆದಾಯ, ಪ್ರವೃತ್ತಿಗಳನ್ನು ವಿಶ್ಲೇಷಿಸಲು ಉಪಯುಕ್ತವಾಗಿದೆ...","content":"""... ಟೇಬಲ್ ಸ್ಕೀಮಾ: sales_data ..."" },"inventory_management": {"description":"ಸ್ಟಾಕ್ ಮಟ್ಟವನ್ನು ಪರಿಶೀಲಿಸಲು ಉಪಯುಕ್ತವಾಗಿದೆ...","content":"""... ಟೇಬಲ್ ಸ್ಕೀಮಾ: inventory_items ..."" }}`
### **ಹಂತ 2: ಪ್ರಮುಖ ಸಾಧನಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿ (ಸಾಮರ್ಥ್ಯಗಳು)**
ಕಾರ್ಯಗಳನ್ನು ಪೂರ್ಣಗೊಳಿಸಲು ಏಜೆಂಟ್ ಎರಡು ಪ್ರಮುಖ ಸಾಧನಗಳನ್ನು ಅವಲಂಬಿಸಿದೆ:
- `load_skill(skill_name)`**: ರನ್ಟೈಮ್ನಲ್ಲಿ ನಿರ್ದಿಷ್ಟ ಕೌಶಲ್ಯದ ವಿವರಗಳನ್ನು ಕ್ರಿಯಾತ್ಮಕವಾಗಿ ಲೋಡ್ ಮಾಡಿ.**
- `run_sql_query(query)`**: ನಿರ್ದಿಷ್ಟ SQL ಹೇಳಿಕೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿ.**
### **ಹಂತ 3: ಏಜೆಂಟ್ ತರ್ಕವನ್ನು ವ್ಯವಸ್ಥೆಗೊಳಿಸಿ (ಮೆದುಳು)**
LangGraph ಅನ್ನು ಬಳಸಿಕೊಂಡು ReAct ಏಜೆಂಟ್ ಅನ್ನು ನಿರ್ಮಿಸಿ. ಸಿಸ್ಟಮ್ ಪ್ರಾಂಪ್ಟ್ ಇಲ್ಲಿ ನಿರ್ಣಾಯಕ ಪಾತ್ರವನ್ನು ವಹಿಸುತ್ತದೆ, ಇದು ಏಜೆಂಟ್ಗೆ `ಗುರುತಿಸಿ -> ಲೋಡ್ -> ಪ್ರಶ್ನೆ` ಪ್ರಮಾಣಿತ ಕಾರ್ಯಾಚರಣಾ ಕಾರ್ಯವಿಧಾನವನ್ನು (SOP) ಕಟ್ಟುನಿಟ್ಟಾಗಿ ಅನುಸರಿಸಲು ಮಾರ್ಗದರ್ಶನ ನೀಡುತ್ತದೆ.
`system_prompt ="""1. ಸಂಬಂಧಿತ ಕೌಶಲ್ಯವನ್ನು ಗುರುತಿಸಿ.2. ಸ್ಕೀಮಾವನ್ನು ಪಡೆಯಲು 'load_skill' ಬಳಸಿ.3. 'run_sql_query' ಬಳಸಿ SQL ಅನ್ನು ಬರೆಯಿರಿ ಮತ್ತು ಕಾರ್ಯಗತಗೊಳಿಸಿ....ಟೇಬಲ್ ಹೆಸರುಗಳನ್ನು ಊಹಿಸಬೇಡಿ. ಯಾವಾಗಲೂ ಮೊದಲು ಕೌಶಲ್ಯವನ್ನು ಲೋಡ್ ಮಾಡಿ.""`
## **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:ನೀವು ಮಾರಾಟ ವಿಶ್ಲೇಷಣೆ ತಜ್ಞರು. ನಿಮಗೆ 'sales_data' ಟೇಬಲ್ಗೆ ಪ್ರವೇಶವಿದೆ. ಟೇಬಲ್ ಸ್ಕೀಮಾ:- 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'),)]...ಏಜೆಂಟ್ ಪ್ರತಿಕ್ರಿಯೆ: ಒಟ್ಟು ಆದಾಯ $730.50 ಆಗಿದೆ.Testing Inventory Query...Agent calling tools: [{'name': 'load_skill', 'args': {'skill_name': 'inventory_management'}, 'id': 'call_18c823b2d5064e95a0cfe2e3', 'type': 'tool_call'}]Tool output:ನೀವು ದಾಸ್ತಾನು ನಿರ್ವಹಣೆ ತಜ್ಞರು. ನಿಮಗೆ 'inventory_items' ಟೇಬಲ್ಗೆ ಪ್ರವೇಶವಿದೆ. ಟೇಬಲ್ ಸ್ಕೀಮಾ...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',)]...ಏಜೆಂಟ್ ಪ್ರತಿಕ್ರಿಯೆ: ಲ್ಯಾಪ್ಟಾಪ್ **ವೇರ್ಹೌಸ್ 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:# ಹೊಸ ಡಿಬಿ ರಚಿಸಲು ಡೀಫಾಲ್ಟ್ '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()
# --- ಸಂರಚನೆ ---
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')}"
# --- ಡೇಟಾಬೇಸ್ ಸೆಟಪ್ ---
db = SQLDatabase.from_uri(DB_URI)
# --- ಕೌಶಲ್ಯಗಳ ವ್ಯಾಖ್ಯಾನ ---
SKILLS: Dict[str, Dict[str, str]] = {
"sales_analytics": {
"description": "ಮಾರಾಟದ ಆದಾಯ, ಪ್ರವೃತ್ತಿಗಳು ಮತ್ತು ಪ್ರಾದೇಶಿಕ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ವಿಶ್ಲೇಷಿಸಲು ಉಪಯುಕ್ತವಾಗಿದೆ.",
"content": """
ನೀವು ಮಾರಾಟ ವಿಶ್ಲೇಷಣೆ ತಜ್ಞರು.
ನಿಮಗೆ 'sales_data' ಟೇಬಲ್ಗೆ ಪ್ರವೇಶವಿದೆ.
ಟೇಬಲ್ ಸ್ಕೀಮಾ:
- id: ಪೂರ್ಣಾಂಕ (ಪ್ರಾಥಮಿಕ ಕೀ)
- transaction_date: ದಿನಾಂಕ
- product_id: varchar(50)
- amount: ದಶಮಾಂಶ(10, 2)
- region: varchar(50)
ಸಾಮಾನ್ಯ ಪ್ರಶ್ನೆಗಳು:
- ಒಟ್ಟು ಆದಾಯ: SUM(amount)
- ಪ್ರದೇಶದ ಪ್ರಕಾರ ಆದಾಯ: GROUP BY region
- ಮಾರಾಟದ ಪ್ರವೃತ್ತಿ: GROUP BY transaction_date"""
},
"inventory_management": {
"description": "ಸ್ಟಾಕ್ ಮಟ್ಟಗಳು, ಉತ್ಪನ್ನ ಸ್ಥಳಗಳು ಮತ್ತು ಗೋದಾಮಿನ ನಿರ್ವಹಣೆಯನ್ನು ಪರಿಶೀಲಿಸಲು ಉಪಯುಕ್ತವಾಗಿದೆ.",
"content": """
ನೀವು ದಾಸ್ತಾನು ನಿರ್ವಹಣೆ ತಜ್ಞರು.
ನಿಮಗೆ 'inventory_items' 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_nodಇ) 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. ಸಂಬಂಧಿತ ಕೌಶಲ್ಯವನ್ನು ಗುರುತಿಸಿ (sales_analytics ಅಥವಾ inventory_management).2. ಸ್ಕೀಮಾ ಮತ್ತು ಸೂಚನೆಗಳನ್ನು ಪಡೆಯಲು 'load_skill' ಟೂಲ್ ಬಳಸಿ.3. ಲೋಡ್ ಮಾಡಿದ ಕೌಶಲ್ಯದ ಆಧಾರದ ಮೇಲೆ, 'run_sql_query' ಬಳಸಿ SQL ಪ್ರಶ್ನೆಯನ್ನು ಬರೆಯಿರಿ ಮತ್ತು ಕಾರ್ಯಗತಗೊಳಿಸಿ.4. ಪ್ರಶ್ನೆಯ ಫಲಿತಾಂಶಗಳ ಆಧಾರದ ಮೇಲೆ ಬಳಕೆದಾರರ ಪ್ರಶ್ನೆಗೆ ಉತ್ತರಿಸಿ.ಟೇಬಲ್ ಹೆಸರುಗಳನ್ನು ಊಹಿಸಬೇಡಿ. ಯಾವಾಗಲೂ ಮೊದಲು ಕೌಶಲ್ಯವನ್ನು ಲೋಡ್ ಮಾಡಿ.""" print("SQL ಸಹಾಯಕ ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ. ನಿರ್ಗಮಿಸಲು 'quit' ಎಂದು ಟೈಪ್ ಮಾಡಿ.") print("-"*50) messages = [SystemMessage(content=system_prompt)]# ಪೂರ್ವ-ಬೆಚ್ಚಗಿನ ಸಂಪರ್ಕ ಪರಿಶೀಲನೆtry: print(f"ಡೇಟಾಬೇಸ್ಗೆ ಸಂಪರ್ಕಿಸಲಾಗಿದೆ:{DB_URI.split('@')[-1]}")exceptExceptionase: print(f"ಡೇಟಾಬೇಸ್ ಸಂಪರ್ಕ ಎಚ್ಚರಿಕೆ:{e}")whileTrue:try: user_input = input("ಬಳಕೆದಾರ: ")ifuser_input.lower()in["quit","exit"]:break messages.append(HumanMessage(content=user_input))# ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಿ print("ಏಜೆಂಟ್: ", 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"]# ಇತಿಹಾಸವನ್ನು ನವೀಕರಿಸಿ print("-"*50)exceptExceptionase: print(f"\nದೋಷ:{e}")break`