Чи потребують глибокі агенти спеціальні моделі? Демонстрація у банківській сфері з LangSmith
LangChain Deep Agents теоретично є незалежним від моделей, але на практиці залежить від них. Агент для банківських операцій із п’ятьма інструментами, проаналізований у LangSmith, показує, яку роль виконує кожна модель.
Джерела: Beyond Simple Agents: Engineering DeepAgents for Enterprise with LangChain — 2
Природним наступним запитанням під час проектування агентів за допомогою фреймворку Deep Agents є те, чи потрібна для ефективної роботи певна модель. Чесна відповідь має дві частини. З архітектурної точки зору Deep Agents не залежить від того, яку модель ви використовуєте. На практиці результати сильно залежать від обраної моделі.
Архітектурно незалежний від моделі
У фреймворку немає нічого, що б примушувало використовувати певну модель, і код це підтверджує. Можна передати будь-яку модель чату:
from langchain.chat_models import init_chat_model
# Swap any model in — the harness doesn't care
agent = create_deep_agent(
model=init_chat_model("openai:gpt-4o"),
tools=[...],
system_prompt="..."
)
# Or Anthropic
agent = create_deep_agent(
model=init_chat_model("anthropic:claude-opus-4-6"),
tools=[...],
)
# Or Google
agent = create_deep_agent(
model=init_chat_model("google_vertexai:gemini-2.0-flash"),
tools=[...],
)
Інструмент планування, файлова система, створення підагентів та детальні запити – ці чотири основи реалізовані на рівні фреймворку. LangGraph забезпечує середовище виконання, а ШІ є просто двигуном міркувань, підключеним до цього середовища.
Практично чутливо до моделей
Фреймворк спирається на поведінкові особливості, які не всі моделі демонструють однаково добре.
- Надійне викликання інструментів. Усій процедурі потрібно, щоб модель викликала інструменти у правильному форматі з коректними аргументами. Слабкіші моделі вигадують назви інструментів, передають неправильні типи параметрів або пропускають виклик та відповідають у прозі.
- Дотримання довгих системних запитів. Вбудовані запити є довгими. Вони прослять модель спочатку спланувати, скористатися списком завдань, ізолювати контекст у підагентах та перевірити власну роботу. Моделі, які погано виконують інструкції, відхиляються від цього підходу вже на середині завдання.
Приблизне розташування моделей
| Рівень моделі | Поведінка з потужним агентом |
|---|---|
| Моделі передового рівня | Надійне використання інструментів, виконання складних запитів, збереження кохерентності протягом довгих завдань |
| Сильні моделі середнього рівня | Підходять для більшості завдань, іноді виникають проблеми під час дуже довгих процесів |
| Менші або моделі з відкритим кодом | |
| Результати роботи непостійні: поширені помилки форматування інструментів, відхилення у виконанні запитів та передчасна зупинка |
Назви рівнів є прикладами на момент написання, а рейтинги моделей швидко змінюються, тому тестуйте їх на власних завданнях.
Висновок
Уявіть собі кузов гоночного автомобіля з можливістю заміни двигуна: що б ви не встановили, максимальна швидкість визначається двигуном. Система підтримки забезпечує структуру: планування, пам’ять, підагенти та маршрутизацію. Модель надає здатність правильно використовувати все це. Для продакшну, особливо в банку, де вигаданий список банкоматів чи сфабрикований інвестиційний офіцер можуть завдати реальної шкоди, використовуйте передові моделі та не економте на їхній якості.
Час створювати щось
Досить теорії. Існує відомий жарт про документацію без коду: двісті сторінок документації, п’ятнадцять діаграм, добре опрацьований файл README, але нічого, що б фактично працювало. Тож ось працююча демонстрація з п’ятьма банківськими інструментами та фіктивними даними.
Швидкий старт
Створіть API-ключ у консолі Anthropic, а потім налаштуйте проект:
mkdir firstdeepagent && cd firstdeepagent
uv add deepagent anthropic
export ANTHROPIC_API_KEY='asdkjfbaepiufas;dkjcnaisdf'
touch agent.py bank_tools.py mock_data.py
Ці команди створюють папку, встановлюють пакети, експортують ключ (використовуйте свій власний справжній ключ, ніколи не комітований) та створюють три файли. Інструменти для bank_tools.py є наступними:
from mock_data import (OFFICERS_DATA, PORTFOLIO_DATA, ATM_DATA,
RETIREMENT_DATA, LOCATIONS_DATA)
def get_atm_centers(zipcode: str) -> dict:
data = ATM_DATA.get(str(zipcode).strip())
if not data:
return {
"error": f"No ATM data for zipcode '{zipcode}'.",
"available_zipcodes": list(ATM_DATA.keys()),
}
return {"zipcode": zipcode, "atm_centers": data, "total": len(data)}
def get_investment_officers(city: str) -> dict:
key = city.strip().lower()
data = OFFICERS_DATA.get(key)
if not data:
return {
"error": f"No investment officers found in '{city}'.",
"available_cities": [c.title() for c in OFFICERS_DATA],
}
return {"city": city, "officers": data, "total": len(data)}
def get_portfolio_companies(sector: str = "all") -> dict:
companies = PORTFOLIO_DATA
if sector and sector.lower() != "all":
companies = [c for c in companies if sector.lower() in c["sector"].lower()]
return {"companies": companies, "total": len(companies), "total_aum": "$6.35B"}
def get_retirement_plans(plan_type: str = "all") -> dict:
plans = RETIREMENT_DATA
if plan_type and plan_type.lower() != "all":
plans = [
p for p in plans
if plan_type.lower() in p["name"].lower() or plan_type.lower() in p["type"].lower()
]
return {"plans": plans, "total": len(plans)}
def get_bank_locations(city: str = "all") -> dict:
locations = LOCATIONS_DATA
if city and city.lower() != "all":
locations = [l for l in locations if city.lower() in l["city"].lower()]
total_branches = sum(l["branches"] for l in locations)
return {"locations": locations, "total_branches": total_branches}
Модуль mock_data містить зразкові записи, а модуль tools-config — схеми інструментів, відповідності між назвами та функціями, а також системний запит. Зберігайте їх у окремих файлах, щоб код агента залишався компактним. Основний цикл у agent.py виглядає так:
import os
import json
import anthropic
from tools_config import TOOL_SCHEMAS, TOOL_FN_MAP, SYSTEM_PROMPT
def run_agent(client: anthropic.Anthropic, conversation: list[dict]) -> str:
MAX_ITERATIONS = 10
messages = list(conversation)
for _ in range(MAX_ITERATIONS):
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system=SYSTEM_PROMPT,
tools=TOOL_SCHEMAS,
messages=messages,
)
tool_use_blocks = [b for b in response.content if b.type == "tool_use"]
if not tool_use_blocks:
text_parts = [b.text for b in response.content if b.type == "text"]
return "\n".join(text_parts).strip()
tool_results = []
for block in tool_use_blocks:
fn = TOOL_FN_MAP.get(block.name)
result = fn(**block.input) if fn else {"error": f"Unknown tool: {block.name}"}
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result),
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
return "[Max iterations reached — partial answer may be incomplete.]"
def main():
api_key = os.environ.get("ANTHROPIC_API_KEY")
if not api_key:
print("Error: ANTHROPIC_API_KEY environment variable not set.")
print(" export ANTHROPIC_API_KEY=your_key_here")
raise SystemExit(1)
client = anthropic.Anthropic(api_key=api_key)
conversation: list[dict] = []
print("XYZ Bank Agent — type 'quit' to exit.\n")
while True:
try:
user_input = input("You > ").strip()
except (EOFError, KeyboardInterrupt):
print("\nGoodbye!")
break
if not user_input:
continue
if user_input.lower() in {"quit", "exit", "q"}:
print("Goodbye!")
break
conversation.append({"role": "user", "content": user_input})
answer = run_agent(client, conversation)
conversation.append({"role": "assistant", "content": answer})
print(f"\n{answer}\n")
if __name__ == "__main__":
main()
Запуск
Переконайтеся, що ключ експортований, а потім запустіть агента за допомогою uv run agent.py. Приклад сеансу:
XYZ Bank Agent — type 'quit' to exit.
You > Who are the investment officers in Chicago? Also what retirement plans do you offer?
Here's everything you need!
---
## 👔 Investment Officers in Chicago
| Name | Title | Specialty | Phone | Email |
|---|---|---|---|---|
| **Margaret Chen** | Senior Investment Officer | Equities & ETFs | 312-555-0101 | m.chen@xyzbank.com |
| **David Okafor** | Investment Officer | Fixed Income | 312-555-0182 | d.okafor@xyzbank.com |
| **Sarah Kowalski** | Wealth Manager | Retirement Planning | 312-555-0147 | s.kowalski@xyzbank.com |
---
## 🏦 Retirement Plans Offered by XYZ Bank
1. **XYZ Gold 401(k)**
- Min. Contribution: $50/month | Employer match up to 6%
- Features: Roth option, target date funds, low expense ratios
2. **XYZ Silver IRA (Traditional)**
- Min. Contribution: $25/month
- Features: Tax-deferred growth, flexible contributions, 600+ fund choices
3. **XYZ Roth IRA**
- Min. Contribution: $25/month
- Features: Tax-free withdrawals, no required minimum distributions, estate planning benefits
4. **XYZ Executive SEP-IRA**
- Contribute up to 25% of income
- Features: High contribution limits, self-employed friendly, simple administration
---
If you'd like to learn more about any of these plans or get in touch with one of our Chicago investment officers (especially **Sarah Kowalski**, who specializes in retirement planning!), feel free to ask! 😊
You >
Агент розділяє запит на кроки, які можна виконати, обирає відповідні інструменти, запускає їх та збирає результати. Якщо це допомагає, процес виглядає так: надходження запитання, планування, виклик інструментів, збір результатів, остаточна відповідь.
Спостережуваність
Такій системі потрібна телеметрія, тому додайте LangSmith. Інтеграція проста: дві змінні середовища та приблизно три рядки коду. LangSmith обгортає ваші існуючі виклики замість того, щоб їх замінювати.
Цей скрипт викликає безпосередньо Anthropic SDK, а не LangChain, тож для більш детальних записів ви можете за бажанням додати атрибут @traceable до функції run_agent():
from langsmith import traceable
@traceable(name="xyz-bank-agent-run")
def run_agent(client, conversation):
....................
....................
Кожен виклик інструменту, рішення моделі, кількість токенів та час відгуку відображаються у панелі керування LangSmith без змін у логіці циклу агента. Запустіть його знову з більш складним запитанням:
uv run agent.py
XYZ Bank Agent — type 'quit' to exit.
You > Show ATMs in 10001, investment officers in New York, and all branch locations
Here's a complete overview across all three categories:
---
## 🏧 ATMs in ZIP Code 10001
| ATM Name | Address | Hours | Fee |
|---|---|---|---|
| Midtown Manhattan ATM | 350 5th Ave | 24/7 | No fee |
| Penn Station ATM | 8 W 31st St | 24/7 | $2.50 (non-members) |
---
## 💼 Investment Officers — New York
1. **James Thornton** — Chief Investment Officer
- Specialty: Alternative Assets
- 📞 212-555-0201 | ✉️ j.thornton@xyzbank.com
2. **Priya Nair** — Investment Officer
- Specialty: ESG Portfolios
- 📞 212-555-0233 | ✉️ p.nair@xyzbank.com
---
## 🏦 All Branch Locations (61 Branches Nationwide)
| City | Branches | Flagship Address | Hours |
|---|---|---|---|
| Chicago | 14 | 200 W Adams St, Chicago IL 60606 | Mon–Fri 9am–5pm, Sat 9am–1pm |
| New York | 22 | 1 World Trade Center, NY 10007 | Mon–Fri 8am–6pm, Sat 9am–2pm |
| Los Angeles | 11 | 333 S Grand Ave, LA 90071 | Mon–Fri 9am–5pm, Sat 9am–1pm |
| Houston | 8 | 1000 Main St, Houston TX 77002 | Mon–Fri 9am–5pm |
| Boston | 6 | 100 Federal St, Boston MA 02110 | Mon–Fri 9am–5pm, Sat 10am–1pm |
---
Is there anything else you'd like to explore, such as retirement plans or our investment portfolio? 😊
You > What companies are in XYZ Bank's portfolio? List only Technology sector companies
Here are the **Technology sector companies** in XYZ Bank's investment portfolio:
---
## 💻 Technology Portfolio Companies
| Company | Stake | Value | Rating |
|---|---|---|---|
| **Apex Technologies Inc.** | 4.2% | $840M | A+ |
| **Sentinel Cybersecurity** | 7.3% | $1.5B | A+ |
---
### 📊 Summary
- **Total Technology Holdings:** 2 companies
- **Total Portfolio AUM:** $6.35B
- Both companies carry an **A+ rating**, reflecting strong investment quality.
---
Would you like to explore other sectors, view the full portfolio, or learn about our investment officers? Let me know! 😊
You >
Потім відкрийте сайт LangSmith та перегляньте записані виконання. Кожне виконання перелічує свої кроки разом із вхідними даними, результатами, часом виконання та помилками.
Безкоштовний тариф
На момент написання цього тексту план Developer є безкоштовним: він дозволяє 5 000 записів на місяць та не вимагає наявності кредитної картки. Він включає повне відстеження та виправлення помилок кожного кроку, що охоплює вхідні дані, результати, затримку, використання токенів та помилки, а також інтерфейс для швидкого тестування. Він обмежений одним обліковим записом та одним робочим простором, з можливістю зберігання записів протягом 14 днів, що підходить для індивідуальних прототипів та демонстрацій концепцій. LangSmith зазначає, що не тренує моделі на ваших записах, які залишаються приватними для вашої організації. Перевірте поточні тарифи перед тим, як покладатися на ці обмеження.
Коротко кажучи, почніть з безкоштовного тарифу. Він не коштує нічого, на налаштування йде приблизно чверть години, і він негайно відображає кожен виклик інструменту та прийняте рішення. Переходьте на вищий тариф лише тоді, коли обсяг роботи наближається до продакшн-рівня.
Що робити далі
- Замініть штучні дані на справжні джерела, такі як система корпоративного банкінгу, CRM чи внутрішні API.
- Створіть ієрархію, у якій оркестратор-шлюз направляє запити до агентів домену.
- Додайте механізми контролю, які ввічливо відхиляють запити, що не належать до сфери дії, та передають їх людям.
- Зберігайте історію розмов між запитами за допомогою Redis чи бази даних.
- Додайте міжсеансову пам’ять, щоб запити та уподобання повертаючихся користувачів залишалися у пам’яті.
- Встановіть обмеження на частоту запитів та ліміти токенів на користувача та сеанс.
- Складіть набір з 30–50 репрезентативних запитів із очікуваними результатами для оцінки.