xiaohongshu
xiaohongshu
ash-ai
AshAi extension guidelines for integrating AI capabilities with Ash Framework. Use when implementing vectorization/embeddings, exposing Ash actions as LLM tools, creating prompt-backed actions, or setting up MCP servers. Covers semantic search, LangChain integration, and structured outputs.
Full skill instructions
AshAi integrates AI capabilities with Ash resources: vectorization, LLM tools, prompt-backed actions, and MCP servers.
Convert text to vector embeddings for semantic search:
defmodule MyApp.Artist do
use Ash.Resource, extensions: [AshAi]
vectorize do
full_text do
text(fn record ->
"""
Name: #{record.name}
Biography: #{record.biography}
"""
end)
used_attributes [:name, :biography] # Only rebuild when these change
end
strategy :ash_oban # or :after_action, :manual
embedding_model MyApp.OpenAiEmbeddingModel
end
end
defmodule MyApp.OpenAiEmbeddingModel do
use AshAi.EmbeddingModel
@impl true
def dimensions(_opts), do: 3072
@impl true
def generate(texts, _opts) do
response = Req.post!("https://api.openai.com/v1/embeddings",
json: %{"input" => texts, "model" => "text-embedding-3-large"},
headers: [{"Authorization", "Bearer #{System.fetch_env!("OPEN_AI_API_KEY")}"}]
)
case response.status do
200 -> {:ok, Enum.map(response.body["data"], & &1["embedding"])}
_ -> {:error, response.body}
end
end
end
| Strategy | Behavior |
|---|---|
:after_action | Sync after create/update (slow, not for production) |
:ash_oban | Async via Ash Oban (recommended) |
:manual | You control when to update |
read :semantic_search do
argument :query, :string, allow_nil?: false
prepare before_action(fn query, _context ->
case MyApp.OpenAiEmbeddingModel.generate([query.arguments.query], []) do
{:ok, [search_vector]} ->
query
|> Ash.Query.filter(vector_cosine_distance(full_text_vector, ^search_vector) < 0.5)
|> Ash.Query.sort(asc: vector_cosine_distance(full_text_vector, ^search_vector))
{:error, error} -> {:error, error}
end
end)
end
bypass action(:ash_ai_update_embeddings) do
authorize_if AshAi.Checks.ActorIsAshAi
end
Expose Ash actions as LLM tools:
defmodule MyApp.Blog do
use Ash.Domain, extensions: [AshAi]
tools do
tool :read_posts, MyApp.Blog.Post, :read do
description "customize the tool description"
end
tool :create_post, MyApp.Blog.Post, :create
tool :read_with_details, MyApp.Blog.Post, :read do
load [:author, :internal_notes] # Include private attrs when loaded
end
end
end
public?: true attributespublic?: true action argumentsload option: Can include private attributes in responsechain =
%{llm: LangChain.ChatModels.ChatOpenAI.new!(%{model: "gpt-4o"}), verbose: true}
|> LangChain.Chains.LLMChain.new!()
|> AshAi.setup_ash_ai(otp_app: :my_app, tools: [:read_posts, :create_post])
Create actions where LLM provides the implementation:
action :analyze_sentiment, :atom do
constraints one_of: [:positive, :negative]
description "Analyzes sentiment of text"
argument :text, :string, allow_nil?: false
run prompt(
LangChain.ChatModels.ChatOpenAI.new!(%{model: "gpt-4o"}),
tools: true # or [:specific, :tools] or false
)
end
defmodule JobListing do
use Ash.TypedStruct
typed_struct do
field :title, :string, allow_nil?: false
field :company, :string, allow_nil?: false
field :requirements, {:array, :string}
end
end
action :parse_job, JobListing do
argument :raw_content, :string, allow_nil?: false
run prompt(
fn _input, _context ->
LangChain.ChatModels.ChatOpenAI.new!(%{
model: "gpt-4o-mini",
api_key: System.get_env("OPENAI_API_KEY")
})
end,
prompt: "Parse this job listing: <%= @input.arguments.raw_content %>",
tools: false
)
end
For detailed prompt format options and adapters, see references/prompt-actions.md.
# In endpoint.ex
if code_reloading? do
plug AshAi.Mcp.Dev,
protocol_version_statement: "2024-11-05",
otp_app: :your_app
end
pipeline :mcp do
plug AshAuthentication.Strategy.ApiKey.Plug,
resource: YourApp.Accounts.User,
required?: false
end
scope "/mcp" do
pipe_through :mcp
forward "/", AshAi.Mcp.Router,
tools: [:read_posts, :create_post, :analyze_sentiment],
protocol_version_statement: "2024-11-05",
otp_app: :my_app
end
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience