Build a LangChain Agent for AlifOffice
LangChain agents can use any REST API as a tool. This guide wires the AlifOffice API into a LangChain agent so you can query and update your workspace with natural language.
Setup
bash
pip install langchain langchain-openai requests
export OPENAI_API_KEY=sk-...
export AO_API_KEY=ao_...
export AO_WORKSPACE=your-workspace
Define the Tools
python
import os, json, requests
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from langchain.agents import create_openai_functions_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
AO_BASE = "https://alifoffice.com/api/v1"
AO_HEADERS = {
"Authorization": f"Bearer {os.environ['AO_API_KEY']}",
"X-Workspace": os.environ["AO_WORKSPACE"],
"Content-Type": "application/json",
}
def ao_get(path: str, params: dict = None) -> dict:
return requests.get(f"{AO_BASE}/{path}", headers=AO_HEADERS, params=params).json()
def ao_post(path: str, body: dict) -> dict:
return requests.post(f"{AO_BASE}/{path}", headers=AO_HEADERS, json=body).json()
@tool
def list_crm_contacts(search: str = "", type: str = "") -> str:
"""List CRM contacts. Optionally filter by search term or type (person/company)."""
params = {}
if search: params["search"] = search
if type: params["type"] = type
return json.dumps(ao_get("crm/contacts", params))
@tool
def list_deals(stage: str = "") -> str:
"""List CRM deals. Optionally filter by stage: new, qualified, proposal, negotiation, won, lost."""
params = {"stage": stage} if stage else {}
return json.dumps(ao_get("crm/deals", params))
@tool
def list_projects(status: str = "active") -> str:
"""List projects. Filter by status: planning, active, on_hold, completed, cancelled."""
return json.dumps(ao_get("projects", {"status": status}))
@tool
def list_overdue_invoices() -> str:
"""List all overdue invoices with amounts."""
return json.dumps(ao_get("invoice/invoices", {"status": "overdue"}))
@tool
def create_crm_contact(first_name: str, last_name: str, email: str,
company: str = "", job_title: str = "") -> str:
"""Create a new CRM contact."""
body = {"first_name": first_name, "last_name": last_name,
"email": email, "type": "person"}
if company: body["company_name"] = company
if job_title: body["job_title"] = job_title
return json.dumps(ao_post("crm/contacts", body))
@tool
def create_deal(title: str, stage: str = "new", amount: float = 0) -> str:
"""Create a new CRM deal."""
return json.dumps(ao_post("crm/deals", {"title": title, "stage": stage, "amount": amount}))
tools = [list_crm_contacts, list_deals, list_projects, list_overdue_invoices,
create_crm_contact, create_deal]
Build the Agent
python
llm = ChatOpenAI(model="gpt-4o", temperature=0)
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful business assistant with access to AlifOffice data. Always give concise, actionable answers."),
("user", "{input}"),
MessagesPlaceholder("agent_scratchpad"),
])
agent = create_openai_functions_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# Ask questions
executor.invoke({"input": "How many deals do we have in the proposal stage, and what's the total value?"})
executor.invoke({"input": "Are there any overdue invoices? If so, how many and what's the total?"})
executor.invoke({"input": "Create a new contact: John Smith, john@example.com, CTO at ExampleCorp"})
Streaming Responses
python
for chunk in executor.stream({"input": "Give me a summary of all active projects"}):
if "output" in chunk:
print(chunk["output"], end="", flush=True)
Deploy as a FastAPI Service
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Query(BaseModel):
message: str
@app.post("/ask")
def ask(q: Query):
result = executor.invoke({"input": q.message})
return {"answer": result["output"]}
Tip: Usecreate_openai_tools_agentfor parallel tool calls (faster for multi-step queries) instead ofcreate_openai_functions_agent.